mappy 0.0.1.pre → 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 +4 -4
- data/.travis.yml +8 -0
- data/README.md +3 -2
- data/lib/mappy.rb +42 -1
- data/lib/mappy/configuration.rb +32 -0
- data/lib/mappy/resolver.rb +30 -0
- data/lib/mappy/version.rb +1 -1
- data/mappy.gemspec +2 -0
- data/spec/lib/mappy/configuration_spec.rb +29 -0
- data/spec/lib/mappy/resolver_spec.rb +24 -0
- data/spec/lib/mappy_spec.rb +40 -0
- metadata +42 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf1c7c828053b75ccd40b4727fc0ab95b85536a1
|
4
|
+
data.tar.gz: 1de27fffeb496e08ffd418d8e79843196f9c613e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0ecee7474691679b643c5102089575adef6be95aaca636f8b7f42ca66b8248f77f6fe3a41360e48ead89ec3bf38c8c03f9166860dd7ed1ede77db506c27354c
|
7
|
+
data.tar.gz: ef4708b9d7922b4211b7322af5f7bf8e936b78f0a92c80025a69cc05ea07cfd203608bf81e7b7eec832290cb89a7d309d0d4d684d2e86e45a9db205866106829
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
# Mappy
|
1
|
+
# Mappy [](https://travis-ci.org/jeremyf/mappy)
|
2
2
|
|
3
|
-
Map one object to another
|
3
|
+
Map one object to another. Apsiring to be a DSL for mapping one object's "data
|
4
|
+
structure" onto another object's "data structure".
|
4
5
|
|
5
6
|
## Installation
|
6
7
|
|
data/lib/mappy.rb
CHANGED
@@ -1,5 +1,46 @@
|
|
1
1
|
require "mappy/version"
|
2
|
+
require "mappy/configuration"
|
2
3
|
|
3
4
|
module Mappy
|
4
|
-
|
5
|
+
class << self
|
6
|
+
attr_accessor :configuration
|
7
|
+
end
|
8
|
+
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def to_type(object)
|
12
|
+
return object.to_mappy_type if object.respond_to?(:to_mappy_type)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Used for configuring available RemoteService and any additional
|
16
|
+
# initialization requirements for those RemoteServices (i.e. credentials)
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
#
|
20
|
+
# @yieldparam config [Configuration]
|
21
|
+
# @see Mappy::Railtie
|
22
|
+
def configure(&block)
|
23
|
+
@configuration_block = block
|
24
|
+
|
25
|
+
# The Rails load sequence means that some of the configured Targets may
|
26
|
+
# not be loaded; As such I am not calling configure! instead relying on
|
27
|
+
# Mappy::Railtie to handle the configure! call
|
28
|
+
configure! unless defined?(Rails)
|
29
|
+
end
|
30
|
+
|
31
|
+
def map(source, options = {})
|
32
|
+
configuration.map(source, options)
|
33
|
+
end
|
34
|
+
|
35
|
+
def configure!
|
36
|
+
if @configuration_block.respond_to?(:call)
|
37
|
+
self.configuration ||= Configuration.new
|
38
|
+
@configuration_block.call(configuration)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def reset!
|
43
|
+
self.configuration = Configuration.new
|
44
|
+
end
|
45
|
+
|
5
46
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Mappy
|
2
|
+
|
3
|
+
class Configuration
|
4
|
+
attr_reader :map_store
|
5
|
+
def initialize(config = {})
|
6
|
+
@map_store = config.fetch(:map_store) { {} }
|
7
|
+
end
|
8
|
+
|
9
|
+
def legend(options = {})
|
10
|
+
source = options.fetch(:source)
|
11
|
+
target = options.fetch(:target)
|
12
|
+
legend = options.fetch(:legend)
|
13
|
+
|
14
|
+
map_store[target] ||= {}
|
15
|
+
map_store[target][source] = legend
|
16
|
+
end
|
17
|
+
|
18
|
+
def map(source_instance, options = {})
|
19
|
+
source = source_instance.to_mappy_type
|
20
|
+
target = options.fetch(:target)
|
21
|
+
legend = map_store.fetch(target).fetch(source)
|
22
|
+
|
23
|
+
# @Todo: The returned value should not be an OpenStruct, but should
|
24
|
+
# be an instance of the target (as per some Mappy resolver).
|
25
|
+
Resolver.new(
|
26
|
+
target_builder: OpenStruct.method(:new),
|
27
|
+
legend: legend
|
28
|
+
).call(source_instance)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Mappy
|
2
|
+
# Responsible for mapping, via a legend, a source object to an instance of the
|
3
|
+
# target.
|
4
|
+
class Resolver
|
5
|
+
attr_reader :target_builder, :legend
|
6
|
+
def initialize(options = {})
|
7
|
+
@target_builder = options.fetch(:target_builder)
|
8
|
+
@legend = options.fetch(:legend)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(source)
|
12
|
+
attributes = {}
|
13
|
+
legend.each_with_object(attributes) do |(source_method, target_attribute), m|
|
14
|
+
m[target_attribute] = extract_attribute_for(source, source_method)
|
15
|
+
m
|
16
|
+
end
|
17
|
+
target_builder.call(attributes)
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def extract_attribute_for(source, method_name_or_proc)
|
23
|
+
if method_name_or_proc.respond_to?(:call)
|
24
|
+
method_name_or_proc.call(source)
|
25
|
+
elsif method_name_or_proc.is_a?(::Symbol) || method_name_or_proc.is_a?(::String)
|
26
|
+
source.send(method_name_or_proc)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/mappy/version.rb
CHANGED
data/mappy.gemspec
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path('../../../../lib/mappy/configuration', __FILE__)
|
2
|
+
|
3
|
+
module Mappy
|
4
|
+
describe Configuration do
|
5
|
+
let(:map_store) { {} }
|
6
|
+
let(:legend) { [[:title, :title]] }
|
7
|
+
|
8
|
+
subject { described_class.new(map_store: map_store) }
|
9
|
+
|
10
|
+
context '#legend' do
|
11
|
+
it 'should yield a map storage' do
|
12
|
+
subject.legend(source: :article, target: :document, legend: legend)
|
13
|
+
expect(map_store.fetch(:document).fetch(:article)).to eq(legend)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context '#map' do
|
18
|
+
let(:source_type) {:article}
|
19
|
+
let(:article) { double('Article', title: 'Hello', to_mappy_type: source_type) }
|
20
|
+
before(:each) do
|
21
|
+
subject.legend(source: source_type, target: :document, legend: legend)
|
22
|
+
end
|
23
|
+
it 'should yield a map storage' do
|
24
|
+
document = subject.map(article, target: :document)
|
25
|
+
expect(document.title).to eq(article.title)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path('../../../../lib/mappy/resolver', __FILE__)
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module Mappy
|
5
|
+
describe Resolver do
|
6
|
+
let(:source_publisher) { lambda {|source| source.publishers.join("; ")}}
|
7
|
+
let(:source) { double('Source', title: 'A Title', publishers: ["John", "Ringo"]) }
|
8
|
+
let(:target_builder) { lambda {|attrs| OpenStruct.new(attrs) } }
|
9
|
+
let(:legend) {
|
10
|
+
[
|
11
|
+
[:title, :title],
|
12
|
+
[source_publisher, :publisher]
|
13
|
+
]
|
14
|
+
}
|
15
|
+
|
16
|
+
context '#call' do
|
17
|
+
let(:resolved_publisher) { source_publisher.call(source) }
|
18
|
+
subject { described_class.new(target_builder: target_builder, legend: legend).call(source) }
|
19
|
+
|
20
|
+
its(:publisher) { should eq resolved_publisher }
|
21
|
+
its(:title) { should eq source.title }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path('../../../lib/mappy', __FILE__)
|
2
|
+
|
3
|
+
describe Mappy do
|
4
|
+
context '.to_type' do
|
5
|
+
let(:mappy_type) { 'hello-world' }
|
6
|
+
let(:object) { double(to_mappy_type: mappy_type)}
|
7
|
+
it 'with explicit to mappy type' do
|
8
|
+
expect(Mappy.to_type(object)).to eq(mappy_type)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context '.map' do
|
13
|
+
before(:each) do
|
14
|
+
Mappy.configure do |config|
|
15
|
+
config.legend(
|
16
|
+
source: :journal,
|
17
|
+
target: 'orcid/work',
|
18
|
+
legend: [
|
19
|
+
[:title, :title],
|
20
|
+
[lambda{|*|'long-journal'}, :work_type],
|
21
|
+
]
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
after(:each) do
|
26
|
+
Mappy.reset!
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:title) { 'A Rocking Title' }
|
30
|
+
let(:journal) {
|
31
|
+
double('Journal', to_mappy_type: :journal, title: title)
|
32
|
+
}
|
33
|
+
|
34
|
+
subject { Mappy.map(journal, target: 'orcid/work') }
|
35
|
+
|
36
|
+
its(:work_type) { should eq('long-journal')}
|
37
|
+
its(:title) { should eq(title) }
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mappy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Friesen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,6 +38,34 @@ dependencies:
|
|
38
38
|
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
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: byebug
|
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'
|
41
69
|
description: Map one object to another
|
42
70
|
email:
|
43
71
|
- jeremy.n.friesen@gmail.com
|
@@ -46,13 +74,19 @@ extensions: []
|
|
46
74
|
extra_rdoc_files: []
|
47
75
|
files:
|
48
76
|
- .gitignore
|
77
|
+
- .travis.yml
|
49
78
|
- Gemfile
|
50
79
|
- LICENSE
|
51
80
|
- README.md
|
52
81
|
- Rakefile
|
53
82
|
- lib/mappy.rb
|
83
|
+
- lib/mappy/configuration.rb
|
84
|
+
- lib/mappy/resolver.rb
|
54
85
|
- lib/mappy/version.rb
|
55
86
|
- mappy.gemspec
|
87
|
+
- spec/lib/mappy/configuration_spec.rb
|
88
|
+
- spec/lib/mappy/resolver_spec.rb
|
89
|
+
- spec/lib/mappy_spec.rb
|
56
90
|
homepage: https://github.com/jeremyf/mappy
|
57
91
|
licenses:
|
58
92
|
- APACHE2
|
@@ -68,13 +102,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
68
102
|
version: '0'
|
69
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
104
|
requirements:
|
71
|
-
- - '
|
105
|
+
- - '>='
|
72
106
|
- !ruby/object:Gem::Version
|
73
|
-
version:
|
107
|
+
version: '0'
|
74
108
|
requirements: []
|
75
109
|
rubyforge_project:
|
76
110
|
rubygems_version: 2.0.14
|
77
111
|
signing_key:
|
78
112
|
specification_version: 4
|
79
113
|
summary: Map one object to another
|
80
|
-
test_files:
|
114
|
+
test_files:
|
115
|
+
- spec/lib/mappy/configuration_spec.rb
|
116
|
+
- spec/lib/mappy/resolver_spec.rb
|
117
|
+
- spec/lib/mappy_spec.rb
|