mappy 0.0.1.pre → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/jeremyf/mappy.png?branch=master)](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
|