1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
require_relative '../../spec_helper'
describe "File.join" do
# see [ruby-core:46804] for the 4 following rules
it "changes only boundaries separators" do
File.join("file/\\/usr/", "/bin").should == "file/\\/usr/bin"
File.join("file://usr", "bin").should == "file://usr/bin"
end
it "respects the given separator if only one part has a boundary separator" do
File.join("usr/", "bin").should == "usr/bin"
File.join("usr", "/bin").should == "usr/bin"
File.join("usr//", "bin").should == "usr//bin"
File.join("usr", "//bin").should == "usr//bin"
end
it "joins parts using File::SEPARATOR if there are no boundary separators" do
File.join("usr", "bin").should == "usr/bin"
end
it "prefers the separator of the right part if both parts have separators" do
File.join("usr/", "//bin").should == "usr//bin"
File.join("usr//", "/bin").should == "usr/bin"
end
platform_is :windows do
it "respects given separator if only one part has a boundary separator" do
File.join("C:\\", 'windows').should == "C:\\windows"
File.join("C:", "\\windows").should == "C:\\windows"
File.join("\\\\", "usr").should == "\\\\usr"
end
it "prefers the separator of the right part if both parts have separators" do
File.join("C:/", "\\windows").should == "C:\\windows"
File.join("C:\\", "/windows").should == "C:/windows"
end
end
platform_is_not :windows do
it "does not treat \\ as a separator on non-Windows" do
File.join("usr\\", 'bin').should == "usr\\/bin"
File.join("usr", "\\bin").should == "usr/\\bin"
File.join("usr/", "\\bin").should == "usr/\\bin"
File.join("usr\\", "/bin").should == "usr\\/bin"
end
end
it "returns an empty string when given no arguments" do
File.join.should == ""
end
it "returns a duplicate string when given a single argument" do
str = "usr"
File.join(str).should == str
File.join(str).should_not equal(str)
end
it "supports any number of arguments" do
File.join("a", "b", "c", "d").should == "a/b/c/d"
end
it "flattens nested arrays" do
File.join(["a", "b", "c"]).should == "a/b/c"
File.join(["a", ["b", ["c"]]]).should == "a/b/c"
end
it "inserts the separator in between empty strings and arrays" do
File.join("").should == ""
File.join("", "").should == "/"
File.join(["", ""]).should == "/"
File.join("a", "").should == "a/"
File.join("", "a").should == "/a"
File.join([]).should == ""
File.join([], []).should == "/"
File.join([[], []]).should == "/"
File.join("a", []).should == "a/"
File.join([], "a").should == "/a"
end
it "handles leading parts edge cases" do
File.join("/bin") .should == "/bin"
File.join("", "bin") .should == "/bin"
File.join("/", "bin") .should == "/bin"
File.join("/", "/bin").should == "/bin"
end
it "handles trailing parts edge cases" do
File.join("bin", "") .should == "bin/"
File.join("bin/") .should == "bin/"
File.join("bin/", "") .should == "bin/"
File.join("bin", "/") .should == "bin/"
File.join("bin/", "/").should == "bin/"
end
it "handles middle parts edge cases" do
File.join("usr", "", "bin") .should == "usr/bin"
File.join("usr/", "", "bin") .should == "usr/bin"
File.join("usr", "", "/bin").should == "usr/bin"
File.join("usr/", "", "/bin").should == "usr/bin"
end
# TODO: See MRI svn r23306. Add patchlevel when there is a release.
it "raises an ArgumentError if passed a recursive array" do
a = ["a"]
a << a
-> { File.join a }.should raise_error(ArgumentError)
end
it "raises a TypeError exception when args are nil" do
-> { File.join nil }.should raise_error(TypeError)
end
it "calls #to_str" do
-> { File.join(mock('x')) }.should raise_error(TypeError)
bin = mock("bin")
bin.should_receive(:to_str).exactly(:twice).and_return("bin")
File.join(bin).should == "bin"
File.join("usr", bin).should == "usr/bin"
end
it "doesn't mutate the object when calling #to_str" do
usr = mock("usr")
str = "usr"
usr.should_receive(:to_str).and_return(str)
File.join(usr, "bin").should == "usr/bin"
str.should == "usr"
end
it "calls #to_path" do
-> { File.join(mock('x')) }.should raise_error(TypeError)
bin = mock("bin")
bin.should_receive(:to_path).exactly(:twice).and_return("bin")
File.join(bin).should == "bin"
File.join("usr", bin).should == "usr/bin"
end
it "raises errors for null bytes" do
-> { File.join("\x00x", "metadata.gz") }.should raise_error(ArgumentError) { |e|
e.message.should == 'string contains null byte'
}
-> { File.join("metadata.gz", "\x00x") }.should raise_error(ArgumentError) { |e|
e.message.should == 'string contains null byte'
}
end
end
|