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.
- checksums.yaml +7 -0
- data/.editorconfig +8 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +11 -0
- data/.ruby-version +1 -0
- data/.travis.yml +20 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +123 -0
- data/Guardfile +16 -0
- data/LICENSE +7 -0
- data/README.md +660 -0
- data/bin/benchmark +134 -0
- data/bin/console +11 -0
- data/hashematics.gemspec +32 -0
- data/lib/hashematics.rb +10 -0
- data/lib/hashematics/category.rb +67 -0
- data/lib/hashematics/configuration.rb +90 -0
- data/lib/hashematics/dictionary.rb +72 -0
- data/lib/hashematics/graph.rb +62 -0
- data/lib/hashematics/group.rb +57 -0
- data/lib/hashematics/hashematics.rb +36 -0
- data/lib/hashematics/id.rb +29 -0
- data/lib/hashematics/key.rb +76 -0
- data/lib/hashematics/object_interface.rb +35 -0
- data/lib/hashematics/record.rb +60 -0
- data/lib/hashematics/record_set.rb +29 -0
- data/lib/hashematics/type.rb +72 -0
- data/lib/hashematics/version.rb +12 -0
- data/lib/hashematics/visitor.rb +50 -0
- data/spec/examples/person.rb +36 -0
- data/spec/fixtures/config.yml +44 -0
- data/spec/fixtures/data.csv +9 -0
- data/spec/fixtures/people.yml +84 -0
- data/spec/hashematics/category_spec.rb +62 -0
- data/spec/hashematics/graph_spec.rb +572 -0
- data/spec/hashematics/key_spec.rb +37 -0
- data/spec/hashematics/object_interface_spec.rb +42 -0
- data/spec/hashematics/record_set_spec.rb +24 -0
- data/spec/hashematics/record_spec.rb +49 -0
- data/spec/hashematics/type_spec.rb +104 -0
- data/spec/spec_helper.rb +42 -0
- metadata +211 -0
@@ -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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|