random_attributes 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +181 -0
- data/Rakefile +1 -0
- data/lib/random_attributes/version.rb +3 -0
- data/lib/random_attributes.rb +200 -0
- data/random_attributes.gemspec +27 -0
- data/spec/random_attributes_spec.rb +164 -0
- data/spec/spec_helper.rb +8 -0
- metadata +109 -0
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
data/.rspec
ADDED
data/Gemfile
ADDED
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,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
|
data/spec/spec_helper.rb
ADDED
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
|