metahash-rb 1.0.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 +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +53 -0
- data/Rakefile +1 -0
- data/lib/metahash.rb +50 -0
- data/lib/metahash/metadata.rb +135 -0
- data/lib/metahash/version.rb +3 -0
- data/metahash.gemspec +32 -0
- data/spec/metadata_spec.rb +58 -0
- data/spec/metahash_spec.rb +54 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/support/models/test_object.rb +3 -0
- data/spec/support/sample_hashes.rb +9 -0
- data/spec/support/schema.rb +8 -0
- data/tddium.yml +3 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4017650f154dc99effbfb8b354353dc193088eed
|
4
|
+
data.tar.gz: 49824be43db47b292c7326284b2aff91257e021f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ccdc5d25310105884c35fbbe09c07c7814ccc83953ba33e954abc3403faa862376543f9b17ecd0f3a517b9548dc5f406afcee6d9305a277fed8ceba737e5a36a
|
7
|
+
data.tar.gz: 9fa68441c4516a83050f90efc62b4369d3c5a97c959eb2b5b0b9e37f04cede5dfa014bdecc82c74e629888aead1827bdd4fd3a8238efe68961bb986d8b828c36
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 TinderBox
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
MetaHash
|
2
|
+
========
|
3
|
+
|
4
|
+
[](https://ci.solanolabs.com:443/TinderBox/MetaHash/suites/110842)
|
5
|
+
[](https://codeclimate.com/github/NullVoxPopuli/MetaHash)
|
6
|
+
[](https://gemnasium.com/NullVoxPopuli/MetaHash)
|
7
|
+
|
8
|
+
|
9
|
+
Provides a subclass of Hash and a wrapper around Rails' serialize attribute for object-like access to hashes without validating existence of nested hashes
|
10
|
+
|
11
|
+
## Examples
|
12
|
+
#### Access nested hashes using method / object syntax
|
13
|
+
|
14
|
+
h = Metadata.new
|
15
|
+
h # => {}
|
16
|
+
h.outer.inner # => {}
|
17
|
+
|
18
|
+
#### Access to values stored in nested hashes via method call syntax
|
19
|
+
|
20
|
+
h = Metadata.new( { outer: { inner: { hash_key: "value" } } } )
|
21
|
+
h.outer.inner.hash_key # => "value"
|
22
|
+
|
23
|
+
#### Set values for nested hash structures without the nested hashes having to be initially defined
|
24
|
+
|
25
|
+
h = Metadata.new( {} )
|
26
|
+
|
27
|
+
## Using with ActiveRecord
|
28
|
+
|
29
|
+
#### In your Gemfile
|
30
|
+
|
31
|
+
gem "metahash-rb"
|
32
|
+
|
33
|
+
#### in your ActiveRecord model
|
34
|
+
|
35
|
+
has_metadata
|
36
|
+
|
37
|
+
or
|
38
|
+
|
39
|
+
has_metadata :field_not_called_metadata
|
40
|
+
|
41
|
+
|
42
|
+
## Support
|
43
|
+
|
44
|
+
This gem has been tested with Ruby 2.0, and rails 3.2, 4.1
|
45
|
+
|
46
|
+
|
47
|
+
## Contributing
|
48
|
+
|
49
|
+
1. Fork the project
|
50
|
+
2. Create a new, descriptively named branch
|
51
|
+
3. Add Test(s)!
|
52
|
+
4. Commit your proposed changes
|
53
|
+
5. Submit a pull request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/metahash.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require "metahash/metadata"
|
2
|
+
require "metahash/version"
|
3
|
+
require 'active_record'
|
4
|
+
|
5
|
+
module MetaHash
|
6
|
+
|
7
|
+
# When an active record object is loaded, convert to Metadata.
|
8
|
+
# If for whatever reason we lose this Metadata class, we can read
|
9
|
+
# the hash by creating class Metadata < Hash; end
|
10
|
+
#
|
11
|
+
# @param [Symbol] serialized_field name of the field to convert to Metadata
|
12
|
+
def has_metadata(serialized_field = "metadata")
|
13
|
+
# tell Active Record that the field is going to be JSON
|
14
|
+
# serialized, because JSON > YAML
|
15
|
+
serialize serialized_field, JSON
|
16
|
+
|
17
|
+
after_initialize do |record|
|
18
|
+
# first check the type of the field
|
19
|
+
# proceed if hash, abort if Metadata
|
20
|
+
if record.has_attribute?(serialized_field)
|
21
|
+
if [Hash, NilClass].include?(record.send(serialized_field).class)
|
22
|
+
# alias the old method / field
|
23
|
+
backup_name = "#{serialized_field}_original".to_sym
|
24
|
+
# alias_method backup_name, serialized_field
|
25
|
+
record.define_singleton_method backup_name, record.method(serialized_field)
|
26
|
+
# name the metadata accessor the same as the original field
|
27
|
+
# rails should automatically serialize this on save
|
28
|
+
initial_value = record.send(backup_name) || {}
|
29
|
+
record.send("#{serialized_field}=", Metadata.new(initial_value))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
# create a before_save hook to store a pure Hash in the DB
|
36
|
+
before_save do |record|
|
37
|
+
@temp_metadata = record.send(serialized_field)
|
38
|
+
record.send("#{serialized_field}=", @temp_metadata.to_hash) if @temp_metadata
|
39
|
+
end
|
40
|
+
|
41
|
+
# restore the metadata to the field
|
42
|
+
after_save do |record|
|
43
|
+
record.send("#{serialized_field}=", @temp_metadata) if @temp_metadata
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
ActiveRecord::Base.send :extend, MetaHash
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# MetadataHash - A specific use of ruby's Hash
|
2
|
+
#
|
3
|
+
# overrides Hash's method missing, providing the following functionality:
|
4
|
+
# 1. Access Nested hashes using the method / attribute syntax
|
5
|
+
# i.e.: h = {}
|
6
|
+
# h.middle.inner == {}
|
7
|
+
#
|
8
|
+
# 2. Access to values stored in nested hashes via method call syntax
|
9
|
+
# i.e.: h = { middle: { inner: { key: "value" } } }
|
10
|
+
# h.middle.inner.key == "value"
|
11
|
+
#
|
12
|
+
# 3. Set values for nested hash structures without middle nested hashes
|
13
|
+
# having to be defined
|
14
|
+
# i.e.: h = {}
|
15
|
+
# h.middle.inner = 3
|
16
|
+
# h == { middle: { inner: 3 } }
|
17
|
+
#
|
18
|
+
# 4. Old hash square bracket access still works
|
19
|
+
# i.e.: h = { inner: { key: "value" } }
|
20
|
+
# h[:inner][:key] == "value"
|
21
|
+
#
|
22
|
+
class Metadata < Hash
|
23
|
+
|
24
|
+
# the hash being passed in will have all its subhashes converted to
|
25
|
+
# metadata hashes.
|
26
|
+
# this is needed to we can have the
|
27
|
+
#
|
28
|
+
# @raise [ArgumentError] if one of the keys is method of Hash
|
29
|
+
# @raise [ArgumentError] if hash is not a type of Hash or Metadata
|
30
|
+
# @param [Hash] hash the structure to convert to Metadata
|
31
|
+
def initialize(hash = {})
|
32
|
+
# for maybe instantiating nested hashes that we
|
33
|
+
# aren't yet sure if they are going to have values or not
|
34
|
+
@empty_nested_hashes = []
|
35
|
+
|
36
|
+
if hash.is_a?(Metadata)
|
37
|
+
# we have nothing to do
|
38
|
+
return hash
|
39
|
+
elsif hash.is_a?(Hash)
|
40
|
+
# recursively create nested metadata objects
|
41
|
+
hash.each do |key, value|
|
42
|
+
if not valid_key?(key)
|
43
|
+
raise ArgumentError.new("Not Allowed. '#{key}' is a reserved method.")
|
44
|
+
end
|
45
|
+
|
46
|
+
self[key] = (
|
47
|
+
if value.is_a?(Hash)
|
48
|
+
Metadata.new(value)
|
49
|
+
elsif value.is_a?(Array)
|
50
|
+
# ensure hashes kept in an array are also converted to metadata
|
51
|
+
array = value.map{ |element|
|
52
|
+
element.is_a?(Hash) ? Metadata.new(element) : element
|
53
|
+
}
|
54
|
+
else
|
55
|
+
value
|
56
|
+
end
|
57
|
+
)
|
58
|
+
end
|
59
|
+
else
|
60
|
+
raise ArgumentError.new("Field must be a Hash or Metadata")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# this is what allows functionality mentioned in the class comment to happen
|
66
|
+
# @raise [ArgumentError] if one of the keys is method of Hash
|
67
|
+
def method_missing(method_name, *args)
|
68
|
+
# check for assignment
|
69
|
+
if (key = method_name.to_s).include?("=")
|
70
|
+
key = key.chop.to_sym
|
71
|
+
if not self.valid_key?(key)
|
72
|
+
raise ArgumentError.new("Not Allowed. '#{key}' is a reserved method.")
|
73
|
+
end
|
74
|
+
|
75
|
+
if not @empty_nested_hashes.empty?
|
76
|
+
deepest_metadata = self
|
77
|
+
@empty_nested_hashes.each do |key|
|
78
|
+
deepest_metadata = deepest_metadata[key] = Metadata.new
|
79
|
+
end
|
80
|
+
@empty_nested_hashes = []
|
81
|
+
deepest_metadata[key] = args[0]
|
82
|
+
end
|
83
|
+
else
|
84
|
+
value = self[method_name]
|
85
|
+
if not value
|
86
|
+
@empty_nested_hashes << method_name.to_sym
|
87
|
+
value = self
|
88
|
+
end
|
89
|
+
value
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
# Metdata has indifferent access
|
95
|
+
def [](key)
|
96
|
+
super(key.to_sym)
|
97
|
+
end
|
98
|
+
|
99
|
+
# # Metadata has indifferent access,
|
100
|
+
# # so just say that all the keys are symbols.
|
101
|
+
def []=(key, value)
|
102
|
+
super(key.to_sym, value)
|
103
|
+
end
|
104
|
+
|
105
|
+
# tests the ability to use this key as a key in a hash
|
106
|
+
# @param [Symbol] key
|
107
|
+
# @return [Boolean] whether or not this can be used as a hash key
|
108
|
+
def valid_key?(key)
|
109
|
+
# second parameter says that we are
|
110
|
+
# looking at private methods as well
|
111
|
+
not self.respond_to?(key, true)
|
112
|
+
end
|
113
|
+
|
114
|
+
# convert to regular hash, recursively
|
115
|
+
def to_hash
|
116
|
+
hash = {}
|
117
|
+
self.each do |k,v|
|
118
|
+
hash[k] = (
|
119
|
+
if v.is_a?(Metadata)
|
120
|
+
v.to_hash
|
121
|
+
elsif v.is_a?(Array)
|
122
|
+
v.map{ |e| e.is_a?(Metadata) ? e.to_hash : e }
|
123
|
+
else
|
124
|
+
v
|
125
|
+
end
|
126
|
+
)
|
127
|
+
end
|
128
|
+
|
129
|
+
hash
|
130
|
+
end
|
131
|
+
|
132
|
+
def to_ary
|
133
|
+
self.to_hash.to_a
|
134
|
+
end
|
135
|
+
end
|
data/metahash.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "metahash/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "metahash-rb"
|
9
|
+
s.version = MetaHash::VERSION
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.license = "MIT"
|
12
|
+
s.authors = ["L. Preston Sego III"]
|
13
|
+
s.email = "LPSego3+dev@gmail.com"
|
14
|
+
s.homepage = "https://github.com/NullVoxPopuli/MetaHash"
|
15
|
+
s.summary = "MetaHash-#{MetaHash::VERSION}"
|
16
|
+
s.description = "Provides a subclass of Hash and a wrapper around Rails' serialize attribute for object-like access to hashes without validating existence of nested hashes."
|
17
|
+
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split($/)
|
20
|
+
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
21
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
|
24
|
+
|
25
|
+
s.add_runtime_dependency "activerecord", ">= 3.0.0"
|
26
|
+
s.add_development_dependency "bundler"
|
27
|
+
s.add_development_dependency "rspec"
|
28
|
+
s.add_development_dependency "sqlite3"
|
29
|
+
s.add_development_dependency "pry-byebug"
|
30
|
+
s.add_development_dependency "codeclimate-test-reporter"
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Metadata do
|
4
|
+
|
5
|
+
it "is a hash" do
|
6
|
+
expect(Metadata.new).to be_kind_of(Hash)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "pruning empty hashes" do
|
10
|
+
let(:m){Metadata.new}
|
11
|
+
|
12
|
+
it "removes empty hashes" do
|
13
|
+
m.a.b.c
|
14
|
+
expect(m.send :prune).to eq Metadata.new
|
15
|
+
end
|
16
|
+
|
17
|
+
it "does not remove valid hashes" do
|
18
|
+
m.a.b = 2
|
19
|
+
expect(m.send :prune).to_not eq Metadata.new
|
20
|
+
end
|
21
|
+
|
22
|
+
it "does not pollute itself with empty hashes" do
|
23
|
+
m.a.b.c
|
24
|
+
expect(m).to eq Metadata.new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
it "sets a non-exsiting deep value" do
|
30
|
+
m = Metadata.new
|
31
|
+
m.a.b = 2
|
32
|
+
expect(m.a.b).to eq 2
|
33
|
+
end
|
34
|
+
|
35
|
+
it "has indifferent access" do
|
36
|
+
m = Metadata.new(a: 2)
|
37
|
+
expect(m.a).to eq 2
|
38
|
+
expect(m[:a]).to eq 2
|
39
|
+
expect(m["a"]).to eq 2
|
40
|
+
end
|
41
|
+
|
42
|
+
it "allows method-style access to nested hashes" do
|
43
|
+
m = Metadata.new(h)
|
44
|
+
expect(m.outer.inner.k).to eq h[:outer][:inner][:k]
|
45
|
+
end
|
46
|
+
|
47
|
+
it "allows hash-style access to nested hashes" do
|
48
|
+
m = Metadata.new(h)
|
49
|
+
expect(m[:outer][:inner][:k]).to eq h[:outer][:inner][:k]
|
50
|
+
end
|
51
|
+
|
52
|
+
it "does not allow hash keys to conflict with the name of a method of the Hash object" do
|
53
|
+
expect{
|
54
|
+
Metadata.new( outer: { key: "value" } )
|
55
|
+
}.to raise_error
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe MetaHash do
|
4
|
+
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
m = TestObject.new(metadata: h, name: "MetaHash")
|
8
|
+
m.save
|
9
|
+
end
|
10
|
+
|
11
|
+
after(:each) do
|
12
|
+
TestObject.destroy_all
|
13
|
+
end
|
14
|
+
|
15
|
+
it "converts the chose field to Metadata" do
|
16
|
+
p = TestObject.last
|
17
|
+
expect(p.metadata).to be_kind_of(Metadata)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "instantiates with an empty hash if the field is nil" do
|
21
|
+
p = TestObject.new
|
22
|
+
p.metadata = nil
|
23
|
+
p = TestObject.last
|
24
|
+
expect(p.metadata).to_not be_nil
|
25
|
+
expect(p.metadata).to be_kind_of(Metadata)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "does not modify the original contents of the chosen field on initialization" do
|
29
|
+
p = TestObject.last
|
30
|
+
expect(p.metadata.to_hash).to eq Metadata.new(h)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "creates an alias for the original field's data" do
|
34
|
+
p = TestObject.last
|
35
|
+
expect(p.metadata_original).to eq Metadata.new(h)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "doesn't error when a the attribute is not included in the retrieval of a record" do
|
39
|
+
expect{
|
40
|
+
p = TestObject.select("name")
|
41
|
+
}.to_not raise_error
|
42
|
+
end
|
43
|
+
|
44
|
+
it "converts the field back to a Hash before saving to the database" do
|
45
|
+
db = ActiveRecord::Base.connection.select_all("
|
46
|
+
SELECT metadata
|
47
|
+
FROM test_objects
|
48
|
+
").last
|
49
|
+
p = db["metadata"]
|
50
|
+
expect(JSON.load(p)).to eq JSON.load(h.to_json)
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
require "rubygems"
|
3
|
+
require "bundler/setup"
|
4
|
+
require "metahash"
|
5
|
+
require "pry-byebug" # binding.pry to debug!
|
6
|
+
require "codeclimate-test-reporter"
|
7
|
+
CodeClimate::TestReporter.start
|
8
|
+
|
9
|
+
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
10
|
+
load File.dirname(__FILE__) + '/support/schema.rb'
|
11
|
+
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
17
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
18
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
19
|
+
# loaded once.
|
20
|
+
#
|
21
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
22
|
+
RSpec.configure do |config|
|
23
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
24
|
+
config.run_all_when_everything_filtered = true
|
25
|
+
config.filter_run :focus
|
26
|
+
|
27
|
+
# Run specs in random order to surface order dependencies. If you find an
|
28
|
+
# order dependency and want to debug it, you can fix the order by providing
|
29
|
+
# the seed, which is printed after each run.
|
30
|
+
# --seed 1234
|
31
|
+
config.order = 'random'
|
32
|
+
end
|
data/tddium.yml
ADDED
metadata
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: metahash-rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- L. Preston Sego III
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sqlite3
|
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: pry-byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: codeclimate-test-reporter
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Provides a subclass of Hash and a wrapper around Rails' serialize attribute
|
98
|
+
for object-like access to hashes without validating existence of nested hashes.
|
99
|
+
email: LPSego3+dev@gmail.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- ".rspec"
|
106
|
+
- Gemfile
|
107
|
+
- LICENSE
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- lib/metahash.rb
|
111
|
+
- lib/metahash/metadata.rb
|
112
|
+
- lib/metahash/version.rb
|
113
|
+
- metahash.gemspec
|
114
|
+
- spec/metadata_spec.rb
|
115
|
+
- spec/metahash_spec.rb
|
116
|
+
- spec/spec_helper.rb
|
117
|
+
- spec/support/models/test_object.rb
|
118
|
+
- spec/support/sample_hashes.rb
|
119
|
+
- spec/support/schema.rb
|
120
|
+
- tddium.yml
|
121
|
+
homepage: https://github.com/NullVoxPopuli/MetaHash
|
122
|
+
licenses:
|
123
|
+
- MIT
|
124
|
+
metadata: {}
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
require_paths:
|
128
|
+
- lib
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
requirements: []
|
140
|
+
rubyforge_project:
|
141
|
+
rubygems_version: 2.4.1
|
142
|
+
signing_key:
|
143
|
+
specification_version: 4
|
144
|
+
summary: MetaHash-1.0.1
|
145
|
+
test_files:
|
146
|
+
- spec/metadata_spec.rb
|
147
|
+
- spec/metahash_spec.rb
|
148
|
+
- spec/spec_helper.rb
|
149
|
+
- spec/support/models/test_object.rb
|
150
|
+
- spec/support/sample_hashes.rb
|
151
|
+
- spec/support/schema.rb
|