rordash 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,182 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Metrics/ModuleLength
4
+ module Rordash
5
+ RSpec.describe HashUtil do
6
+ let(:hash) { { data: { nestedKey: { id: "some-identifier", items: [4, 9, 7] } } } }
7
+
8
+ describe 'dot notation' do
9
+ let(:dotted_hash) do
10
+ { "data.nestedKey.id" => "some-identifier",
11
+ "data.nestedKey.items[0]" => 4,
12
+ "data.nestedKey.items[1]" => 9,
13
+ "data.nestedKey.items[2]" => 7 }
14
+ end
15
+
16
+ describe ".dot" do
17
+ it "flattens deeply nested objects using dot notation" do
18
+ expect(described_class.dot(hash, keep_arrays: false)).to eql(dotted_hash)
19
+ end
20
+ end
21
+
22
+ describe ".dotted_keys" do
23
+ it "flattens deeply nested objects to keys in dot notation" do
24
+ expect(described_class.dotted_keys(hash, keep_arrays: false)).to eql(dotted_hash.keys)
25
+ end
26
+ end
27
+
28
+ describe ".undot" do
29
+ it "hydrates dotted hash to deeply nested object" do
30
+ expect(described_class.undot(dotted_hash)).to eql(hash)
31
+ end
32
+ end
33
+
34
+ describe '.pick' do
35
+ it 'picks keys from hash' do
36
+ paths = %w[data.nestedKey.id data.nestedKey.items[2] data.nestedKey.items[1]]
37
+ expect(described_class.pick(hash, paths,
38
+ keep_arrays: false)).to eql({ data: { nestedKey: { id: "some-identifier",
39
+ items: [9, 7] } } })
40
+ end
41
+ end
42
+
43
+ describe '.get' do
44
+ it 'picks keys from hash' do
45
+ expect(described_class.get(hash, 'data.nestedKey.items[1]')).to be(9)
46
+ end
47
+ end
48
+
49
+ describe '.set' do
50
+ it 'sets key value pair at specified dotted path' do
51
+ expect(described_class.set({}, 'data.nestedKey.items[1]',
52
+ 10)).to eql({ data: { nestedKey: { items: [nil, 10] } } })
53
+ end
54
+ end
55
+
56
+ describe 'reject_blank_values' do
57
+ let(:input) { { a: '', b: ' ', c: nil, d: '123', e: [], f: {} } }
58
+
59
+ it 'removes blank values' do
60
+ expect(described_class.reject_blank_values(input)).to eql({ d: "123", e: [], f: {} })
61
+ end
62
+
63
+ it 'does not deep remove blank values' do
64
+ expect(described_class.reject_blank_values(input.merge(f: { g: '' }))).to eql({ d: "123", e: [],
65
+ f: { g: '' } })
66
+ end
67
+ end
68
+
69
+ describe 'deep_reject_blank_values' do
70
+ let(:input) { { a: '', b: ' ', c: nil, d: '123', e: [], f: { g: '' }, h: [1, nil, '', ' ', 3] } }
71
+
72
+ it 'removes deep blank values' do
73
+ expect(described_class.deep_reject_blank_values(input)).to eql({ d: "123", h: [1, 3] })
74
+ end
75
+ end
76
+ end
77
+
78
+ describe ".from_string" do
79
+ let(:input) { JSON.dump(a: 1) }
80
+
81
+ it "convert json string to hash" do
82
+ expect(described_class.from_string(input)).to eql({ a: 1 })
83
+ end
84
+
85
+ it "handles hashes" do
86
+ expect(described_class.from_string(a: 1)).to eql(a: 1)
87
+ end
88
+ end
89
+
90
+ describe ".group_by" do
91
+ let(:input) { [6.5, 4.12, 6.8, 5.4] }
92
+
93
+ context 'with hash input' do
94
+ let(:input) { [{ shared_key: 1, a: 1 }, { shared_key: 2, b: 2 }, { shared_key: 1, c: 3 }] }
95
+
96
+ it 'handles key only' do
97
+ expect(described_class.group_by(input,
98
+ :shared_key)).to eql({
99
+ 1 => [{ shared_key: 1, a: 1 },
100
+ { shared_key: 1,
101
+ c: 3 }], 2 => [{ shared_key: 2, b: 2 }]
102
+ })
103
+ end
104
+ end
105
+
106
+ it "groups elements" do
107
+ expect(described_class.group_by(input, lambda { |val|
108
+ val.floor
109
+ })).to eql({ 4 => [4.12], 5 => [5.4], 6 => [6.5, 6.8] })
110
+ end
111
+ end
112
+
113
+ describe '.get_first_present' do
114
+ let(:google_address) { '2253-20800 Westminster Hwy, Richmond, BC V6V 2W3, Canada' }
115
+ let(:input) do
116
+ { 'google_address' => '',
117
+ 'main_property' => { 'google_address' => '2253-20800 Westminster Hwy, Richmond, BC V6V 2W3, Canada' } }
118
+ end
119
+ let(:paths) { %w[google_address main_property.google_address] }
120
+
121
+ subject(:present_val) { described_class.get_first_present(input, paths) }
122
+
123
+ it 'returns first filled match' do
124
+ expect(present_val).to eql(google_address)
125
+ end
126
+ end
127
+
128
+ describe '.digest' do
129
+ let(:input) { { key: 'some-value' } }
130
+
131
+ subject(:digested_str) { described_class.digest(input) }
132
+ it 'returns encoded digest string of input' do
133
+ expect(digested_str).to eql('POWr8Qgq9OA+L8ejA4gkAG2kgNs=')
134
+ end
135
+ end
136
+
137
+ describe ".to_str" do
138
+ it "convert hash to json string" do
139
+ # rubocop:disable Layout/LineLength
140
+ expect(described_class.to_str(hash)).to eql("{\"data\":{\"nestedKey\":{\"id\":\"some-identifier\",\"items\":[4,9,7]}}}")
141
+ # rubocop:enable Layout/LineLength
142
+ end
143
+
144
+ it "handles strings" do
145
+ expect(described_class.to_str("{ a: 1 }")).to eql("{ a: 1 }")
146
+ end
147
+ end
148
+
149
+ describe ".pretty" do
150
+ it "returns correctly formatted string" do
151
+ expect(described_class.pretty(hash)).to eql(%({
152
+ "data": {
153
+ "nestedKey": {
154
+ "id": "some-identifier",
155
+ "items": [
156
+ 4,
157
+ 9,
158
+ 7
159
+ ]
160
+ }
161
+ }
162
+ }))
163
+ end
164
+
165
+ context 'with array' do
166
+ let(:input) { [{ a: 1 }, b: 2] }
167
+
168
+ it "returns correctly formatted string" do
169
+ expect(described_class.pretty(input)).to eql(%([
170
+ {
171
+ "a": 1
172
+ },
173
+ {
174
+ "b": 2
175
+ }
176
+ ]))
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+ # rubocop:enable Metrics/ModuleLength
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rordash
4
+ RSpec.describe NumericUtil do
5
+ describe '.numeric?' do
6
+ let(:value) { '12345' }
7
+
8
+ subject(:is_numeric) { described_class.numeric?(value) }
9
+
10
+ it 'returns true' do
11
+ expect(is_numeric).to be_truthy
12
+ end
13
+
14
+ context 'with value with non numeric values' do
15
+ let(:value) { '12A345' }
16
+
17
+ it 'returns false' do
18
+ expect(is_numeric).to be_falsey
19
+ end
20
+ end
21
+
22
+ context 'with blank value' do
23
+ let(:value) { '' }
24
+
25
+ it 'returns false' do
26
+ expect(is_numeric).to be_falsey
27
+ end
28
+ end
29
+
30
+ context 'with whitespace' do
31
+ let(:value) { ' 1' }
32
+
33
+ it 'returns false' do
34
+ expect(is_numeric).to be_truthy
35
+ end
36
+ end
37
+ end
38
+
39
+ describe '.convert_unit' do
40
+ let(:from_unit) { :m }
41
+ let(:to_unit) { :ft }
42
+ let(:value) { 10 }
43
+
44
+ subject(:converted_unit) { described_class.convert_unit(value, from_unit: from_unit, to_unit: to_unit) }
45
+
46
+ it 'calculates amount correctly' do
47
+ expect(converted_unit.round(4)).to be(32.8084)
48
+ end
49
+ end
50
+
51
+ describe '.convert_unit_sq' do
52
+ let(:from_unit) { :m }
53
+ let(:to_unit) { :ft }
54
+ let(:value) { 25 }
55
+
56
+ subject(:sq_unit) { described_class.convert_unit_sq(value, from_unit: from_unit, to_unit: to_unit) }
57
+
58
+ it 'calculates amount correctly' do
59
+ expect(sq_unit.round(3)).to be(269.098)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rordash
4
+ RSpec.describe ObjectUtil do
5
+ describe '.to_classname' do
6
+ context 'when given a class object that is not defined' do
7
+ it 'returns nil' do
8
+ expect(described_class.to_classname("Foo")).to be_nil
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rordash
4
+ RSpec.describe PathUtil do
5
+ describe '#fixtures_path' do
6
+ context 'without arg' do
7
+ it 'returns full fixture path' do
8
+ fixtures_path = Rails.root.join('spec', 'fixtures')
9
+
10
+ expect(described_class.fixtures_path).to eql(Pathname.new(fixtures_path))
11
+ end
12
+ end
13
+
14
+ context 'with filename' do
15
+ let(:filename) { 'some-file-name.png ' }
16
+
17
+ it 'returns full fixture path' do
18
+ fixtures_path = Rails.root.join('spec', 'fixtures')
19
+ expect(described_class.fixtures_path(filename)).to eql(Pathname.new("#{fixtures_path}/#{filename}"))
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rordash
4
+ RSpec.describe RegexUtil do
5
+ describe '.match?' do
6
+ subject(:matched) { described_class.match?(type, value) }
7
+
8
+ let(:value) { nil }
9
+ let(:type) { nil }
10
+
11
+ describe ':email' do
12
+ let(:type) { :email }
13
+
14
+ context 'with valid email' do
15
+ let(:value) { 'email@domain.com' }
16
+
17
+ it 'returns true' do
18
+ expect(matched).to be_truthy
19
+ end
20
+ end
21
+
22
+ context 'with invalid email' do
23
+ let(:value) { 'emaild.g' }
24
+
25
+ it 'returns false' do
26
+ expect(matched).to be_falsey
27
+ end
28
+ end
29
+ end
30
+
31
+ context 'with a URI' do
32
+ it 'returns true for a valid URI' do
33
+ expect(described_class.match?(:uri, 'https://www.example.com')).to be_truthy
34
+ end
35
+
36
+ it 'returns false for an invalid URI' do
37
+ expect(described_class.match?(:uri, 'not a uri')).to be_falsey
38
+ end
39
+ end
40
+
41
+ context 'with a postal code' do
42
+ it 'returns true for a valid postal code' do
43
+ expect(described_class.match?(:postal_code, 'V5K 0A1')).to be_truthy
44
+ end
45
+
46
+ it 'returns false for an invalid postal code' do
47
+ expect(described_class.match?(:postal_code, 'not a postal code')).to be_falsey
48
+ end
49
+ end
50
+
51
+ context 'with a dotted index' do
52
+ it 'returns true for a valid dotted index' do
53
+ expect(described_class.match?(:dotted_index, 'person.address[0]')).to be_truthy
54
+ end
55
+
56
+ it 'returns false for an invalid dotted index' do
57
+ expect(described_class.match?(:dotted_index, 'not a dotted index')).to be_falsey
58
+ end
59
+ end
60
+ end
61
+
62
+ describe '#match' do
63
+ it 'returns the matched value for a successful match' do
64
+ expect(described_class.match(:uri, 'https://www.example.com').to_s).to eq('https://www.example.com')
65
+ end
66
+
67
+ it 'returns nil for an unsuccessful match' do
68
+ expect(described_class.match(:uri, 'not a uri')).to be_nil
69
+ end
70
+ end
71
+
72
+ describe '#replace' do
73
+ it 'replaces the matched value with the replacement string' do
74
+ expect(described_class.replace(:postal_code, 'V5K 0A1', 'REDACTED')).to eq('REDACTED')
75
+ end
76
+
77
+ it 'returns the original value if the regular expression does not match' do
78
+ expect(described_class.replace(:postal_code, 'not a postal code', 'REDACTED')).to eq('not a postal code')
79
+ end
80
+
81
+ it 'returns the original value if the value is not a string' do
82
+ expect(described_class.replace(:postal_code, 123, 'REDACTED')).to eq(123)
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rordash
4
+ RSpec.describe UrlUtil do
5
+ let(:url) { "http://html.joe.com/Jobs/123/249 Subert Place Feb29'27.pdf" }
6
+
7
+ describe '.safe_escape' do
8
+ it 'encodes url' do
9
+ expect(described_class.safe_escape(url)).to eql("http://html.joe.com/Jobs/123/249%20Subert%20Place%20Feb29'27.pdf")
10
+ end
11
+ end
12
+
13
+ describe '.error_from_http_status' do
14
+ it 'returns appropriate http status message' do
15
+ expect(described_class.error_from_http_status(400)).to eql("Bad Request")
16
+ end
17
+
18
+ context 'with invalid http status code' do
19
+ it 'unknown http code message' do
20
+ expect(described_class.error_from_http_status(-1)).to eql("Invalid HTTP Status Code")
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Rordash do
4
+ it "has a version number" do
5
+ expect(Rordash::VERSION).not_to be_nil
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.join(__dir__, "..", 'dev', 'setup')
4
+ require Pathname.new(__dir__).realpath.join('coverage_helper').to_s
5
+
6
+ unless defined? Rails
7
+ module Rails
8
+ class << self
9
+ def root
10
+ Pathname.new(__dir__).join('..')
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ RSpec.configure do |config|
17
+ # Enable flags like --only-failures and --next-failure
18
+ config.example_status_persistence_file_path = ".rspec_status"
19
+
20
+ # Disable RSpec exposing methods globally on `Module` and `main`
21
+ config.disable_monkey_patching!
22
+
23
+ config.expect_with :rspec do |c|
24
+ c.syntax = :expect
25
+ end
26
+ end