ndr_support 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +14 -0
  3. data/.rubocop.yml +27 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +22 -0
  6. data/CODE_OF_CONDUCT.md +13 -0
  7. data/Gemfile +4 -0
  8. data/Guardfile +16 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +91 -0
  11. data/Rakefile +12 -0
  12. data/code_safety.yml +258 -0
  13. data/gemfiles/Gemfile.rails32 +6 -0
  14. data/gemfiles/Gemfile.rails32.lock +108 -0
  15. data/gemfiles/Gemfile.rails41 +6 -0
  16. data/gemfiles/Gemfile.rails41.lock +111 -0
  17. data/gemfiles/Gemfile.rails42 +6 -0
  18. data/gemfiles/Gemfile.rails42.lock +111 -0
  19. data/lib/ndr_support.rb +21 -0
  20. data/lib/ndr_support/array.rb +52 -0
  21. data/lib/ndr_support/concerns/working_days.rb +94 -0
  22. data/lib/ndr_support/date_and_time_extensions.rb +103 -0
  23. data/lib/ndr_support/daterange.rb +196 -0
  24. data/lib/ndr_support/fixnum/calculations.rb +15 -0
  25. data/lib/ndr_support/fixnum/julian_date_conversions.rb +14 -0
  26. data/lib/ndr_support/hash.rb +52 -0
  27. data/lib/ndr_support/integer.rb +12 -0
  28. data/lib/ndr_support/nil.rb +38 -0
  29. data/lib/ndr_support/ourdate.rb +97 -0
  30. data/lib/ndr_support/ourtime.rb +51 -0
  31. data/lib/ndr_support/regexp_range.rb +65 -0
  32. data/lib/ndr_support/safe_file.rb +185 -0
  33. data/lib/ndr_support/safe_path.rb +268 -0
  34. data/lib/ndr_support/string/cleaning.rb +136 -0
  35. data/lib/ndr_support/string/conversions.rb +137 -0
  36. data/lib/ndr_support/tasks.rb +1 -0
  37. data/lib/ndr_support/time/conversions.rb +13 -0
  38. data/lib/ndr_support/utf8_encoding.rb +72 -0
  39. data/lib/ndr_support/utf8_encoding/control_characters.rb +53 -0
  40. data/lib/ndr_support/utf8_encoding/force_binary.rb +44 -0
  41. data/lib/ndr_support/utf8_encoding/object_support.rb +31 -0
  42. data/lib/ndr_support/version.rb +5 -0
  43. data/lib/ndr_support/yaml/serialization_migration.rb +65 -0
  44. data/lib/tasks/audit_code.rake +423 -0
  45. data/ndr_support.gemspec +39 -0
  46. data/test/array_test.rb +20 -0
  47. data/test/concerns/working_days_test.rb +122 -0
  48. data/test/daterange_test.rb +194 -0
  49. data/test/fixnum/calculations_test.rb +28 -0
  50. data/test/hash_test.rb +84 -0
  51. data/test/integer_test.rb +14 -0
  52. data/test/nil_test.rb +40 -0
  53. data/test/ourdate_test.rb +27 -0
  54. data/test/ourtime_test.rb +27 -0
  55. data/test/regexp_range_test.rb +135 -0
  56. data/test/resources/filesystem_paths.yml +37 -0
  57. data/test/safe_file_test.rb +597 -0
  58. data/test/safe_path_test.rb +168 -0
  59. data/test/string/cleaning_test.rb +176 -0
  60. data/test/string/conversions_test.rb +353 -0
  61. data/test/test_helper.rb +41 -0
  62. data/test/time/conversions_test.rb +15 -0
  63. data/test/utf8_encoding/control_characters_test.rb +84 -0
  64. data/test/utf8_encoding/force_binary_test.rb +64 -0
  65. data/test/utf8_encoding_test.rb +170 -0
  66. data/test/yaml/serialization_test.rb +145 -0
  67. metadata +295 -0
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ # This tests our Integer extension
4
+ class IntegerTest < Minitest::Test
5
+ def test_rounding
6
+ assert_equal 124_000, 123_221.round_up_to(3)
7
+ assert_equal 123_300, 123_221.round_up_to(4)
8
+ assert_equal 760, 758.round_up_to(2)
9
+ assert_equal 3453, 3452.round_up_to(4)
10
+ assert_nil 1.round_up_to(2)
11
+ refute_nil 10.round_up_to(2)
12
+ assert_nil 12.round_up_to(-45)
13
+ end
14
+ end
data/test/nil_test.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ # This tests our Nil extension
4
+ class NilTest < Minitest::Test
5
+ test 'to_date' do
6
+ assert_nil nil.to_date
7
+ end
8
+
9
+ test 'titleize' do
10
+ assert_nil nil.titleize
11
+ end
12
+
13
+ test 'surnameize' do
14
+ assert_nil nil.surnameize
15
+ end
16
+
17
+ test 'postcodeize' do
18
+ assert_nil nil.postcodeize
19
+ end
20
+
21
+ test 'upcase' do
22
+ assert_nil nil.upcase
23
+ end
24
+
25
+ test 'clean' do
26
+ assert_nil nil.clean(:tnmcategory)
27
+ end
28
+
29
+ test 'squash' do
30
+ assert_nil nil.squash
31
+ end
32
+
33
+ test 'gsub' do
34
+ assert_equal '', nil.gsub(/.*/)
35
+ end
36
+
37
+ test 'strip' do
38
+ assert_nil nil.strip
39
+ end
40
+ end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ # This tests our Ourdate class
4
+ class OurdateTest < Minitest::Test
5
+ def test_date_and_time
6
+ d = Ourdate.build_datetime(2003, 11, 30)
7
+ assert_equal '30 November 2003', d.to_verbose
8
+ assert_equal '2003-11-30', d.to_iso
9
+ assert_equal '30.11.2003', d.to_ours
10
+ assert_equal '30.11.2003', d.to_s
11
+ end
12
+
13
+ def test_ourdate
14
+ # Creating an Ourdate from a String
15
+ od = Ourdate.new('01.02.2000')
16
+ assert_equal Date.new(2000, 2, 1).to_s(:ui), od.to_s
17
+ assert_kind_of Date, od.thedate
18
+ assert_equal '01.02.2000', od.thedate.to_s
19
+ # Creating an Ourdate from a Date
20
+ od = Ourdate.new(Date.new(2000, 3, 1))
21
+ assert_equal '01.03.2000', od.to_s
22
+ end
23
+
24
+ def test_blank
25
+ assert Ourdate.new.blank? # delegates to empty?
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ # This tests our Ourtime class
4
+ class OurtimeTest < Minitest::Test
5
+ def test_initialize_with_local_format_string
6
+ # Creating an Ourtime from a local-format String (with seconds)
7
+ ot = Ourtime.new('01.02.1993 04:05:06')
8
+ assert_equal '1993-02-01 04:05:06', ot.thetime.strftime('%Y-%m-%d %H:%M:%S')
9
+ assert_kind_of Time, ot.thetime
10
+ end
11
+
12
+ def test_initialize_with_time
13
+ # Creating an Ourtime from a Time
14
+ ot = Ourtime.new(Time.mktime(1993, 2, 1, 4, 5))
15
+ assert_equal '01.02.1993 04:05', ot.to_s
16
+ end
17
+
18
+ def test_initialize_with_no_parameters
19
+ assert Ourtime.new.blank? # delegates to empty?
20
+ end
21
+
22
+ def test_initialize_with_iso_string
23
+ # Parsing an ISO datetime
24
+ ot = Ourtime.new('1993-04-05 06:07:08')
25
+ assert_equal '1993-04-05 06:07:08', ot.thetime.strftime('%Y-%m-%d %H:%M:%S')
26
+ end
27
+ end
@@ -0,0 +1,135 @@
1
+ require 'test_helper'
2
+
3
+ # This tests our RegexpRange class
4
+ class RegexpRangeTest < Minitest::Test
5
+ def setup
6
+ @lines = [
7
+ '0Lorem ipsum dolor sit amet',
8
+ '1consectetur adipisicing elit',
9
+ '2sed do eiusmod tempor incididunt ut labore et dolore magna aliqua',
10
+ '3Ut enim ad minim veniam, quis nostrud exercitation ullamco',
11
+ '4laboris nisi ut aliquip ex ea commodo consequat'
12
+ ]
13
+ end
14
+
15
+ test 'to_yaml' do
16
+ regexp_range = RegexpRange.new(0, /^3Ut/)
17
+
18
+ # Don't test YAML serialisation directly, but make it can be loaded:
19
+ deserialized_regexp_range = YAML.load(regexp_range.to_yaml)
20
+ assert_instance_of RegexpRange, deserialized_regexp_range
21
+ assert_equal regexp_range.begin, deserialized_regexp_range.begin
22
+ assert_equal regexp_range.end, deserialized_regexp_range.end
23
+ assert_equal regexp_range.excl, deserialized_regexp_range.excl
24
+ end
25
+
26
+ test 'to_range with number and number' do
27
+ assert_equal Range.new(2, 3, true), RegexpRange.new(2, 3, true).to_range(@lines)
28
+ assert_equal Range.new(2, 3, false), RegexpRange.new(2, 3, false).to_range(@lines)
29
+ assert_equal Range.new(0, -1, true), RegexpRange.new(0, -1, true).to_range(@lines)
30
+ assert_equal Range.new(0, -1, false), RegexpRange.new(0, -1, false).to_range(@lines)
31
+
32
+ assert_equal @lines[Range.new(2, 3, true)],
33
+ @lines[RegexpRange.new(2, 3, true).to_range(@lines)]
34
+ assert_equal @lines[Range.new(2, 3, false)],
35
+ @lines[RegexpRange.new(2, 3, false).to_range(@lines)]
36
+ end
37
+
38
+ test 'to_range with number and regexp' do
39
+ assert_equal Range.new(2, 3, true), RegexpRange.new(2, /^3Ut/, true).to_range(@lines)
40
+ assert_equal Range.new(2, 3, false), RegexpRange.new(2, /^3Ut/, false).to_range(@lines)
41
+
42
+ assert_equal @lines[Range.new(2, 3, true)],
43
+ @lines[RegexpRange.new(2, /^3Ut/, true).to_range(@lines)]
44
+ assert_equal @lines[Range.new(2, 3, false)],
45
+ @lines[RegexpRange.new(2, /^3Ut/, false).to_range(@lines)]
46
+
47
+ assert_raises RegexpRange::PatternMatchError do
48
+ RegexpRange.new(2, /^NO_MATCH$/, true).to_range(@lines)
49
+ end
50
+ assert_raises RegexpRange::PatternMatchError do
51
+ RegexpRange.new(2, /^NO_MATCH$/, false).to_range(@lines)
52
+ end
53
+ end
54
+
55
+ test 'to_range with regexp and number' do
56
+ assert_equal Range.new(1, -1, true), RegexpRange.new(/^1consec/, -1, true).to_range(@lines)
57
+ assert_equal Range.new(1, -1, false), RegexpRange.new(/^1consec/, -1, false).to_range(@lines)
58
+ assert_equal Range.new(1, 5, true), RegexpRange.new(/^1consec/, 5, true).to_range(@lines)
59
+ assert_equal Range.new(1, 5, false), RegexpRange.new(/^1consec/, 5, false).to_range(@lines)
60
+
61
+ assert_equal @lines[Range.new(1, -1, true)],
62
+ @lines[RegexpRange.new(/^1consec/, -1, true).to_range(@lines)]
63
+ assert_equal @lines[Range.new(1, -1, false)],
64
+ @lines[RegexpRange.new(/^1consec/, -1, false).to_range(@lines)]
65
+
66
+ assert_raises RegexpRange::PatternMatchError do
67
+ RegexpRange.new(/^NO_MATCH$/, 5, true).to_range(@lines)
68
+ end
69
+ assert_raises RegexpRange::PatternMatchError do
70
+ RegexpRange.new(/^NO_MATCH$/, 5, false).to_range(@lines)
71
+ end
72
+ end
73
+
74
+ test 'to_range with regexp and regexp' do
75
+ assert_equal Range.new(1, 3, true),
76
+ RegexpRange.new(/^1consec/, /^3Ut/, true).to_range(@lines)
77
+ assert_equal Range.new(1, 3, false),
78
+ RegexpRange.new(/^1consec/, /^3Ut/, false).to_range(@lines)
79
+
80
+ assert_equal @lines[Range.new(1, 3, true)],
81
+ @lines[RegexpRange.new(/^1consec/, /^3Ut/, true).to_range(@lines)]
82
+ assert_equal @lines[Range.new(1, 3, false)],
83
+ @lines[RegexpRange.new(/^1consec/, /^3Ut/, false).to_range(@lines)]
84
+
85
+ assert_raises RegexpRange::PatternMatchError do
86
+ RegexpRange.new(/^NO_MATCH$/, /^NO_MATCH$/, true).to_range(@lines)
87
+ end
88
+ assert_raises RegexpRange::PatternMatchError do
89
+ RegexpRange.new(/^NO_MATCH$/, /^NO_MATCH$/, false).to_range(@lines)
90
+ end
91
+ end
92
+
93
+ test 'comparison to self' do
94
+ rr1 = RegexpRange.new(/start/, /end/, false)
95
+ assert_equal rr1, rr1
96
+ end
97
+
98
+ test 'comparison to identical regexprange' do
99
+ rr1 = RegexpRange.new(/start/, /end/, false)
100
+ rr2 = RegexpRange.new(/start/, /end/, false)
101
+ assert_equal rr1, rr2
102
+ end
103
+
104
+ test 'comparison to different regexprange' do
105
+ rr1 = RegexpRange.new(/start/, /end/, false)
106
+ rr2 = RegexpRange.new(/start/, /end/, true)
107
+ refute_equal rr1, rr2
108
+
109
+ rr3 = RegexpRange.new(/start/, /end/, false)
110
+ rr4 = RegexpRange.new(/start/, /finish/, false)
111
+ refute_equal rr3, rr4
112
+
113
+ rr5 = RegexpRange.new(/start/, /end/, true)
114
+ rr6 = RegexpRange.new(/begin/, /end/, true)
115
+ refute_equal rr5, rr6
116
+ end
117
+
118
+ test 'hash key comparison' do
119
+ rr1 = RegexpRange.new(/start/, /end/, false)
120
+ rr2 = RegexpRange.new(/start/, /end/, false)
121
+ rr3 = RegexpRange.new(/start/, /end/, true)
122
+
123
+ hash = Hash.new { |h, k| h[k] = 0 }
124
+
125
+ hash[rr1] += 1
126
+ hash[rr2] += 1
127
+ hash[rr3] += 1
128
+
129
+ assert_equal 2, hash.keys.length
130
+
131
+ assert_equal 2, hash[rr1]
132
+ assert_equal 2, hash[rr2]
133
+ assert_equal 1, hash[rr3]
134
+ end
135
+ end
@@ -0,0 +1,37 @@
1
+ # This allows us different filesystem paths for different platforms
2
+ ---
3
+ test_files: &test_files
4
+ root: <%= Dir.mktmpdir %>
5
+
6
+ ? !ruby/regexp /.*/
7
+ :
8
+ dbs_outbox:
9
+ root: "/mounts/ron/dbs_outbox"
10
+ prms:
11
+ - r
12
+ - w
13
+ - x
14
+ broken_space:
15
+ root: "potato"
16
+ prms:
17
+ - r
18
+ - w
19
+ - x
20
+ test_space_r:
21
+ <<: *test_files
22
+ prms:
23
+ - r
24
+ test_space_w:
25
+ <<: *test_files
26
+ prms:
27
+ - w
28
+ test_space_rw:
29
+ <<: *test_files
30
+ prms:
31
+ - r
32
+ - w
33
+ permanent_test_files:
34
+ root: <%#= Rails.root.join("test","unit","files") %>
35
+ prms:
36
+ - r
37
+ - w
@@ -0,0 +1,597 @@
1
+ require 'test_helper'
2
+
3
+ # Switch on the patientlimiter as though in external environment
4
+
5
+ class SafeFileTest < Minitest::Test
6
+ def setup
7
+ @not_empty_fpath = SafePath.new('test_space_rw').join('test_file_rw_not_empty')
8
+
9
+ File.open(@not_empty_fpath, 'w') do |f|
10
+ f.write 'I am not empty'
11
+ end
12
+
13
+ @empty_fpath = SafePath.new('test_space_rw').join('test_file_rw')
14
+
15
+ File.open(@empty_fpath, 'w') do |f|
16
+ f.write ''
17
+ end
18
+ end
19
+
20
+ def teardown
21
+ FileUtils.rm(Dir[SafePath.new('test_space_rw').join('*')])
22
+ end
23
+
24
+ ################################################################################
25
+ # .new
26
+
27
+ test 'constructor should accept safe_path only' do
28
+ assert_raises ArgumentError do
29
+ SafeFile.new('example_file', 'rw')
30
+ end
31
+ end
32
+
33
+ test 'should raise exception if try to write in read-only space' do
34
+ assert_raises SecurityError do
35
+ SafeFile.new(SafePath.new('test_space_r').join!('test_file_r'), 'a+')
36
+ end
37
+
38
+ assert_raises SecurityError do
39
+ SafeFile.new(SafePath.new('test_space_r').join!('test_file_r'), 'a')
40
+ end
41
+
42
+ assert_raises SecurityError do
43
+ SafeFile.new(SafePath.new('test_space_r').join!('test_file_r'), 'r+')
44
+ end
45
+
46
+ assert_raises SecurityError do
47
+ SafeFile.new(SafePath.new('test_space_r').join!('test_file_r'), 'w')
48
+ end
49
+ end
50
+
51
+ test 'should raise exception if try to read in write only space' do
52
+ assert_raises SecurityError do
53
+ SafeFile.new(SafePath.new('test_space_w').join!('test_file_w'), 'a+')
54
+ end
55
+
56
+ assert_raises SecurityError do
57
+ SafeFile.new(SafePath.new('test_space_w').join!('test_file_w'), 'r+')
58
+ end
59
+
60
+ assert_raises SecurityError do
61
+ SafeFile.new(SafePath.new('test_space_w').join!('test_file_w'), 'r')
62
+ end
63
+ end
64
+
65
+ test 'should read from read-only space and write to write only space' do
66
+ write_only_path = SafePath.new('test_space_w').join!('new_file_rw_new_file')
67
+ read_only_path = SafePath.new('test_space_r').join!('new_file_rw_new_file')
68
+ refute File.exist?(read_only_path)
69
+
70
+ f = SafeFile.new(write_only_path, 'w')
71
+ assert_equal 4, f.write('test')
72
+ f.close
73
+
74
+ assert File.exist?(read_only_path)
75
+
76
+ f = SafeFile.new(read_only_path, 'r')
77
+ assert_equal 'test', f.read
78
+ f.close
79
+ end
80
+
81
+ test 'should read/write from file with new to rw space' do
82
+ fpath = SafePath.new('test_space_rw').join!('new_file_rw_new_file')
83
+
84
+ refute File.exist?(fpath)
85
+
86
+ f = SafeFile.new(fpath, 'w')
87
+ assert_equal 4, f.write('test')
88
+ f.close
89
+
90
+ assert File.exist?(fpath)
91
+
92
+ f = SafeFile.new(fpath, 'r')
93
+ assert_equal 'test', f.read
94
+ f.close
95
+ end
96
+
97
+ test 'should accept mode types' do
98
+ s = SafeFile.new(@empty_fpath, 'r')
99
+ s.close
100
+
101
+ s = SafeFile.new(@empty_fpath, 'w')
102
+ s.close
103
+
104
+ s = SafeFile.new(@empty_fpath, 'r+')
105
+ s.close
106
+
107
+ s = SafeFile.new(@empty_fpath, 'w+')
108
+ s.close
109
+
110
+ s = SafeFile.new(@empty_fpath, 'a+')
111
+ s.close
112
+
113
+ s = SafeFile.new(@empty_fpath, 'a')
114
+ s.close
115
+ end
116
+
117
+ test 'should raise exception if incorect mode passed' do
118
+ assert_raises ArgumentError do
119
+ SafeFile.new(@empty_fpath, 'potato_mode')
120
+ end
121
+
122
+ assert_raises ArgumentError do
123
+ SafeFile.new(@empty_fpath, 'rw+a+')
124
+ end
125
+
126
+ assert_raises ArgumentError do
127
+ SafeFile.new(@empty_fpath, 'r+w+')
128
+ end
129
+ end
130
+
131
+ test 'should accept permissions' do
132
+ f = SafeFile.new(@empty_fpath, 'r', 755)
133
+ f.close
134
+
135
+ SafeFile.new(@empty_fpath, 755)
136
+ end
137
+
138
+ ################################################################################
139
+ # ::open
140
+
141
+ test '::open should accept safe_path only' do
142
+ p = SafePath.new('test_space_rw').join('test1')
143
+
144
+ refute File.exist?(p)
145
+
146
+ assert_raises ArgumentError do
147
+ SafeFile.open(p.to_s, 'r') do |f|
148
+ f.write 'hohohoho'
149
+ end
150
+ end
151
+
152
+ assert_raises ArgumentError do
153
+ f = SafeFile.open(p.to_s, 'r')
154
+ f.write 'hohohoho'
155
+ f.close
156
+ end
157
+
158
+ refute File.exist?(p)
159
+ end
160
+
161
+ test '::open should check pathspace permissions' do
162
+ read_only_path = SafePath.new('test_space_r').join!('new_file_rw_blablabla')
163
+ write_only_path = SafePath.new('test_space_w').join!('test_file_rw_not_empty')
164
+
165
+ refute File.exist?(read_only_path)
166
+
167
+ assert_raises SecurityError do
168
+ SafeFile.open(read_only_path, 'w') do |f|
169
+ f.write('test')
170
+ end
171
+ end
172
+
173
+ refute File.exist?(read_only_path)
174
+
175
+ fcontent = 'something else'
176
+
177
+ assert_raises SecurityError do
178
+ SafeFile.open(write_only_path, 'r') do |f|
179
+ fcontent = f.read
180
+ end
181
+ end
182
+
183
+ refute_equal fcontent, File.read(write_only_path)
184
+ end
185
+
186
+ test '::open should read/write from file' do
187
+ fpath = SafePath.new('test_space_rw').join!('new_file_rw_blablabla')
188
+ read_only_path = SafePath.new('test_space_r').join!('new_file_rw_blablabla')
189
+ write_only_path = SafePath.new('test_space_w').join!('new_file_rw_blablabla')
190
+ refute File.exist?(fpath)
191
+
192
+ SafeFile.open(fpath, 'w') do |f|
193
+ assert_equal 4, f.write('test')
194
+ end
195
+
196
+ SafeFile.open(fpath, 'r') do |f|
197
+ assert_equal 'test', f.read
198
+ end
199
+
200
+ # Test how the defailt arguments work
201
+ SafeFile.open(read_only_path) do |f|
202
+ assert_equal 'test', f.read
203
+ end
204
+
205
+ # Test how the defailt arguments work
206
+ assert_raises SecurityError do
207
+ SafeFile.open(write_only_path) do |f|
208
+ assert_equal 'test', f.read
209
+ end
210
+ end
211
+
212
+ assert_equal 1, File.delete(fpath)
213
+ end
214
+
215
+ test '::open should accept fs permissions with block' do
216
+ p = SafePath.new('test_space_rw').join('test1')
217
+
218
+ SafeFile.open(p, 'w', 255) do |f|
219
+ f.write 'test332'
220
+ end
221
+
222
+ assert File.exist?(p)
223
+ end
224
+
225
+ test '::open should accept fs permissions with no block' do
226
+ p = SafePath.new('test_space_rw').join('test1')
227
+
228
+ f = SafeFile.open(p, 'w', 255)
229
+ f.close
230
+
231
+ assert File.exist?(p)
232
+ end
233
+
234
+ test '::open should work as new if no block passed' do
235
+ p = SafePath.new('test_space_r').join('test_file_rw')
236
+
237
+ f = SafeFile.open(p)
238
+ assert_equal SafeFile, f.class
239
+ f.close
240
+ end
241
+
242
+ ################################################################################
243
+ # ::read
244
+
245
+ test '::read should accept safe_path only' do
246
+ assert_raises ArgumentError do
247
+ SafeFile.read @not_empty_fpath.to_s
248
+ end
249
+ end
250
+
251
+ test '::read should check pathspace permissions' do
252
+ write_only_path = SafePath.new('test_space_w').join('test_file_rw')
253
+
254
+ fcontent = 'none'
255
+ assert_raises SecurityError do
256
+ fcontent = SafeFile.read(write_only_path)
257
+ end
258
+ assert_equal 'none', fcontent
259
+ end
260
+
261
+ test '::read should read file content' do
262
+ assert File.read(@not_empty_fpath), SafeFile.read(@not_empty_fpath)
263
+ end
264
+
265
+ ################################################################################
266
+ # .read
267
+
268
+ test '#read should check pathspace permissions' do
269
+ p = SafePath.new('test_space_w').join('test_file_rw_not_empty')
270
+
271
+ f = SafeFile.new(p, 'w')
272
+ assert_raises SecurityError do
273
+ f.read
274
+ end
275
+ f.close
276
+ end
277
+
278
+ test '#read should read read-only namespace' do
279
+ p = SafePath.new('test_space_r').join('test_file_rw_not_empty')
280
+
281
+ f = SafeFile.new(p, 'r')
282
+ assert_equal 'I am not empty', f.read
283
+ f.close
284
+ end
285
+
286
+ ################################################################################
287
+ # .write
288
+
289
+ test '#write should check pathspace permissions' do
290
+ p = SafePath.new('test_space_r').join('test_file_rw_not_empty')
291
+
292
+ f = SafeFile.new(p, 'r')
293
+ assert_raises SecurityError do
294
+ f.write 'junk'
295
+ end
296
+ f.close
297
+ end
298
+
299
+ test '#write should write to write namespace' do
300
+ p = SafePath.new('test_space_rw').join('test1')
301
+
302
+ f = SafeFile.new(p, 'w')
303
+ f.write 'good test'
304
+ f.close
305
+
306
+ f = SafeFile.new(p, 'r')
307
+ assert_equal 'good test', f.read
308
+ f.close
309
+
310
+ assert File.exist? p.to_s
311
+ File.delete p
312
+ end
313
+
314
+ ################################################################################
315
+ # .path
316
+
317
+ test '#path should return instance of SafePath' do
318
+ p = SafePath.new('test_space_r').join('test_file_rw_not_empty')
319
+
320
+ f = SafeFile.new(p)
321
+ assert_equal SafePath, f.path.class
322
+ refute_equal p.object_id, f.path.object_id
323
+ assert_equal p, f.path
324
+ end
325
+
326
+ ################################################################################
327
+ # .close
328
+
329
+ test '#close should close the file' do
330
+ p = SafePath.new('test_space_w').join('test_file_rw')
331
+ f = SafeFile.new(p, 'w')
332
+ f.write 'test'
333
+ f.close
334
+ end
335
+
336
+ ################################################################################
337
+ # ::extname
338
+
339
+ test '::extname should accept safe_path only' do
340
+ assert_raises ArgumentError do
341
+ SafeFile.extname 'bad/extention.rb'
342
+ end
343
+ end
344
+
345
+ test '::extname should NOT check pathspace permissions' do
346
+ read_only_path = SafePath.new('test_space_r').join('test_file_rw_not_empty')
347
+ write_only_path = SafePath.new('test_space_w').join('test_file_rw_not_empty')
348
+
349
+ SafeFile.extname read_only_path
350
+ SafeFile.extname write_only_path
351
+ end
352
+
353
+ test '::extname should return the extention only' do
354
+ assert_equal '.rb', SafeFile.extname(SafePath.new('test_space_r').join('test_file.rb'))
355
+ assert_equal '', SafeFile.extname(SafePath.new('test_space_r').join('test_file'))
356
+ end
357
+
358
+ ################################################################################
359
+ # ::basename
360
+
361
+ test '::basename should accept safe_path only' do
362
+ assert_raises ArgumentError do
363
+ SafeFile.basename('some/evil/path.rb')
364
+ end
365
+
366
+ assert_raises ArgumentError do
367
+ SafeFile.basename('some/evil/path.rb', '.rb')
368
+ end
369
+ end
370
+
371
+ test '::basename should NOT check pathspace permissions' do
372
+ read_only_path = SafePath.new('test_space_r').join('test_file_rw_not_empty')
373
+ write_only_path = SafePath.new('test_space_w').join('test_file_rw_not_empty')
374
+
375
+ SafeFile.basename read_only_path
376
+ SafeFile.basename write_only_path
377
+ end
378
+
379
+ test '::basename should should return the basename' do
380
+ p = SafePath.new('test_space_rw').join('myfile.rb')
381
+
382
+ assert_equal 'myfile.rb', SafeFile.basename(p)
383
+ assert_equal 'myfile', SafeFile.basename(p, '.rb')
384
+ end
385
+
386
+ ################################################################################
387
+ # ::readlines
388
+
389
+ test "::readlines shouldn't accept more than 2 and less than 1 arguments" do
390
+ p = SafePath.new('test_space_r').join('test_file_rw')
391
+ assert_raises ArgumentError do
392
+ SafeFile.readlines
393
+ end
394
+
395
+ assert_raises ArgumentError do
396
+ SafeFile.readlines(p, 'junk_argument1', :junk_argument2)
397
+ end
398
+
399
+ assert_raises ArgumentError do
400
+ SafeFile.readlines('junk/path/to/file.rb')
401
+ end
402
+ end
403
+
404
+ test '::readlines should check pathspace permissions' do
405
+ p = SafePath.new('test_space_w').join('test_file_rw')
406
+ assert_raises SecurityError do
407
+ SafeFile.readlines(p)
408
+ end
409
+ end
410
+
411
+ test '::readlines should read lines from file' do
412
+ p = SafePath.new('test_space_r').join('test_file_rw')
413
+ # Use file because this test should be independent on the rest of the functionality of SafeFile
414
+ File.open(p, 'w') do |f|
415
+ f.write "there are three\nlines in this file\nand eight words"
416
+ end
417
+
418
+ lines = SafeFile.readlines(p)
419
+
420
+ assert_equal 3, lines.length
421
+ assert_equal "there are three\n", lines[0]
422
+ assert_equal "lines in this file\n", lines[1]
423
+ assert_equal 'and eight words', lines[2]
424
+
425
+ lines = SafeFile.readlines(p, ' ')
426
+ assert_equal 8, lines.length
427
+ assert_equal 'there ', lines[0]
428
+ end
429
+
430
+ ################################################################################
431
+ # ::directory?
432
+
433
+ test '::directory? should accept only safe_path' do
434
+ assert_raises ArgumentError do
435
+ SafeFile.directory?('some/junk/path')
436
+ end
437
+ end
438
+
439
+ test '::directory? should NOT check for pathspace permissions' do
440
+ read_only_path = SafePath.new('test_space_r').join('test_file_rw_not_empty')
441
+ write_only_path = SafePath.new('test_space_w').join('test_file_rw_not_empty')
442
+
443
+ SafeFile.directory?(read_only_path)
444
+ SafeFile.directory?(write_only_path)
445
+ end
446
+
447
+ test '::directory? should return true if the path is a directory and false otherwise' do
448
+ p = SafePath.new('test_space_r')
449
+ assert SafeFile.directory?(p)
450
+ refute SafeFile.directory?(p.join('test_file_rw_not_empty'))
451
+ end
452
+
453
+ ################################################################################
454
+ # ::exist? ::exists?
455
+
456
+ test '::exist? and ::exists? should accept only safe_path' do
457
+ assert_raises ArgumentError do
458
+ SafeFile.exist?('some/junk/path')
459
+ end
460
+
461
+ assert_raises ArgumentError do
462
+ SafeFile.exist?('some/junk/path')
463
+ end
464
+ end
465
+
466
+ test '::exist? and ::exists? should NOT check pathspace permissions' do
467
+ read_only_path = SafePath.new('test_space_r').join('test_file_rw_not_empty')
468
+ write_only_path = SafePath.new('test_space_w').join('test_file_rw_not_empty')
469
+
470
+ SafeFile.exist?(read_only_path)
471
+ SafeFile.exist?(write_only_path)
472
+ SafeFile.exist?(read_only_path)
473
+ SafeFile.exist?(write_only_path)
474
+ end
475
+
476
+ test 'exist? and exists? should return true if the file exists and false otherwise' do
477
+ real = SafePath.new('test_space_r').join('test_file_rw')
478
+ junk = SafePath.new('test_space_r').join('test_file_rw_junk')
479
+
480
+ assert SafeFile.exist?(real)
481
+ assert SafeFile.exist?(real)
482
+
483
+ refute SafeFile.exist?(junk)
484
+ refute SafeFile.exist?(junk)
485
+ end
486
+
487
+ ################################################################################
488
+ # ::file?
489
+
490
+ test '::file? should accept safe_path only' do
491
+ assert_raises ArgumentError do
492
+ SafeFile.file?('some/junk.path')
493
+ end
494
+ end
495
+
496
+ test '::file? should NOT check pathspace permissions' do
497
+ read_only_path = SafePath.new('test_space_r').join('test_file_rw_not_empty')
498
+ write_only_path = SafePath.new('test_space_w').join('test_file_rw_not_empty')
499
+
500
+ SafeFile.file?(read_only_path)
501
+ SafeFile.file?(write_only_path)
502
+ end
503
+
504
+ test 'file? should return true of the path is file and false otherwise' do
505
+ file = SafePath.new('test_space_r').join('test_file_rw')
506
+ dir = SafePath.new('test_space_r')
507
+
508
+ assert SafeFile.file?(file)
509
+ refute SafeFile.file?(dir)
510
+ end
511
+
512
+ ################################################################################
513
+ # ::zero?
514
+
515
+ test '::zero? should accept only SafePath' do
516
+ assert_raises ArgumentError do
517
+ SafeFile.zero? SafePath.new('test_space_w').join!('test_file_rw').to_s
518
+ end
519
+ end
520
+
521
+ test '::zero? should NOT check pathspace permissions' do
522
+ read_only_path = SafePath.new('test_space_r').join('test_file_rw_not_empty')
523
+ write_only_path = SafePath.new('test_space_w').join('test_file_rw_not_empty')
524
+
525
+ SafeFile.zero?(read_only_path)
526
+ SafeFile.zero?(write_only_path)
527
+ end
528
+
529
+ test '::zero? should return true when the file is empty and false otherwise' do
530
+ assert SafeFile.zero? SafePath.new('test_space_rw').join!('test_file_rw')
531
+ refute SafeFile.zero?(SafePath.new('test_space_rw').join!('test_file_rw_not_empty'))
532
+ end
533
+
534
+ ################################################################################
535
+ # ::dirname
536
+
537
+ test '::dirname should accept safe_path only' do
538
+ assert_raises ArgumentError do
539
+ SafeFile.dirname('some/junk/path')
540
+ end
541
+ end
542
+
543
+ test '::dirname should NOT check pathspace permissions' do
544
+ read_only_path = SafePath.new('test_space_r').join('test_file_rw_not_empty')
545
+ write_only_path = SafePath.new('test_space_w').join('test_file_rw_not_empty')
546
+
547
+ SafeFile.dirname(read_only_path)
548
+ SafeFile.dirname(write_only_path)
549
+ end
550
+
551
+ test '::dirname should return the directory' do
552
+ p = SafePath.new('test_space_r')
553
+
554
+ assert_equal SafePath, SafeFile.dirname(p.join('test_file_rw')).class
555
+ refute_equal p.object_id, SafeFile.dirname(p.join('test_file_rw')).object_id
556
+
557
+ assert_equal p.to_s, SafeFile.dirname(p.join('test_file_rw')).to_s
558
+ end
559
+
560
+ ################################################################################
561
+ # ::delete
562
+
563
+ test '::delete should accept safe_path only' do
564
+ assert_raises ArgumentError do
565
+ SafeFile.delete('test_path')
566
+ end
567
+ end
568
+
569
+ test '::delete should check pathspace permissions' do
570
+ assert_raises SecurityError do
571
+ SafeFile.delete(SafePath.new('test_space_r').join!('test_file_r'))
572
+ end
573
+ end
574
+
575
+ test '::delete should delete file/files' do
576
+ sp = SafePath.new('test_space_w').join!('new_test_file')
577
+
578
+ group = [SafePath.new('test_space_w').join!('new_test_file1'),
579
+ SafePath.new('test_space_w').join!('new_test_file2'),
580
+ SafePath.new('test_space_w').join!('new_test_file3')]
581
+
582
+ (group + [sp]).each do |fname|
583
+ # This test should't depend on the rest of the functionality of SafeFile
584
+ File.open(fname, 'w') { |f| f.write 'test' }
585
+ end
586
+
587
+ SafeFile.delete sp
588
+
589
+ refute File.exist?(sp)
590
+
591
+ SafeFile.delete(*group)
592
+
593
+ group.each do |fname|
594
+ refute File.exist?(fname)
595
+ end
596
+ end
597
+ end