1 /++
2 $(H2 Scriptlike $(SCRIPTLIKE_VERSION))
3 
4 Extra Scriptlike-only functionality to complement and wrap $(MODULE_STD_PATH),
5 providing extra functionality, such as no-fail "try*" alternatives, and support
6 for Scriptlike's $(API_PATH_EXTR Path), command echoing and dry-run features.
7 
8 Modules:
9 $(UL
10 	$(LI $(MODULE_PATH_EXTR) )
11 	$(LI $(MODULE_PATH_WRAP) )
12 )
13 
14 Copyright: Copyright (C) 2014-2017 Nick Sabalausky
15 License:   zlib/libpng
16 Authors:   Nick Sabalausky
17 +/
18 module scriptlike.path;
19 
20 public import scriptlike.path.extras;
21 public import scriptlike.path.wrappers;
22 
23 // The unittests in this module mainly check that all the templates compile
24 // correctly and that the appropriate Phobos functions are correctly called.
25 //
26 // A completely thorough testing of the behavior of such functions is
27 // occasionally left to Phobos itself as it is outside the scope of these tests.
28 version(unittest_scriptlike_d)
29 unittest
30 {
31 	import std.algorithm;
32 	import std.conv;
33 	import std.datetime;
34 	import std.file;
35 	import std.path : dirSeparator;
36 	import std.process;
37 	import std.range;
38 	import std.stdio;
39 	import std.string;
40 	import std.traits;
41 	import std.typecons;
42 	import std.typetuple;
43 
44 	import std.stdio : writeln;
45 	writeln("Running Scriptlike unittests: std.path wrappers");
46 	
47 	alias dirSep = dirSeparator;
48 
49 	{
50 		auto e = Ext(".txt");
51 		assert(e != Ext(".dat"));
52 		assert(e == Ext(".txt"));
53 		version(Windows)
54 			assert(e == Ext(".TXT"));
55 		else version(OSX)
56 			assert(e == Ext(".TXT"));
57 		else version(Posix)
58 			assert(e != Ext(".TXT"));
59 		else
60 			static assert(0, "This platform not supported.");
61 		
62 		// Test the other comparison overloads
63 		assert(e != Ext(".dat"));
64 		assert(e == Ext(".txt"));
65 		assert(Ext(".dat") != e);
66 		assert(Ext(".txt") == e);
67 		assert(".dat" != e);
68 		assert(".txt" == e);
69 
70 		assert(Ext("foo"));
71 		assert(Ext(""));
72 		assert(Ext(null).toString() is null);
73 		assert(!Ext(null));
74 	}
75 
76 	auto p = Path();
77 	assert(p.raw == ".");
78 	assert(!p.empty);
79 	
80 	assert(Path("").empty);
81 	
82 	assert(Path("foo"));
83 	assert(Path(""));
84 	assert(Path(null).raw is null);
85 	assert(!Path(null));
86 	
87 	version(Windows)
88 		auto testStrings = ["/foo/bar", "/foo/bar/", `\foo\bar`, `\foo\bar\`];
89 	else version(Posix)
90 		auto testStrings = ["/foo/bar", "/foo/bar/"];
91 	else
92 		static assert(0, "This platform not supported.");
93 	
94 	foreach(str; testStrings)
95 	{
96 		writeln("  testing str: ", str);
97 		
98 		p = Path(str);
99 		assert(!p.empty);
100 		assert(p.raw == dirSep~"foo"~dirSep~"bar");
101 		
102 		p = Path(str);
103 		assert(p.raw == dirSep~"foo"~dirSep~"bar");
104 		assert(p.raw == p.raw);
105 		assert(p.toString()    == p.raw.to!string());
106 		
107 		assert(p.up.toString() == dirSep~"foo");
108 		assert(p.up.up.toString() == dirSep);
109 
110 		assert((p~"sub").toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"sub");
111 		assert((p~"sub"~"2").toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"sub"~dirSep~"2");
112 		assert((p~Path("sub")).toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"sub");
113 		
114 		version(Windows)
115 			assert((p~"sub dir").toString() == `"`~dirSep~"foo"~dirSep~"bar"~dirSep~"sub dir"~`"`);
116 		else version(Posix)
117 			assert((p~"sub dir").toString() == `'`~dirSep~"foo"~dirSep~"bar"~dirSep~`sub dir'`);
118 		else
119 			static assert(0, "This platform not supported.");
120 
121 		assert(("dir"~p).toString() == dirSep~"foo"~dirSep~"bar");
122 		assert(("dir"~Path(str[1..$])).toString() == "dir"~dirSep~"foo"~dirSep~"bar");
123 		
124 		p ~= "blah";
125 		assert(p.toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"blah");
126 		
127 		p ~= Path("more");
128 		assert(p.toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"blah"~dirSep~"more");
129 		
130 		p ~= "..";
131 		assert(p.toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"blah");
132 		
133 		p ~= Path("..");
134 		assert(p.toString() == dirSep~"foo"~dirSep~"bar");
135 		
136 		p ~= "sub dir";
137 		p ~= "..";
138 		assert(p.toString() == dirSep~"foo"~dirSep~"bar");
139 		
140 		p ~= "filename";
141 		assert((p~Ext(".txt")).toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"filename.txt");
142 		assert((p~Ext("txt")).toString()  == dirSep~"foo"~dirSep~"bar"~dirSep~"filename.txt");
143 		assert((p~Ext("")).toString()     == dirSep~"foo"~dirSep~"bar"~dirSep~"filename");
144 
145 		p ~= Ext(".ext");
146 		assert(p.toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"filename.ext");
147 		assert(p.baseName().toString() == "filename.ext");
148 		assert(p.dirName().toString() == dirSep~"foo"~dirSep~"bar");
149 		assert(p.rootName().toString() == dirSep);
150 		assert(p.driveName().toString() == "");
151 		assert(p.stripDrive().toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"filename.ext");
152 		version(Windows)
153 		{
154 			assert(( Path("C:"~p.raw) ).toString() == "C:"~dirSep~"foo"~dirSep~"bar"~dirSep~"filename.ext");
155 			assert(( Path("C:"~p.raw) ).stripDrive().toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"filename.ext");
156 		}
157 		assert(p.extension().toString() == ".ext");
158 		assert(p.stripExtension().toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"filename");
159 		assert(p.setExtension(".txt").toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"filename.txt");
160 		assert(p.setExtension("txt").toString()  == dirSep~"foo"~dirSep~"bar"~dirSep~"filename.txt");
161 		assert(p.setExtension("").toString()     == dirSep~"foo"~dirSep~"bar"~dirSep~"filename");
162 		assert(p.setExtension(Ext(".txt")).toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"filename.txt");
163 		assert(p.setExtension(Ext("txt")).toString()  == dirSep~"foo"~dirSep~"bar"~dirSep~"filename.txt");
164 		assert(p.setExtension(Ext("")).toString()     == dirSep~"foo"~dirSep~"bar"~dirSep~"filename");
165 
166 		assert(p.defaultExtension(".dat").toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"filename.ext");
167 		assert(p.stripExtension().defaultExtension(".dat").toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"filename.dat");
168 
169 		assert(equal(p.pathSplitter(), [dirSep, "foo", "bar", "filename.ext"]));
170 
171 		assert(p.isRooted());
172 		version(Windows)
173 			assert(!p.isAbsolute());
174 		else version(Posix)
175 			assert(p.isAbsolute());
176 		else
177 			static assert(0, "This platform not supported.");
178 
179 		assert(!( Path("dir"~p.raw) ).isRooted());
180 		assert(!( Path("dir"~p.raw) ).isAbsolute());
181 		
182 		version(Windows)
183 		{
184 			assert(( Path("dir"~p.raw) ).absolutePath("C:/main").toString() == "C:"~dirSep~"main"~dirSep~"dir"~dirSep~"foo"~dirSep~"bar"~dirSep~"filename.ext");
185 			assert(( Path("C:"~p.raw) ).relativePath("C:/foo").toString() == "bar"~dirSep~"filename.ext");
186 			assert(( Path("C:"~p.raw) ).relativePath("C:/foo/bar").toString() == "filename.ext");
187 		}
188 		else version(Posix)
189 		{
190 			assert(( Path("dir"~p.raw) ).absolutePath("/main").toString() == dirSep~"main"~dirSep~"dir"~dirSep~"foo"~dirSep~"bar"~dirSep~"filename.ext");
191 			assert(p.relativePath("/foo").toString() == "bar"~dirSep~"filename.ext");
192 			assert(p.relativePath("/foo/bar").toString() == "filename.ext");
193 		}
194 		else
195 			static assert(0, "This platform not supported.");
196 
197 		assert(p.filenameCmp(dirSep~"foo"~dirSep~"bar"~dirSep~"filename.ext") == 0);
198 		assert(p.filenameCmp(dirSep~"faa"~dirSep~"bat"~dirSep~"filename.ext") != 0);
199 		assert(p.globMatch("*foo*name.ext"));
200 		assert(!p.globMatch("*foo*Bname.ext"));
201 
202 		assert(!p.isValidFilename());
203 		assert(p.baseName().isValidFilename());
204 		assert(p.isValidPath());
205 		
206 		assert(p.expandTilde().toString() == dirSep~"foo"~dirSep~"bar"~dirSep~"filename.ext");
207 		
208 		assert(p != Path("/dir/subdir/filename.ext"));
209 		assert(p == Path("/foo/bar/filename.ext"));
210 		version(Windows)
211 			assert(p == Path("/FOO/BAR/FILENAME.EXT"));
212 		else version(OSX)
213 			assert(p == Path("/FOO/BAR/FILENAME.EXT"));
214 		else version(Posix)
215 			assert(p != Path("/FOO/BAR/FILENAME.EXT"));
216 		else
217 			static assert(0, "This platform not supported.");
218 		
219 		// Test the other comparison overloads
220 		assert(p != Path("/dir/subdir/filename.ext"));
221 		assert(p == Path("/foo/bar/filename.ext"));
222 		assert(Path("/dir/subdir/filename.ext") != p);
223 		assert(Path("/foo/bar/filename.ext")    == p);
224 		assert("/dir/subdir/filename.ext" != p);
225 		assert("/foo/bar/filename.ext"    == p);
226 	}
227 }