hashematics 1.0.0

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.
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'spec_helper'
11
+
12
+ describe ::Hashematics::Key do
13
+ describe '#eql?' do
14
+ it 'should compare Key objects' do
15
+ expect(described_class.new('id')).to eq(described_class.new('id'))
16
+ expect(described_class.new('id')).to eq(described_class.new(:id))
17
+ expect(described_class.new(['id'])).to eq(described_class.new('id'))
18
+ expect(described_class.new([:id])).to eq(described_class.new('id'))
19
+ expect(described_class.new([:id])).to eq(described_class.new(['id']))
20
+ end
21
+
22
+ it 'should compare Key with string' do
23
+ expect(described_class.new('id')).to eq('id')
24
+ expect(described_class.new(:id)).to eq('id')
25
+ end
26
+
27
+ it 'should compare Key with symbol' do
28
+ expect(described_class.new('id')).to eq(:id)
29
+ expect(described_class.new(:id)).to eq(:id)
30
+ end
31
+
32
+ it 'should compare Key with array' do
33
+ expect(described_class.new('id')).to eq(['id'])
34
+ expect(described_class.new(:id)).to eq([:id])
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'spec_helper'
11
+ require 'examples/person'
12
+
13
+ describe ::Hashematics::ObjectInterface do
14
+ let(:input) do
15
+ {
16
+ id: 1,
17
+ 'first' => 'Matt'
18
+ }
19
+ end
20
+
21
+ let(:person) { Person.new(input) }
22
+
23
+ it 'should read hash indifferently' do
24
+ expect(described_class.get(input, :id)).to eq(input[:id])
25
+ expect(described_class.get(input, 'id')).to eq(input[:id])
26
+ expect(described_class.get(input, :first)).to eq(input['first'])
27
+ expect(described_class.get(input, 'first')).to eq(input['first'])
28
+
29
+ expect(described_class.get(person, 'doesnt_exist')).to eq(nil)
30
+ expect(described_class.get(person, :doesnt_exist)).to eq(nil)
31
+ end
32
+
33
+ it 'should read object if object is responsive' do
34
+ expect(described_class.get(person, :id)).to eq(input[:id])
35
+ expect(described_class.get(person, 'id')).to eq(input[:id])
36
+ expect(described_class.get(person, :first)).to eq(input['first'])
37
+ expect(described_class.get(person, 'first')).to eq(input['first'])
38
+
39
+ expect(described_class.get(person, 'doesnt_exist')).to eq(nil)
40
+ expect(described_class.get(person, :doesnt_exist)).to eq(nil)
41
+ end
42
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'spec_helper'
11
+
12
+ describe ::Hashematics::RecordSet do
13
+ let(:csv_rows) { csv_fixture('data.csv') }
14
+
15
+ let(:record_set) { described_class.new }
16
+
17
+ subject { record_set }
18
+
19
+ specify '#rows returns the original dataset' do
20
+ csv_rows.each { |row| subject.add(row) }
21
+
22
+ expect(subject.rows).to eq(csv_rows)
23
+ end
24
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'spec_helper'
11
+
12
+ describe ::Hashematics::Record do
13
+ let(:csv_rows) { csv_fixture('data.csv') }
14
+
15
+ describe '#category_id' do
16
+ it 'returns correct ID for specified keys' do
17
+ records = csv_rows.map { |row| described_class.new(row) }
18
+
19
+ keys = [
20
+ 'ID #',
21
+ ['ID #', 'Car ID #'],
22
+ ['ID #', 'House ID #']
23
+ ].map { |p| ::Hashematics::Key.new(p) }
24
+
25
+ keys.each do |key|
26
+ records.each do |record|
27
+ concat_only = key.map { |p| "#{p}::#{record[p]}" }.join('::')
28
+ expected_id_value = ::Hashematics::Id.digest(concat_only)
29
+
30
+ actual_id_value = record.id(key).value
31
+
32
+ expect(actual_id_value).to eq(expected_id_value)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ describe '#eql?' do
39
+ it 'should compare Record objects' do
40
+ expect(described_class.new(id: 1)).to eq(described_class.new(id: 1))
41
+ expect(described_class.new(id: 1)).not_to eq(described_class.new(id: '1'))
42
+ end
43
+
44
+ it 'should compare Record to Hash objects' do
45
+ expect(described_class.new(id: 1)).to eq(id: 1)
46
+ expect(described_class.new(id: 1)).not_to eq(id: '1')
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'spec_helper'
11
+ require 'examples/person'
12
+
13
+ describe ::Hashematics::Type do
14
+ let(:input) do
15
+ {
16
+ id: 1,
17
+ first: 'Matt',
18
+ middle: 'Elfy',
19
+ last: 'Rizzo'
20
+ }
21
+ end
22
+
23
+ let(:person) { Person.new(input) }
24
+
25
+ context 'when input is an object' do
26
+ context 'with no properties and object does not respond to keys' do
27
+ specify '#convert makes blank object' do
28
+ type = described_class.new
29
+
30
+ actual = type.convert(person)
31
+
32
+ expect(actual).to eq({})
33
+ end
34
+ end
35
+ end
36
+
37
+ context 'when input is a hash' do
38
+ context 'with no properties but object responds to keys' do
39
+ specify '#convert makes object' do
40
+ type = described_class.new
41
+
42
+ actual = type.convert(input)
43
+
44
+ expect(actual).to eq(input)
45
+ end
46
+ end
47
+
48
+ context 'with property array' do
49
+ let(:properties) { [:id, 'first', :last] }
50
+
51
+ context 'with proc/lambda object_class' do
52
+ let(:expected) do
53
+ {
54
+ id: '1 - Processed',
55
+ 'first' => 'Matt - Processed',
56
+ last: 'Rizzo - Processed'
57
+ }
58
+ end
59
+
60
+ let(:object_class) do
61
+ lambda do |h|
62
+ h.map { |k, v| [k, "#{v} - Processed"] }.to_h
63
+ end
64
+ end
65
+
66
+ specify '#convert makes object' do
67
+ type = described_class.new(properties: properties, object_class: object_class)
68
+
69
+ actual = type.convert(input)
70
+
71
+ expect(actual).to eq(expected)
72
+ end
73
+ end
74
+
75
+ context 'with class object_class' do
76
+ specify '#convert makes object' do
77
+ type = described_class.new(properties: properties, object_class: Person)
78
+
79
+ actual = type.convert(input)
80
+
81
+ expect(actual).to eq(person)
82
+ end
83
+ end
84
+
85
+ context 'with nil object_class' do
86
+ let(:expected) do
87
+ {
88
+ id: 1,
89
+ 'first' => 'Matt',
90
+ last: 'Rizzo'
91
+ }
92
+ end
93
+
94
+ specify '#convert makes object' do
95
+ type = described_class.new(properties: properties)
96
+
97
+ actual = type.convert(input)
98
+
99
+ expect(actual).to eq(expected)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2018-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'pry'
11
+ require 'csv'
12
+
13
+ require 'simplecov'
14
+ require 'simplecov-console'
15
+ SimpleCov.formatter = SimpleCov::Formatter::Console
16
+ SimpleCov.start
17
+
18
+ require './lib/hashematics'
19
+
20
+ def fixture_path(*filename)
21
+ File.join('spec', 'fixtures', filename)
22
+ end
23
+
24
+ def csv_fixture(*filename)
25
+ CSV.new(fixture(*filename), headers: true).map(&:to_h)
26
+ end
27
+
28
+ def yaml_fixture(*filename)
29
+ # rubocop:disable Security/YAMLLoad
30
+ YAML.load(fixture(*filename))
31
+ # rubocop:enable Security/YAMLLoad
32
+ end
33
+
34
+ def fixture(*filename)
35
+ # Excel adds a Byte Order Mark to the beginning of the file. Let Ruby
36
+ # know about this so that the first 'id' column is correctly parsed.
37
+ # More info about the Excel Byte Order Mark and Ruby is available at:
38
+ # https://estl.tech/of-ruby-and-hidden-csv-characters-ef482c679b35 .
39
+ file = File.open(fixture_path(*filename), 'r:bom|utf-8')
40
+
41
+ file.read
42
+ end
metadata ADDED
@@ -0,0 +1,211 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hashematics
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Matthew Ruggio
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-04-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faker
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: guard-rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pdf-inspector
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.8'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.8'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.63.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.63.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.16.1
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.16.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov-console
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.4.2
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.4.2
125
+ description: " Hashematics is a configuration-based object graphing tool which
126
+ can turn a flat, single dimensional dataset into a structure of deeply nested objects.\n"
127
+ email:
128
+ - mruggio@bluemarblepayroll.com
129
+ executables:
130
+ - benchmark
131
+ - console
132
+ extensions: []
133
+ extra_rdoc_files: []
134
+ files:
135
+ - ".editorconfig"
136
+ - ".gitignore"
137
+ - ".rubocop.yml"
138
+ - ".ruby-version"
139
+ - ".travis.yml"
140
+ - CHANGELOG.md
141
+ - Gemfile
142
+ - Gemfile.lock
143
+ - Guardfile
144
+ - LICENSE
145
+ - README.md
146
+ - bin/benchmark
147
+ - bin/console
148
+ - hashematics.gemspec
149
+ - lib/hashematics.rb
150
+ - lib/hashematics/category.rb
151
+ - lib/hashematics/configuration.rb
152
+ - lib/hashematics/dictionary.rb
153
+ - lib/hashematics/graph.rb
154
+ - lib/hashematics/group.rb
155
+ - lib/hashematics/hashematics.rb
156
+ - lib/hashematics/id.rb
157
+ - lib/hashematics/key.rb
158
+ - lib/hashematics/object_interface.rb
159
+ - lib/hashematics/record.rb
160
+ - lib/hashematics/record_set.rb
161
+ - lib/hashematics/type.rb
162
+ - lib/hashematics/version.rb
163
+ - lib/hashematics/visitor.rb
164
+ - spec/examples/person.rb
165
+ - spec/fixtures/config.yml
166
+ - spec/fixtures/data.csv
167
+ - spec/fixtures/people.yml
168
+ - spec/hashematics/category_spec.rb
169
+ - spec/hashematics/graph_spec.rb
170
+ - spec/hashematics/key_spec.rb
171
+ - spec/hashematics/object_interface_spec.rb
172
+ - spec/hashematics/record_set_spec.rb
173
+ - spec/hashematics/record_spec.rb
174
+ - spec/hashematics/type_spec.rb
175
+ - spec/spec_helper.rb
176
+ homepage: https://github.com/bluemarblepayroll/hashematics
177
+ licenses:
178
+ - MIT
179
+ metadata: {}
180
+ post_install_message:
181
+ rdoc_options: []
182
+ require_paths:
183
+ - lib
184
+ required_ruby_version: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: 2.3.8
189
+ required_rubygems_version: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ requirements: []
195
+ rubygems_version: 3.0.1
196
+ signing_key:
197
+ specification_version: 4
198
+ summary: Configurable Data Shaper
199
+ test_files:
200
+ - spec/examples/person.rb
201
+ - spec/fixtures/config.yml
202
+ - spec/fixtures/data.csv
203
+ - spec/fixtures/people.yml
204
+ - spec/hashematics/category_spec.rb
205
+ - spec/hashematics/graph_spec.rb
206
+ - spec/hashematics/key_spec.rb
207
+ - spec/hashematics/object_interface_spec.rb
208
+ - spec/hashematics/record_set_spec.rb
209
+ - spec/hashematics/record_spec.rb
210
+ - spec/hashematics/type_spec.rb
211
+ - spec/spec_helper.rb