random_attributes 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0fb42eebf2719fd9e4eb30962ce7e4f22917ce2a
4
+ data.tar.gz: 315f87390f64da8c27f7a751b575d8a823f24f02
5
+ SHA512:
6
+ metadata.gz: 5459f78ca52131e811ca1fd89d59d0d6b47d0a1782b5779b690346426ba71e315fb4340da30bc6cc07b31e9193cd80405fc2bb2a5d7311f4a0891c670e01badc
7
+ data.tar.gz: d0592a236ec2a26f2693803df620c353d6a3dd739516b9719a3ea78ecfef6f0f49ecd93f734e109089c4c2114e55a5cbbc22a37bbd760611b1d00d766f4d73c6
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in random_attributes.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Rufus Post
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,181 @@
1
+ # RandomAttributes
2
+
3
+ Sometimes people give you rubbish data, when they do rather than wiring
4
+ everything up with hundreds of methods you could use RandomAttributes.
5
+
6
+ If mangling crappy data is not your issue you are probably better served by
7
+ something like [virtus](https://github.com/solnic/virtus).
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'random_attributes'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install random_attributes
22
+
23
+ ## Usage
24
+
25
+ Vanilla:
26
+
27
+ ```ruby
28
+ class Foo
29
+ include RandomAttributes
30
+ attribute "fooBar"
31
+ end
32
+
33
+ foo = Foo.parse { "fooBar" => "hello" }
34
+ foo.foo_bar #=> "hello"
35
+ ```
36
+
37
+ Alias:
38
+
39
+ ```ruby
40
+ class Foo
41
+ include RandomAttributes
42
+ attribute "fooBar", alias: :moo_bar
43
+ end
44
+
45
+ foo = Foo.parse { "fooBar" => "hello" }
46
+ foo.moo_bar #=> "hello"
47
+ ```
48
+
49
+ Type casting:
50
+
51
+ ```ruby
52
+ class Foo
53
+ include RandomAttributes
54
+ attribute "fooBar", type: String
55
+ end
56
+
57
+ foo = Foo.parse { "fooBar" => 34 }
58
+ foo.foo_bar #=> "34"
59
+ ```
60
+
61
+ Many possible values:
62
+
63
+ ```ruby
64
+ class Foo
65
+ include RandomAttributes
66
+ attribute ["fooBar", "mooBar"], alias: :foo_bar
67
+ end
68
+
69
+ foo = Foo.parse { "fooBar" => "hello" }
70
+ foo.foo_bar #=> "hello"
71
+
72
+ foo = Foo.parse { "mooBar" => "hello" }
73
+ foo.foo_bar #=> "hello"
74
+ ```
75
+
76
+ Trying another node:
77
+
78
+ ```ruby
79
+ class Foo
80
+ include RandomAttributes
81
+ attribute "parentNode"
82
+ attribute "fooBar", try: :parent_node
83
+ end
84
+
85
+ foo = Foo.parse { "fooBar" => "hello" }
86
+ foo.foo_bar #=> "hello"
87
+
88
+ foo = Foo.parse { "parentNode" => { "fooBar" => "hello" } }
89
+ foo.foo_bar #=> "hello"
90
+ ```
91
+
92
+ Nested within a node:
93
+
94
+ ```ruby
95
+ class Foo
96
+ include RandomAttributes
97
+ attribute "parentNode"
98
+ attribute "fooBar", within: :parent_node
99
+ end
100
+
101
+ foo = Foo.parse { "parentNode" => { "fooBar" => "hello" } }
102
+ foo.foo_bar #=> "hello"
103
+ ```
104
+
105
+ Models:
106
+
107
+ ```ruby
108
+ class Bar
109
+ attr_reader :message
110
+ def initialize message
111
+ @message = message
112
+ end
113
+ end
114
+
115
+ class Foo
116
+ include RandomAttributes
117
+ attribute "fooBar", model: Bar
118
+ end
119
+
120
+ foo = Foo.parse { "fooBar" => "hello" }
121
+ foo.foo_bar.message #=> "hello"
122
+ ```
123
+
124
+ Collections:
125
+
126
+ ```ruby
127
+ class Bar
128
+ attr_reader :message
129
+ def initialize message
130
+ @message = message
131
+ end
132
+ end
133
+
134
+ class Foo
135
+ include RandomAttributes
136
+ attribute "fooBar", collection: Bar
137
+ end
138
+
139
+ foo = Foo.parse { "fooBar" => ["hello", "goodbye"] }
140
+ foo.foo_bar.first.message #=> "hello"
141
+ foo.foo_bar.last.message #=> "goodbye"
142
+ ```
143
+
144
+ Parse data with proc:
145
+
146
+ ```ruby
147
+ class Foo
148
+ include RandomAttributes
149
+ attribute "fooBar", parse: ->(value) { "#{value} from a proc!" }
150
+ end
151
+
152
+ foo = Foo.parse { "fooBar" => "hello" }
153
+ foo.foo_bar #=> "hello from a proc!"
154
+ ```
155
+
156
+ Callbacks:
157
+
158
+ ```ruby
159
+ class Foo
160
+ include RandomAttributes
161
+ attribute "fooBar"
162
+ attribute "multipleFooBar"
163
+
164
+ after_parse :multiply_foo_bar
165
+
166
+ def multiply_foo_bar
167
+ set_attribute :multiple_foo_bar, foo_bar * 2
168
+ end
169
+ end
170
+
171
+ foo = Foo.parse { "fooBar" => 2 }
172
+ foo.multiple_foo_bar #=> 4
173
+ ```
174
+
175
+ ## Contributing
176
+
177
+ 1. Fork it
178
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
179
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
180
+ 4. Push to the branch (`git push origin my-new-feature`)
181
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ module RandomAttributes
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,200 @@
1
+ require "random_attributes/version"
2
+ require "active_support/concern"
3
+ require "active_support/callbacks"
4
+
5
+ # RandomAttributes
6
+ #
7
+ # Getters, setters and object building for a someone elses data structure.
8
+ #
9
+ # Example:
10
+ #
11
+ # class Runner
12
+ # include RandomAttributes
13
+ # attribute 'runnerName', alias: :name
14
+ # end
15
+ #
16
+ # runner = Runner.new "runnerName" => "Phar Lap"
17
+ # runner.name #=> "Phar Lap"
18
+ #
19
+ module RandomAttributes
20
+ extend ActiveSupport::Concern
21
+ include ActiveSupport::Callbacks
22
+
23
+ class Register
24
+ class AliasError < StandardError; end
25
+
26
+ attr_reader :originals, :aliased, :type, :parent_node, :try_node
27
+
28
+ def initialize(attrs, options = {})
29
+
30
+ if attrs.is_a?(Array)
31
+ raise AliasError, "if you want to alias attributes you need to specify the alias in the options" unless
32
+ options[:alias].present?
33
+ @aliased = options[:alias].to_s
34
+ else
35
+ @aliased = options[:alias].to_s.presence || attrs.underscore
36
+ attrs = [attrs]
37
+ end
38
+
39
+ @originals = attrs
40
+ @parent_node = options[:within]
41
+ @try_node = options[:try]
42
+
43
+ @type = options[:type]
44
+ @model = options[:model]
45
+ @collection = options[:collection]
46
+ @cast_proc = options[:parse] || cast_to_proc
47
+ end
48
+
49
+ def key
50
+ @originals.join '__'
51
+ end
52
+
53
+ def cast(value)
54
+ @cast_proc.call value
55
+ end
56
+
57
+ private
58
+
59
+ # TODO refactor this.
60
+ def cast_to_proc
61
+ if @type
62
+ ->(value) { value ? Kernel.send(@type.to_s, value) : value }
63
+ elsif @model
64
+ ->(value) { value ? @model.parse(value) : value }
65
+ elsif @collection
66
+ if @collection.respond_to?(:parse)
67
+ ->(value) {
68
+ if value
69
+ value.map do |member|
70
+ member.is_a?(@collection) ? member : @collection.parse(member)
71
+ end
72
+ else
73
+ []
74
+ end
75
+ }
76
+ else
77
+ ->(value) {
78
+ if value
79
+ value.map do |member|
80
+ member.is_a?(@collection) ? member : @collection.new(member)
81
+ end
82
+ else
83
+ []
84
+ end
85
+ }
86
+ end
87
+ else
88
+ ->(value) { value }
89
+ end
90
+ end
91
+ end
92
+
93
+ included do
94
+ define_callbacks :parse
95
+ end
96
+
97
+ module ClassMethods
98
+ def attribute(attrs, options = {})
99
+ register = Register.new attrs, options
100
+
101
+ attribute_register[register.aliased] = register
102
+
103
+ define_method register.aliased do
104
+ get_attribute register
105
+ end
106
+
107
+ define_method :"#{register.aliased}=" do |value|
108
+ set_attribute register.aliased, value
109
+ end
110
+ end
111
+
112
+ def attribute_register
113
+ @_attribute_register ||= {}
114
+ end
115
+
116
+ def parse(attributes)
117
+ new.parse attributes
118
+ end
119
+
120
+ def before_parse(*args, &block)
121
+ set_callback(:parse, :before, *args, &block)
122
+ end
123
+
124
+ def after_parse(*args, &block)
125
+ set_callback(:parse, :after, *args, &block)
126
+ end
127
+ end
128
+
129
+ def initialize(attrs = nil)
130
+ parse attrs
131
+ end
132
+
133
+ def cache_key
134
+ @raw_attributes_hash
135
+ end
136
+
137
+ def parse(attrs = nil)
138
+ @parsed_attributes = {}
139
+ attrs && attrs.stringify_keys!
140
+ run_callbacks :parse do
141
+ @raw_attributes = attributes.merge(attrs.nil? ? {} : attrs).freeze
142
+ @raw_attributes_hash = Digest::MD5.hexdigest(attributes.to_s)
143
+ end
144
+ self
145
+ end
146
+
147
+ alias :merge_attributes :parse
148
+
149
+ def attributes
150
+ @raw_attributes ||= {}.freeze
151
+ end
152
+
153
+ private
154
+
155
+ def parsed_attributes
156
+ @parsed_attributes ||= {}
157
+ end
158
+
159
+ def get_attribute(register)
160
+ if parsed_attributes.key?(register.aliased)
161
+ parsed_attributes[register.aliased]
162
+ else
163
+ parsed_attributes[register.aliased] = _get_attribute(register)
164
+ end
165
+ end
166
+
167
+ def set_attribute(key, value)
168
+ parsed_attributes[key.to_s] = value
169
+ end
170
+
171
+ def _search_originals(register, node, value = nil)
172
+ register.originals.each do |key|
173
+ break if value = node[key]
174
+ end
175
+ value
176
+ end
177
+
178
+ def _get_attribute(register)
179
+
180
+ value = attributes[register.aliased]
181
+
182
+ unless value
183
+ if register.try_node
184
+ if try_node = send(register.try_node)
185
+ value = _search_originals register, try_node
186
+ else
187
+ value = _search_originals register, attributes
188
+ end
189
+ elsif register.parent_node
190
+ if parent_node = send(register.parent_node)
191
+ value = _search_originals register, parent_node
192
+ end
193
+ else
194
+ value = _search_originals register, attributes
195
+ end
196
+ end
197
+
198
+ register.cast(value)
199
+ end
200
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'random_attributes/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "random_attributes"
8
+ spec.version = RandomAttributes::VERSION
9
+ spec.authors = ["Rufus Post"]
10
+ spec.email = ["rufuspost@gmail.com"]
11
+ spec.description = %q{When someone gives you rubbish data an you want to map it to something else.}
12
+ spec.summary = %q{Data hash to object mapper}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "active_support", ">= 3.0"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "rspec", "~> 2.14"
26
+ spec.add_development_dependency "ffaker"
27
+ end
@@ -0,0 +1,164 @@
1
+ require 'spec_helper'
2
+ require 'active_support/core_ext/hash'
3
+ require 'ffaker'
4
+
5
+ class TestAttributeThing
6
+ include RandomAttributes
7
+
8
+ attribute 'name'
9
+ end
10
+
11
+ class TestAttributeCasting
12
+ include RandomAttributes
13
+
14
+ attribute 'name'
15
+ attribute 'venue', type: String
16
+ attribute 'fooName', alias: :bar_name
17
+ attribute 'raceIdentifier', alias: :identifier, type: String
18
+ attribute 'number', type: Integer
19
+ attribute 'stake', type: Float
20
+ attribute ['fooMeeting', 'barMeeting'], alias: :meeting
21
+ attribute 'manyThings', collection: TestAttributeThing
22
+ attribute 'singleThing', model: TestAttributeThing
23
+ attribute 'someDetails', alias: :details
24
+ attribute 'nestedDetail', within: :details
25
+ attribute ['status', 'raceStatus'], alias: :status, try: :details
26
+ attribute 'afterParseValue'
27
+ attribute 'afterOptions', parse: ->(value) { "#{value} after parse!" }
28
+
29
+ after_parse :change_value
30
+
31
+ def change_value
32
+ # We have to use this method here because I can't figure out why the
33
+ # dynamic method is not working.
34
+ set_attribute :after_parse_value, 'after parse!'
35
+ end
36
+ end
37
+
38
+ describe RandomAttributes do
39
+ let(:string) {
40
+ Faker::Name.name
41
+ }
42
+
43
+ it "should default to given type" do
44
+ subject = TestAttributeCasting.parse 'name' => string
45
+ subject.name.should eq string
46
+ end
47
+
48
+ it "should cast strings and rename attribute" do
49
+ subject = TestAttributeCasting.parse 'venue' => string
50
+ subject.venue.should be_a(String)
51
+ end
52
+
53
+ it "should cast floats" do
54
+ subject = TestAttributeCasting.parse 'stake' => '1.5'
55
+ subject.stake.should be_a(Float)
56
+ end
57
+
58
+ it "should cast integers" do
59
+ subject = TestAttributeCasting.parse 'number' => '10'
60
+ subject.number.should be_a(Integer)
61
+ end
62
+
63
+ it "should rename attributes" do
64
+ subject = TestAttributeCasting.parse 'raceIdentifier' => string
65
+ subject.identifier.should eq string
66
+ end
67
+
68
+ it "should create setter method" do
69
+ subject = TestAttributeCasting.parse 'raceIdentifier' => string
70
+ subject.identifier = 'Matamata'
71
+ subject.identifier.should eq 'Matamata'
72
+ end
73
+
74
+ it "should try many attributes" do
75
+ subject = TestAttributeCasting.parse 'fooMeeting' => nil, 'barMeeting' => string
76
+ subject.meeting.should eq string
77
+ end
78
+
79
+ it "should try a collection" do
80
+ subject = TestAttributeCasting.parse 'manyThings' => [{ "name" => string}]
81
+ subject.many_things.first.name.should eq string
82
+ end
83
+
84
+ it "should just return element if already a collection member" do
85
+ subject = TestAttributeCasting.parse 'manyThings' => [TestAttributeThing.new(name: string)]
86
+ subject.many_things.first.name.should eq string
87
+ end
88
+
89
+ it "should memoize instance variables" do
90
+ subject = TestAttributeCasting.parse 'manyThings' => [{ "name" => string}]
91
+ subject.many_things.first.object_id.should eq subject.many_things.first.object_id
92
+ end
93
+
94
+ it "should return an array if collection nil" do
95
+ subject = TestAttributeCasting.parse 'manyThings' => nil
96
+ subject.many_things.should be_a(Array)
97
+ end
98
+
99
+ it "should try a member" do
100
+ subject = TestAttributeCasting.parse 'singleThing' => { "name" => string}
101
+ subject.single_thing.name.should eq string
102
+ end
103
+
104
+ it "should assign something one deep" do
105
+ subject = TestAttributeCasting.parse 'someDetails' => { 'nestedDetail' => string }
106
+ subject.nested_detail.should eq string
107
+ end
108
+
109
+ it "should try other places for the data" do
110
+ subject = TestAttributeCasting.parse 'someDetails' => { 'raceStatus' => string }
111
+ subject.status.should eq string
112
+
113
+ subject = TestAttributeCasting.parse 'raceStatus' => string
114
+ subject.status.should eq string
115
+
116
+ subject = TestAttributeCasting.parse 'status' => string
117
+ subject.status.should eq string
118
+ end
119
+
120
+ it "should return the aliased value if present" do
121
+ subject = TestAttributeCasting.parse "bar_name" => string
122
+ subject.bar_name.should eq string
123
+ end
124
+
125
+ it "should call the after parse method" do
126
+ subject = TestAttributeCasting.parse "afterParseValue" => string
127
+ subject.after_parse_value.should eq "after parse!"
128
+ end
129
+
130
+ it "should add a callback from the options hash" do
131
+ subject = TestAttributeCasting.parse "afterOptions" => string
132
+ subject.after_options.should eq "#{string} after parse!"
133
+ end
134
+
135
+ it "should clear memoized data when parsed is called" do
136
+ subject = TestAttributeCasting.new
137
+
138
+ subject.name.should be_nil
139
+
140
+ subject = TestAttributeCasting.parse 'name' => string
141
+ subject.name.should eq string
142
+ end
143
+
144
+ it "should have instance method parse methods" do
145
+ subject = TestAttributeCasting.new
146
+
147
+ subject.parse 'name' => 'foo'
148
+ subject.name.should eq 'foo'
149
+
150
+ subject.merge_attributes 'name' => 'bar'
151
+ subject.name.should eq 'bar'
152
+ end
153
+
154
+ it "should return a reliable cache key" do
155
+ subject = TestAttributeThing.parse 'name' => 'foo'
156
+ subject.cache_key.should eq "c9e2bd1b9e2ee9b862a8f035e4ec9d57"
157
+ end
158
+
159
+ it "should return the original raw attributes hash as a cache key" do
160
+ subject_one = TestAttributeThing.parse 'name' => 'foo'
161
+ subject_two = TestAttributeThing.parse 'name' => 'foo'
162
+ subject_one.cache_key.should eq subject_two.cache_key
163
+ end
164
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'random_attributes'
5
+
6
+ RSpec.configure do |config|
7
+ config.order = 'random'
8
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: random_attributes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Rufus Post
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2013-12-16 00:00:00 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: active_support
16
+ prerelease: false
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: "3.0"
22
+ type: :runtime
23
+ version_requirements: *id001
24
+ - !ruby/object:Gem::Dependency
25
+ name: bundler
26
+ prerelease: false
27
+ requirement: &id002 !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ~>
30
+ - !ruby/object:Gem::Version
31
+ version: "1.3"
32
+ type: :development
33
+ version_requirements: *id002
34
+ - !ruby/object:Gem::Dependency
35
+ name: rake
36
+ prerelease: false
37
+ requirement: &id003 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - &id005
40
+ - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ type: :development
44
+ version_requirements: *id003
45
+ - !ruby/object:Gem::Dependency
46
+ name: rspec
47
+ prerelease: false
48
+ requirement: &id004 !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ~>
51
+ - !ruby/object:Gem::Version
52
+ version: "2.14"
53
+ type: :development
54
+ version_requirements: *id004
55
+ - !ruby/object:Gem::Dependency
56
+ name: ffaker
57
+ prerelease: false
58
+ requirement: &id006 !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - *id005
61
+ type: :development
62
+ version_requirements: *id006
63
+ description: When someone gives you rubbish data an you want to map it to something else.
64
+ email:
65
+ - rufuspost@gmail.com
66
+ executables: []
67
+
68
+ extensions: []
69
+
70
+ extra_rdoc_files: []
71
+
72
+ files:
73
+ - .gitignore
74
+ - .rspec
75
+ - Gemfile
76
+ - LICENSE.txt
77
+ - README.md
78
+ - Rakefile
79
+ - lib/random_attributes.rb
80
+ - lib/random_attributes/version.rb
81
+ - random_attributes.gemspec
82
+ - spec/random_attributes_spec.rb
83
+ - spec/spec_helper.rb
84
+ homepage: ""
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+
89
+ post_install_message:
90
+ rdoc_options: []
91
+
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - *id005
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - *id005
100
+ requirements: []
101
+
102
+ rubyforge_project:
103
+ rubygems_version: 2.0.3
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Data hash to object mapper
107
+ test_files:
108
+ - spec/random_attributes_spec.rb
109
+ - spec/spec_helper.rb