summaryrefslogtreecommitdiff
path: root/spec/rubyspec/core/file/chmod_spec.rb
blob: 8590f3008dcdf61da0371202f783ca51ccb26fd1 (plain)
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
require File.expand_path('../../../spec_helper', __FILE__)

describe "File#chmod" do
  before :each do
    @filename = tmp('i_exist.exe')
    @file = File.open(@filename, 'w')
  end

  after :each do
    @file.close
    rm_r @filename
  end

  it "returns 0 if successful" do
    @file.chmod(0755).should == 0
  end

  platform_is_not :freebsd, :netbsd, :openbsd do
    it "always succeeds with any numeric values" do
      vals = [-2**30, -2**16, -2**8, -2, -1,
        -0.5, 0, 1, 2, 5.555575, 16, 32, 64, 2**8, 2**16, 2**30]
      vals.each { |v|
        lambda { @file.chmod(v) }.should_not raise_error
      }
    end
  end

  # -256, -2 and -1 raise Errno::E079 on FreeBSD
  # -256, -2 and -1 raise Errno::EFTYPE on NetBSD
  platform_is :freebsd, :netbsd do
    it "always succeeds with any numeric values" do
      vals = [-2**30, -2**16, #-2**8, -2, -1,
        -0.5, 0, 1, 2, 5.555575, 16, 32, 64, 2**8, 2**16, 2**30]
      vals.each { |v|
        lambda { @file.chmod(v) }.should_not raise_error
      }
    end
  end

  # -256, -2 and -1 raise Errno::EINVAL on OpenBSD
  platform_is :openbsd do
    it "always succeeds with any numeric values" do
      vals = [#-2**30, -2**16, -2**8, -2, -1,
        -0.5, 0, 1, 2, 5.555575, 16, 32, 64, 2**8]#, 2**16, 2**30
      vals.each { |v|
        lambda { @file.chmod(v) }.should_not raise_error
      }
    end
  end
  it "invokes to_int on non-integer argument" do
    mode = File.stat(@filename).mode
    (obj = mock('mode')).should_receive(:to_int).and_return(mode)
    @file.chmod(obj)
    File.stat(@filename).mode.should == mode
  end

  platform_is :windows do
    it "with '0444' makes file readable and executable but not writable" do
      @file.chmod(0444)
      File.readable?(@filename).should == true
      File.writable?(@filename).should == false
      File.executable?(@filename).should == true
    end

    it "with '0644' makes file readable and writable and also executable" do
      @file.chmod(0644)
      File.readable?(@filename).should == true
      File.writable?(@filename).should == true
      File.executable?(@filename).should == true
    end
  end

  platform_is_not :windows do
    it "with '0222' makes file writable but not readable or executable" do
      @file.chmod(0222)
      File.readable?(@filename).should == false
      File.writable?(@filename).should == true
      File.executable?(@filename).should == false
    end

    it "with '0444' makes file readable but not writable or executable" do
      @file.chmod(0444)
      File.readable?(@filename).should == true
      File.writable?(@filename).should == false
      File.executable?(@filename).should == false
    end

    it "with '0666' makes file readable and writable but not executable" do
      @file.chmod(0666)
      File.readable?(@filename).should == true
      File.writable?(@filename).should == true
      File.executable?(@filename).should == false
    end

    it "with '0111' makes file executable but not readable or writable" do
      @file.chmod(0111)
      File.readable?(@filename).should == false
      File.writable?(@filename).should == false
      File.executable?(@filename).should == true
    end

    it "modifies the permission bits of the files specified" do
      @file.chmod(0755)
      File.stat(@filename).mode.should == 33261
    end
  end
end

describe "File.chmod" do
  before :each do
    @file = tmp('i_exist.exe')
    touch @file
    @count = File.chmod(0755, @file)
  end

  after :each do
    rm_r @file
  end

  it "returns the number of files modified" do
    @count.should == 1
  end

  platform_is_not :freebsd, :netbsd, :openbsd do
    it "always succeeds with any numeric values" do
      vals = [-2**30, -2**16, -2**8, -2, -1,
        -0.5, 0, 1, 2, 5.555575, 16, 32, 64, 2**8, 2**16, 2**30]
      vals.each { |v|
        lambda { File.chmod(v, @file) }.should_not raise_error
      }
    end
  end

  # -256, -2 and -1 raise Errno::E079 on FreeBSD
  # -256, -2 and -1 raise Errno::EFTYPE on NetBSD
  platform_is :freebsd, :netbsd do
    it "always succeeds with any numeric values" do
      vals = [-2**30, -2**16, #-2**8, -2, -1,
        -0.5, 0, 1, 2, 5.555575, 16, 32, 64, 2**8, 2**16, 2**30]
      vals.each { |v|
        lambda { File.chmod(v, @file) }.should_not raise_error
      }
    end
  end

  platform_is :openbsd do
    it "succeeds with valid values" do
      vals = [-0.5, 0, 1, 2, 5.555575, 16, 32, 64, 2**8]
      vals.each { |v|
        lambda { File.chmod(v, @file) }.should_not raise_error
      }
    end

    it "fails with invalid values" do
      vals = [-2**30, -2**16, -2**8, -2, -1, 2**16, 2**30]
      vals.each { |v|
        lambda { File.chmod(v, @file) }.should raise_error(Errno::EINVAL)
      }
    end
  end

  it "accepts an object that has a #to_path method" do
    File.chmod(0, mock_to_path(@file))
  end

  it "throws a TypeError if the given path is not coercable into a string" do
    lambda { File.chmod(0, []) }.should raise_error(TypeError)
  end

  it "raises an error for a non existent path" do
    lambda {
      File.chmod(0644, "#{@file}.not.existing")
    }.should raise_error(Errno::ENOENT)
  end

  it "invokes to_int on non-integer argument" do
    mode = File.stat(@file).mode
    (obj = mock('mode')).should_receive(:to_int).and_return(mode)
    File.chmod(obj, @file)
    File.stat(@file).mode.should == mode
  end

  it "invokes to_str on non-string file names" do
    mode = File.stat(@file).mode
    (obj = mock('path')).should_receive(:to_str).and_return(@file)
    File.chmod(mode, obj)
    File.stat(@file).mode.should == mode
  end

  platform_is :windows do
    it "with '0444' makes file readable and executable but not writable" do
      File.chmod(0444, @file)
      File.readable?(@file).should == true
      File.writable?(@file).should == false
      File.executable?(@file).should == true
    end

    it "with '0644' makes file readable and writable and also executable" do
      File.chmod(0644, @file)
      File.readable?(@file).should == true
      File.writable?(@file).should == true
      File.executable?(@file).should == true
    end
  end

  platform_is_not :windows do
    it "with '0222' makes file writable but not readable or executable" do
      File.chmod(0222, @file)
      File.readable?(@file).should == false
      File.writable?(@file).should == true
      File.executable?(@file).should == false
    end

    it "with '0444' makes file readable but not writable or executable" do
      File.chmod(0444, @file)
      File.readable?(@file).should == true
      File.writable?(@file).should == false
      File.executable?(@file).should == false
    end

    it "with '0666' makes file readable and writable but not executable" do
      File.chmod(0666, @file)
      File.readable?(@file).should == true
      File.writable?(@file).should == true
      File.executable?(@file).should == false
    end

    it "with '0111' makes file executable but not readable or writable" do
      File.chmod(0111, @file)
      File.readable?(@file).should == false
      File.writable?(@file).should == false
      File.executable?(@file).should == true
    end

    it "modifies the permission bits of the files specified" do
      File.stat(@file).mode.should == 33261
    end
  end
end