mappable_object_attributes 0.1.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 +15 -0
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +103 -0
- data/LICENSE.txt +20 -0
- data/README.md +6 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/lib/mappable_object_attributes.rb +9 -0
- data/lib/mappable_object_attributes/data_attributes_map.rb +85 -0
- data/lib/mappable_object_attributes/mappable_data.rb +132 -0
- data/spec/integration/with_active_record_spec.rb +53 -0
- data/spec/mappable_object_attributes_spec.rb +8 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/spec_helper_with_ar.rb +39 -0
- data/spec/unit/data_attributes_map_spec.rb +66 -0
- data/spec/unit/deprecated_spec.rb +44 -0
- data/spec/unit/mappable_object_spec.rb +31 -0
- metadata +218 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
M2Y3MDk5MjRiNmFlMjdmZWEwZmQ5NDVlM2VmMWU3YTcxODUzYjFiYg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
N2MwYjAyZDhjNDc4Zjc5MTIwNzIwZjIzNGEzZGJmYzAyMGM2YjQzYg==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ODE4YTRjNjllOTVkNDM3MGY1NzlmY2M0ZDdlYjAyMTYyYjFlNzJmNzJjMzRh
|
10
|
+
ZThkY2UwMzc3NzYzNzRiMTA5YTVjM2YwOWZmMTU2NjJhZDljMmNhYzM2NTIw
|
11
|
+
NjUxZGUyNGQ0MzM2MTk1M2ZmOGQyMGQ5ZjM5MGM1NWFiOWMzY2I=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NGM5YjRiOTFkZjM1YzZkZjZmM2VhZWM4NWU0ZjM5NGU0OGI1Y2QyMDYzZjUw
|
14
|
+
OTE0MWRmNzhkMGIzMjcwMWZjNGNjNmRiYmM4M2FiNjA3YzZjYzlmNGE5NTQ1
|
15
|
+
MTI0ZmNkMzJhZjQ4MmI0ZjA4ODNkMGVmZDgxN2VlNmNkNDQ5NWM=
|
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
group :development, :test do
|
4
|
+
gem "rspec", "~> 2.14.0"
|
5
|
+
gem "bundler"
|
6
|
+
gem "jeweler", "~> 1.8.4"
|
7
|
+
gem 'database_cleaner', "1.0.1"
|
8
|
+
gem "pry"
|
9
|
+
gem "rdoc", "~> 3.12"
|
10
|
+
|
11
|
+
gem 'activesupport', ">= 3.2.14"
|
12
|
+
gem 'activerecord', ">= 3.2.14"
|
13
|
+
gem 'protected_attributes'
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
gem 'hashie'
|
18
|
+
gem 'sqlite3'
|
19
|
+
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activemodel (4.0.0)
|
5
|
+
activesupport (= 4.0.0)
|
6
|
+
builder (~> 3.1.0)
|
7
|
+
activerecord (4.0.0)
|
8
|
+
activemodel (= 4.0.0)
|
9
|
+
activerecord-deprecated_finders (~> 1.0.2)
|
10
|
+
activesupport (= 4.0.0)
|
11
|
+
arel (~> 4.0.0)
|
12
|
+
activerecord-deprecated_finders (1.0.3)
|
13
|
+
activesupport (4.0.0)
|
14
|
+
i18n (~> 0.6, >= 0.6.4)
|
15
|
+
minitest (~> 4.2)
|
16
|
+
multi_json (~> 1.3)
|
17
|
+
thread_safe (~> 0.1)
|
18
|
+
tzinfo (~> 0.3.37)
|
19
|
+
addressable (2.3.5)
|
20
|
+
arel (4.0.0)
|
21
|
+
atomic (1.1.12)
|
22
|
+
builder (3.1.4)
|
23
|
+
coderay (1.0.9)
|
24
|
+
database_cleaner (1.0.1)
|
25
|
+
diff-lcs (1.2.4)
|
26
|
+
faraday (0.8.8)
|
27
|
+
multipart-post (~> 1.2.0)
|
28
|
+
git (1.2.5)
|
29
|
+
github_api (0.10.1)
|
30
|
+
addressable
|
31
|
+
faraday (~> 0.8.1)
|
32
|
+
hashie (>= 1.2)
|
33
|
+
multi_json (~> 1.4)
|
34
|
+
nokogiri (~> 1.5.2)
|
35
|
+
oauth2
|
36
|
+
hashie (2.0.5)
|
37
|
+
highline (1.6.19)
|
38
|
+
httpauth (0.2.0)
|
39
|
+
i18n (0.6.4)
|
40
|
+
jeweler (1.8.6)
|
41
|
+
builder
|
42
|
+
bundler (~> 1.0)
|
43
|
+
git (>= 1.2.5)
|
44
|
+
github_api (= 0.10.1)
|
45
|
+
highline (>= 1.6.15)
|
46
|
+
nokogiri (= 1.5.10)
|
47
|
+
rake
|
48
|
+
rdoc
|
49
|
+
json (1.8.0)
|
50
|
+
jwt (0.1.8)
|
51
|
+
multi_json (>= 1.5)
|
52
|
+
method_source (0.8.2)
|
53
|
+
minitest (4.7.5)
|
54
|
+
multi_json (1.7.9)
|
55
|
+
multi_xml (0.5.5)
|
56
|
+
multipart-post (1.2.0)
|
57
|
+
nokogiri (1.5.10)
|
58
|
+
oauth2 (0.9.2)
|
59
|
+
faraday (~> 0.8)
|
60
|
+
httpauth (~> 0.2)
|
61
|
+
jwt (~> 0.1.4)
|
62
|
+
multi_json (~> 1.0)
|
63
|
+
multi_xml (~> 0.5)
|
64
|
+
rack (~> 1.2)
|
65
|
+
protected_attributes (1.0.3)
|
66
|
+
activemodel (>= 4.0.0, < 5.0)
|
67
|
+
pry (0.9.12.2)
|
68
|
+
coderay (~> 1.0.5)
|
69
|
+
method_source (~> 0.8)
|
70
|
+
slop (~> 3.4)
|
71
|
+
rack (1.5.2)
|
72
|
+
rake (10.1.0)
|
73
|
+
rdoc (3.12.2)
|
74
|
+
json (~> 1.4)
|
75
|
+
rspec (2.14.1)
|
76
|
+
rspec-core (~> 2.14.0)
|
77
|
+
rspec-expectations (~> 2.14.0)
|
78
|
+
rspec-mocks (~> 2.14.0)
|
79
|
+
rspec-core (2.14.4)
|
80
|
+
rspec-expectations (2.14.1)
|
81
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
82
|
+
rspec-mocks (2.14.3)
|
83
|
+
slop (3.4.6)
|
84
|
+
sqlite3 (1.3.7)
|
85
|
+
thread_safe (0.1.2)
|
86
|
+
atomic
|
87
|
+
tzinfo (0.3.37)
|
88
|
+
|
89
|
+
PLATFORMS
|
90
|
+
ruby
|
91
|
+
|
92
|
+
DEPENDENCIES
|
93
|
+
activerecord (>= 3.2.14)
|
94
|
+
activesupport (>= 3.2.14)
|
95
|
+
bundler
|
96
|
+
database_cleaner (= 1.0.1)
|
97
|
+
hashie
|
98
|
+
jeweler (~> 1.8.4)
|
99
|
+
protected_attributes
|
100
|
+
pry
|
101
|
+
rdoc (~> 3.12)
|
102
|
+
rspec (~> 2.14.0)
|
103
|
+
sqlite3
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2013 Dan Nguyen
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "mappable_object_attributes"
|
18
|
+
gem.homepage = "http://github.com/dannguyen/mappable_object_attributes"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{A convenience wrapper to help with defining how a record is created}
|
21
|
+
gem.description = %Q{Using the power of Hashie::Mash to define how a record consumes external data into defined records.}
|
22
|
+
gem.email = "dansonguyen@gmail.com"
|
23
|
+
gem.authors = ["Dan Nguyen"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rspec/core'
|
29
|
+
require 'rspec/core/rake_task'
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
spec.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
require 'rdoc/task'
|
42
|
+
Rake::RDocTask.new do |rdoc|
|
43
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
44
|
+
|
45
|
+
rdoc.rdoc_dir = 'rdoc'
|
46
|
+
rdoc.title = "mappable_object_attributes #{version}"
|
47
|
+
rdoc.rdoc_files.include('README*')
|
48
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
49
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
|
3
|
+
module MappableObjectAttributes
|
4
|
+
class DataAttributesMap < BasicObject
|
5
|
+
include ::Kernel
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@mash = ::Hashie::Mash.new
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def map_keys
|
13
|
+
@mash.keys
|
14
|
+
end
|
15
|
+
|
16
|
+
# send all setter methods directly to set_map_att_foo
|
17
|
+
def method_missing(method_name, *arguments, &block)
|
18
|
+
# if it's all word characters and a :setter,
|
19
|
+
# then pass to the mash as a data attribute
|
20
|
+
if method_name.to_s =~ /(\w+)=/
|
21
|
+
set_map_att_foo($1, *arguments)
|
22
|
+
elsif @mash.respond_to?(method_name)
|
23
|
+
@mash.send(method_name, *arguments, &block)
|
24
|
+
else
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
### TO BE deprecated
|
31
|
+
### included these methods because I used them in older projects
|
32
|
+
### and want to make sure this gem is compatible with those older projects
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
def map_simple_atts(*args)
|
37
|
+
args.each{|k| set_map_att_foo(k, k) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def map_nested_att(att_name, nodename)
|
41
|
+
path_arr = Array(nodename)
|
42
|
+
find_nested_node_foo = ->(msh){
|
43
|
+
val = path_arr.inject(msh) do |target_node, att|
|
44
|
+
break if target_node.nil?
|
45
|
+
target_node.fetch(att, nil)
|
46
|
+
end
|
47
|
+
val
|
48
|
+
}
|
49
|
+
|
50
|
+
set_map_att_foo(att_name, find_nested_node_foo)
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
### /deprecated stuff
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
private
|
62
|
+
# also, all atts are now symbols
|
63
|
+
def set_map_att_foo(att, val)
|
64
|
+
# processed_lambda_val is returned at the end and will consist of a lambda
|
65
|
+
|
66
|
+
processed_lambda_val = case
|
67
|
+
when val.blank?
|
68
|
+
# model.somekey = msh[somekey]
|
69
|
+
->(msh){ msh[att] }
|
70
|
+
when val.is_a?(::String) || val.is_a?(::Symbol)
|
71
|
+
# model.somekey = msh[somevalue]
|
72
|
+
->(msh){ msh[val] }
|
73
|
+
when val.is_a?(::Proc) && val.arity == 1 # there should be exactly one argument to the Proc
|
74
|
+
# model.somekey = foo(msh)
|
75
|
+
val
|
76
|
+
else
|
77
|
+
raise ::ArgumentError, "The value mapped to :#{att} must be either a String, Symbol, or Proc with arity 1. But #{val} is a #{val.class}"
|
78
|
+
end
|
79
|
+
|
80
|
+
@mash.store(att.to_sym, processed_lambda_val)
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'active_support/core_ext'
|
2
|
+
module MappableObjectAttributes;
|
3
|
+
module MappableData
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
class_attribute :data_maps
|
8
|
+
self.data_maps ||= Hashie::Mash.new
|
9
|
+
|
10
|
+
class_attribute :is_activerecord
|
11
|
+
self.is_activerecord = self.instance_methods.include?(:attr_accessible)
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def define_attributes_map(mapname=:default, &block)
|
17
|
+
data_map = self.init_map_named(mapname)
|
18
|
+
# let the model-designer define the mash here
|
19
|
+
yield data_map
|
20
|
+
|
21
|
+
# now make accessible if ActiveRecord
|
22
|
+
if self.is_activerecord
|
23
|
+
data_map.keys.each do |mkey|
|
24
|
+
attr_accessible mkey
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
return data_map
|
29
|
+
end
|
30
|
+
|
31
|
+
def default_data_map
|
32
|
+
data_maps[:default]
|
33
|
+
end
|
34
|
+
|
35
|
+
def mapped_attribute_keys(mapname=:default)
|
36
|
+
data_maps.fetch(mapname).map_keys
|
37
|
+
end
|
38
|
+
|
39
|
+
def fetch_map_named(mapname)
|
40
|
+
data_maps.fetch(mapname)
|
41
|
+
end
|
42
|
+
|
43
|
+
def init_map_named(mapname)
|
44
|
+
data_maps[mapname] ||= DataAttributesMap.new
|
45
|
+
end
|
46
|
+
|
47
|
+
# This is called by an importing function, with the expectation
|
48
|
+
# that @@data_attributes_map has been defined
|
49
|
+
#
|
50
|
+
# Returns a Hashie::Mash that assign_attributes/update_attributes
|
51
|
+
# can be called from
|
52
|
+
def make_hash_from(hash_object, mapname=:default)
|
53
|
+
data_mash = Hashie::Mash.new(hash_object)
|
54
|
+
built_mash = Hashie::Mash.new
|
55
|
+
|
56
|
+
# build from the specified data_attributes_map
|
57
|
+
specific_data_map = self.fetch_map_named(mapname)
|
58
|
+
specific_data_map.each_pair do |key, proc|
|
59
|
+
built_mash[key] = proc.call(data_mash)
|
60
|
+
end
|
61
|
+
|
62
|
+
return built_mash
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# ActiveRecord specific
|
67
|
+
def build_from_map(hash_object, mapname=:default)
|
68
|
+
instance = self.new
|
69
|
+
instance.assign_attributes_from_hash(hash_object, mapname)
|
70
|
+
|
71
|
+
return instance
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_from_map(hash_object, mapname=:default)
|
75
|
+
instance = build_from_map(hash_object, mapname)
|
76
|
+
instance.save
|
77
|
+
|
78
|
+
return instance
|
79
|
+
end
|
80
|
+
|
81
|
+
# pre: Has access to ActiveController
|
82
|
+
def make_mapped_atts_accessible(data_hsh)
|
83
|
+
# params = ActionController::Parameters.new(data_hsh)
|
84
|
+
# permitted_params = params.permit!
|
85
|
+
|
86
|
+
# return permitted_params
|
87
|
+
|
88
|
+
data_hsh
|
89
|
+
end
|
90
|
+
|
91
|
+
end # END OF Class Methods
|
92
|
+
|
93
|
+
|
94
|
+
###################### instance methods
|
95
|
+
|
96
|
+
# usage: convenience method that calls:
|
97
|
+
# - make_hash_from
|
98
|
+
# - makes attributes accessible
|
99
|
+
# - assign_attributes
|
100
|
+
# part of #build_from_map
|
101
|
+
def assign_attributes_from_hash(hash_object, mapname=:default)
|
102
|
+
msh = self.class.make_hash_from(hash_object, mapname)
|
103
|
+
accessible_msh = self.class.make_mapped_atts_accessible(msh)
|
104
|
+
|
105
|
+
self.assign_attributes(accessible_msh)
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
=begin # deprecated non AR stuff
|
120
|
+
old def build_from_map(hash_object, mapname=:default)
|
121
|
+
|
122
|
+
hsh = make_hash_from(hash_object, mapname)
|
123
|
+
obj = self.new
|
124
|
+
hsh.each_pair do |k,v|
|
125
|
+
obj.send("#{k}=".to_sym, v)
|
126
|
+
end
|
127
|
+
|
128
|
+
return obj
|
129
|
+
end
|
130
|
+
|
131
|
+
=end
|
132
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper_with_ar'
|
2
|
+
|
3
|
+
describe "Interaction with ActiveRecord" do
|
4
|
+
|
5
|
+
class AliceMap < ActiveRecord::Base
|
6
|
+
include MappableData
|
7
|
+
|
8
|
+
define_attributes_map do |alice|
|
9
|
+
alice.name = :name
|
10
|
+
alice.hed = :headline
|
11
|
+
alice.birth_year = ->(data){DateTime.parse(data.birthday).year}
|
12
|
+
end
|
13
|
+
|
14
|
+
define_attributes_map(:secondary) do |alice|
|
15
|
+
alice.name = :name
|
16
|
+
alice.hed = :hed
|
17
|
+
alice.birth_year = ->(data){DateTime.parse(data.birthday).year}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#build_from_map' do
|
22
|
+
before(:each) do
|
23
|
+
@data_obj = {'name' => 'Al',
|
24
|
+
'headline' => "A Head",
|
25
|
+
'hed' => 'Other Hed',
|
26
|
+
'birthday' => "1999-01-12"}
|
27
|
+
@alice = AliceMap.build_from_map(@data_obj)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should be a new record' do
|
31
|
+
expect(@alice.new_record?).to be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should have mapped attributes' do
|
35
|
+
expect(@alice.name).to eq 'Al'
|
36
|
+
expect(@alice.hed).to eq 'A Head'
|
37
|
+
expect(@alice.birth_year).to eq 1999
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should accept second argument to build from a specified map' do
|
41
|
+
@alice2 = AliceMap.build_from_map @data_obj, :secondary
|
42
|
+
expect(@alice2.hed).to eq 'Other Hed'
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#create_from_map' do
|
46
|
+
it 'should create record similar to #build_from_map' do
|
47
|
+
@alice = AliceMap.create_from_map(@data_obj)
|
48
|
+
expect(@alice.new_record?).not_to be_true
|
49
|
+
expect(@alice.hed).to eq 'A Head'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'mappable_object_attributes'
|
5
|
+
require 'pry'
|
6
|
+
|
7
|
+
include MappableObjectAttributes
|
8
|
+
|
9
|
+
# Requires supporting files with custom matchers and macros, etc,
|
10
|
+
# in ./support/ and its subdirectories.
|
11
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
# Use color in STDOUT
|
17
|
+
config.color_enabled = true
|
18
|
+
|
19
|
+
# Use color not only in STDOUT but also in pagers and files
|
20
|
+
config.tty = true
|
21
|
+
|
22
|
+
# Use the specified formatter
|
23
|
+
config.formatter = :documentation # :progress, :html, :textmate
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'active_record'
|
4
|
+
require 'protected_attributes'
|
5
|
+
require 'database_cleaner'
|
6
|
+
require 'sqlite3'
|
7
|
+
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.before(:each) do
|
11
|
+
DatabaseCleaner.start
|
12
|
+
end
|
13
|
+
|
14
|
+
config.after(:each) do
|
15
|
+
DatabaseCleaner.clean
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
ActiveRecord::Base.establish_connection(
|
23
|
+
:adapter => "sqlite3",
|
24
|
+
:database => ":memory:"
|
25
|
+
)
|
26
|
+
ActiveRecord::Migration.verbose = false
|
27
|
+
|
28
|
+
ActiveRecord::Schema.define do
|
29
|
+
create_table :alice_maps do |t|
|
30
|
+
t.string :name
|
31
|
+
t.string :hed
|
32
|
+
t.integer :birth_year
|
33
|
+
t.timestamps
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
DatabaseCleaner.clean_with(:truncation)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
describe 'DataAttributesMap' do
|
6
|
+
|
7
|
+
context 'end result of #set_map_att_foo' do
|
8
|
+
class BobMap
|
9
|
+
include MappableData
|
10
|
+
|
11
|
+
define_attributes_map do |bob|
|
12
|
+
bob.name = :name
|
13
|
+
bob.hed = :headline
|
14
|
+
bob.birth_year = ->(data){DateTime.parse(data.birthday).year}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
before(:each) do
|
19
|
+
@data_obj = {'name' => 'Bob',
|
20
|
+
'headline' => "A headline",
|
21
|
+
'hed' => 'Should be ignored',
|
22
|
+
'birthday' => "1985-01-12"}
|
23
|
+
@hash = BobMap.make_hash_from(@data_obj)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'all mapped values should be Procs' do
|
27
|
+
expect( BobMap.default_data_map.values.all?{|p| p.is_a?(Proc)} ).to be true
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'value is blank' do
|
31
|
+
it 'should extract :key from data_obj' do
|
32
|
+
expect(@hash.name).to eq 'Bob'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'value is a String or symbol' do
|
37
|
+
it 'should extract :value (as a key) from data_obj' do
|
38
|
+
expect(@hash.hed).to eq 'A headline'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'value is a Proc' do
|
43
|
+
it 'should execute Proc upon the data object' do
|
44
|
+
expect(@hash.birth_year).to eq 1985
|
45
|
+
end
|
46
|
+
it 'should raise ArgumentError if arity is != 1' do
|
47
|
+
expect{ BobMap.define_attributes_map do |b|
|
48
|
+
b.faulty = ->(data, badarg){'hey'}
|
49
|
+
end
|
50
|
+
}.to raise_error ArgumentError
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'value is something else' do
|
55
|
+
it 'should raise an ArgumentError' do
|
56
|
+
expect{ BobMap.define_attributes_map do |b|
|
57
|
+
b.faulty = {no: 'good'}
|
58
|
+
end
|
59
|
+
}.to raise_error ArgumentError
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
## legacy methods to be changed or deprecated
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
|
6
|
+
class SomePerson
|
7
|
+
include MappableData
|
8
|
+
|
9
|
+
define_attributes_map do |person|
|
10
|
+
person.map_simple_atts :name, :age, :category
|
11
|
+
person.map_nested_att :zipcode, [:address, :zip]
|
12
|
+
person.map_nested_att :street_name, [:address, :street, :name]
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'deprecated convenience methods' do
|
19
|
+
|
20
|
+
before(:each) do
|
21
|
+
@data_obj = {name: 'Charlie', age: 12, category: 'Runner',
|
22
|
+
address: {zip: 90210, street: {name: 'Broadway', number: 100}}
|
23
|
+
}
|
24
|
+
|
25
|
+
@person_hash = SomePerson.make_hash_from(@data_obj)
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
context '#map_simple_atts' do
|
30
|
+
it 'should map simple attributes' do
|
31
|
+
expect(@person_hash.name).to eq 'Charlie'
|
32
|
+
expect(@person_hash.age).to eq 12
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context '#map_nested_att' do
|
37
|
+
it 'should map nested attributes' do
|
38
|
+
expect(@person_hash.zipcode).to eq 90210
|
39
|
+
expect(@person_hash.street_name).to eq 'Broadway'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
class MappedObj
|
5
|
+
include MappableData
|
6
|
+
|
7
|
+
define_attributes_map do |o|
|
8
|
+
o.name = :name
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'MappableData' do
|
14
|
+
|
15
|
+
it 'should have @@data_maps' do
|
16
|
+
expect(MappedObj.data_maps).to be_a Hashie::Mash
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
describe '#define_attributes_map' do
|
21
|
+
it 'should define :default map by default' do
|
22
|
+
expect(MappedObj.mapped_attribute_keys(:default) ).to eq [:name]
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should have named @@data_attributes_map[:hello]' do
|
26
|
+
MappedObj.define_attributes_map(:hello){|o| }
|
27
|
+
expect(MappedObj.fetch_map_named(:hello)).to be_a DataAttributesMap
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,218 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mappable_object_attributes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dan Nguyen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: hashie
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
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: 2.14.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.14.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
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: jeweler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.8.4
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.8.4
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: database_cleaner
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.0.1
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.0.1
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rdoc
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.12'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ~>
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.12'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: activesupport
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 3.2.14
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ! '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 3.2.14
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: activerecord
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 3.2.14
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ! '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 3.2.14
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: protected_attributes
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ! '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ! '>='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
description: Using the power of Hashie::Mash to define how a record consumes external
|
168
|
+
data into defined records.
|
169
|
+
email: dansonguyen@gmail.com
|
170
|
+
executables: []
|
171
|
+
extensions: []
|
172
|
+
extra_rdoc_files:
|
173
|
+
- LICENSE.txt
|
174
|
+
- README.md
|
175
|
+
files:
|
176
|
+
- .document
|
177
|
+
- .rspec
|
178
|
+
- Gemfile
|
179
|
+
- Gemfile.lock
|
180
|
+
- LICENSE.txt
|
181
|
+
- README.md
|
182
|
+
- Rakefile
|
183
|
+
- VERSION
|
184
|
+
- lib/mappable_object_attributes.rb
|
185
|
+
- lib/mappable_object_attributes/data_attributes_map.rb
|
186
|
+
- lib/mappable_object_attributes/mappable_data.rb
|
187
|
+
- spec/integration/with_active_record_spec.rb
|
188
|
+
- spec/mappable_object_attributes_spec.rb
|
189
|
+
- spec/spec_helper.rb
|
190
|
+
- spec/spec_helper_with_ar.rb
|
191
|
+
- spec/unit/data_attributes_map_spec.rb
|
192
|
+
- spec/unit/deprecated_spec.rb
|
193
|
+
- spec/unit/mappable_object_spec.rb
|
194
|
+
homepage: http://github.com/dannguyen/mappable_object_attributes
|
195
|
+
licenses:
|
196
|
+
- MIT
|
197
|
+
metadata: {}
|
198
|
+
post_install_message:
|
199
|
+
rdoc_options: []
|
200
|
+
require_paths:
|
201
|
+
- lib
|
202
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
203
|
+
requirements:
|
204
|
+
- - ! '>='
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: '0'
|
207
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
208
|
+
requirements:
|
209
|
+
- - ! '>='
|
210
|
+
- !ruby/object:Gem::Version
|
211
|
+
version: '0'
|
212
|
+
requirements: []
|
213
|
+
rubyforge_project:
|
214
|
+
rubygems_version: 2.0.5
|
215
|
+
signing_key:
|
216
|
+
specification_version: 4
|
217
|
+
summary: A convenience wrapper to help with defining how a record is created
|
218
|
+
test_files: []
|