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.
- checksums.yaml +15 -0
- data/.gitignore +14 -0
- data/.rubocop.yml +27 -0
- data/.ruby-version +1 -0
- data/.travis.yml +22 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/Guardfile +16 -0
- data/LICENSE.txt +21 -0
- data/README.md +91 -0
- data/Rakefile +12 -0
- data/code_safety.yml +258 -0
- data/gemfiles/Gemfile.rails32 +6 -0
- data/gemfiles/Gemfile.rails32.lock +108 -0
- data/gemfiles/Gemfile.rails41 +6 -0
- data/gemfiles/Gemfile.rails41.lock +111 -0
- data/gemfiles/Gemfile.rails42 +6 -0
- data/gemfiles/Gemfile.rails42.lock +111 -0
- data/lib/ndr_support.rb +21 -0
- data/lib/ndr_support/array.rb +52 -0
- data/lib/ndr_support/concerns/working_days.rb +94 -0
- data/lib/ndr_support/date_and_time_extensions.rb +103 -0
- data/lib/ndr_support/daterange.rb +196 -0
- data/lib/ndr_support/fixnum/calculations.rb +15 -0
- data/lib/ndr_support/fixnum/julian_date_conversions.rb +14 -0
- data/lib/ndr_support/hash.rb +52 -0
- data/lib/ndr_support/integer.rb +12 -0
- data/lib/ndr_support/nil.rb +38 -0
- data/lib/ndr_support/ourdate.rb +97 -0
- data/lib/ndr_support/ourtime.rb +51 -0
- data/lib/ndr_support/regexp_range.rb +65 -0
- data/lib/ndr_support/safe_file.rb +185 -0
- data/lib/ndr_support/safe_path.rb +268 -0
- data/lib/ndr_support/string/cleaning.rb +136 -0
- data/lib/ndr_support/string/conversions.rb +137 -0
- data/lib/ndr_support/tasks.rb +1 -0
- data/lib/ndr_support/time/conversions.rb +13 -0
- data/lib/ndr_support/utf8_encoding.rb +72 -0
- data/lib/ndr_support/utf8_encoding/control_characters.rb +53 -0
- data/lib/ndr_support/utf8_encoding/force_binary.rb +44 -0
- data/lib/ndr_support/utf8_encoding/object_support.rb +31 -0
- data/lib/ndr_support/version.rb +5 -0
- data/lib/ndr_support/yaml/serialization_migration.rb +65 -0
- data/lib/tasks/audit_code.rake +423 -0
- data/ndr_support.gemspec +39 -0
- data/test/array_test.rb +20 -0
- data/test/concerns/working_days_test.rb +122 -0
- data/test/daterange_test.rb +194 -0
- data/test/fixnum/calculations_test.rb +28 -0
- data/test/hash_test.rb +84 -0
- data/test/integer_test.rb +14 -0
- data/test/nil_test.rb +40 -0
- data/test/ourdate_test.rb +27 -0
- data/test/ourtime_test.rb +27 -0
- data/test/regexp_range_test.rb +135 -0
- data/test/resources/filesystem_paths.yml +37 -0
- data/test/safe_file_test.rb +597 -0
- data/test/safe_path_test.rb +168 -0
- data/test/string/cleaning_test.rb +176 -0
- data/test/string/conversions_test.rb +353 -0
- data/test/test_helper.rb +41 -0
- data/test/time/conversions_test.rb +15 -0
- data/test/utf8_encoding/control_characters_test.rb +84 -0
- data/test/utf8_encoding/force_binary_test.rb +64 -0
- data/test/utf8_encoding_test.rb +170 -0
- data/test/yaml/serialization_test.rb +145 -0
- 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
|