mappy 0.0.1 → 0.0.2
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/README.md +15 -0
- data/lib/mappy/configuration.rb +7 -1
- data/lib/mappy/resolver.rb +1 -1
- data/lib/mappy/target_builder_factory.rb +37 -0
- data/lib/mappy/version.rb +1 -1
- data/mappy.gemspec +1 -0
- data/spec/lib/mappy/configuration_spec.rb +8 -2
- data/spec/lib/mappy/resolver_spec.rb +1 -1
- data/spec/lib/mappy/target_builder_factory_spec.rb +27 -0
- data/spec/lib/mappy_spec.rb +4 -6
- data/spec/lib/model_support.rb +14 -0
- metadata +20 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f61f54bcd4b19eae357e8b121765aae2437f0db6
|
4
|
+
data.tar.gz: 690d5a86cae5781ff21024436a42037093918776
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a366fa8161a24d3eec2da41bf226ad55bd83b47b1e32fc2295a18aef024121b110f4c38156711ee9ea4c5c0e42c8ff61b9652280e0c6c7e055b8aa7c071c9f2
|
7
|
+
data.tar.gz: dd9e93aa43fcc49d43d9be06c831783b912537bf63d0c3a1fc321028ef9f6f55c337c4f795f92a4641dbbc74f97654a72ccfcc2bf09b539955d9fc993d2e3f43
|
data/README.md
CHANGED
@@ -3,6 +3,21 @@
|
|
3
3
|
Map one object to another. Apsiring to be a DSL for mapping one object's "data
|
4
4
|
structure" onto another object's "data structure".
|
5
5
|
|
6
|
+
## Why?
|
7
|
+
|
8
|
+
Because I have discovered that I am regularly working with a heterogenious set of
|
9
|
+
objects that need to be handled via some other service. And that service has its
|
10
|
+
expected data structure. And there are quite a few services.
|
11
|
+
|
12
|
+
That is to say, I'm attempting to submit a work to my Orcid Profile. I need some
|
13
|
+
method for defining how to map my home grown "Article" object to the attributes
|
14
|
+
that are needed for an Orcide work. And I don't want to infect my Article class
|
15
|
+
with a #to_orcid_profile_attributes method.
|
16
|
+
|
17
|
+
Or I want to create a DOI for my Article.
|
18
|
+
|
19
|
+
In essence, Mappy provides a configurable seam in an application.
|
20
|
+
|
6
21
|
## Installation
|
7
22
|
|
8
23
|
Add this line to your application's Gemfile:
|
data/lib/mappy/configuration.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require "mappy/resolver"
|
2
|
+
require "mappy/target_builder_factory"
|
3
|
+
|
1
4
|
module Mappy
|
2
5
|
|
3
6
|
class Configuration
|
@@ -18,12 +21,15 @@ module Mappy
|
|
18
21
|
def map(source_instance, options = {})
|
19
22
|
source = source_instance.to_mappy_type
|
20
23
|
target = options.fetch(:target)
|
24
|
+
target_builder_finder = options.fetch(:target_builder_finder) { Mappy::TargetBuilderFactory }
|
21
25
|
legend = map_store.fetch(target).fetch(source)
|
22
26
|
|
27
|
+
target_builder = target_builder_finder.call(target)
|
28
|
+
|
23
29
|
# @Todo: The returned value should not be an OpenStruct, but should
|
24
30
|
# be an instance of the target (as per some Mappy resolver).
|
25
31
|
Resolver.new(
|
26
|
-
target_builder:
|
32
|
+
target_builder: target_builder,
|
27
33
|
legend: legend
|
28
34
|
).call(source_instance)
|
29
35
|
end
|
data/lib/mappy/resolver.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
|
3
|
+
module Mappy
|
4
|
+
class InvalidTargetBuilder < RuntimeError
|
5
|
+
end
|
6
|
+
|
7
|
+
# Responsible for taking a symbol, finding the appropriate class then
|
8
|
+
# verifying that the class is "well formed."
|
9
|
+
class TargetBuilderFactory
|
10
|
+
|
11
|
+
def self.call(*args)
|
12
|
+
new.call(*args)
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(target_symbol)
|
16
|
+
target_builder = extract_target_builder(target_symbol)
|
17
|
+
validate!(target_builder)
|
18
|
+
target_builder
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def extract_target_builder(target_symbol)
|
23
|
+
target_symbol.to_s.classify.constantize
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate!(target_builder)
|
27
|
+
target_instance = target_builder.allocate
|
28
|
+
|
29
|
+
begin
|
30
|
+
target_instance.send(:initialize, {})
|
31
|
+
rescue ArgumentError => e
|
32
|
+
raise InvalidTargetBuilder.new("Expected #{target_builder} to initialize with an attributes hash.\n#{e}")
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/mappy/version.rb
CHANGED
data/mappy.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_dependency 'activesupport'
|
21
22
|
spec.add_development_dependency "bundler", "~> 1.5"
|
22
23
|
spec.add_development_dependency "rake"
|
23
24
|
spec.add_development_dependency "rspec"
|
@@ -17,11 +17,17 @@ module Mappy
|
|
17
17
|
context '#map' do
|
18
18
|
let(:source_type) {:article}
|
19
19
|
let(:article) { double('Article', title: 'Hello', to_mappy_type: source_type) }
|
20
|
+
let(:target_builder) { OpenStruct }
|
21
|
+
let(:target_type) { :document }
|
22
|
+
let(:target_builder_finder) { double("Finder") }
|
23
|
+
|
20
24
|
before(:each) do
|
21
|
-
subject.legend(source: source_type, target:
|
25
|
+
subject.legend(source: source_type, target: target_type, legend: legend)
|
22
26
|
end
|
23
27
|
it 'should yield a map storage' do
|
24
|
-
|
28
|
+
target_builder_finder.should_receive(:call).with(target_type).and_return(target_builder)
|
29
|
+
|
30
|
+
document = subject.map(article, target: target_type, target_builder_finder: target_builder_finder)
|
25
31
|
expect(document.title).to eq(article.title)
|
26
32
|
end
|
27
33
|
end
|
@@ -5,7 +5,7 @@ module Mappy
|
|
5
5
|
describe Resolver do
|
6
6
|
let(:source_publisher) { lambda {|source| source.publishers.join("; ")}}
|
7
7
|
let(:source) { double('Source', title: 'A Title', publishers: ["John", "Ringo"]) }
|
8
|
-
let(:target_builder) {
|
8
|
+
let(:target_builder) { OpenStruct }
|
9
9
|
let(:legend) {
|
10
10
|
[
|
11
11
|
[:title, :title],
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path('../../../../lib/mappy/target_builder_factory', __FILE__)
|
2
|
+
require File.expand_path('../../model_support', __FILE__)
|
3
|
+
|
4
|
+
module Mappy
|
5
|
+
describe TargetBuilderFactory do
|
6
|
+
subject { described_class.new }
|
7
|
+
|
8
|
+
context '.call' do
|
9
|
+
it 'returns a builder lambda based on the input' do
|
10
|
+
expect(described_class.call('mappy/mock_valid_model')).to respond_to(:new)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context '#call' do
|
15
|
+
it 'returns a builder lambda based on the input' do
|
16
|
+
expect(subject.call('mappy/mock_valid_model')).to respond_to(:new)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'raises an exception when the builder does not have attributes' do
|
20
|
+
expect {
|
21
|
+
subject.call('mappy/mock_invalid_model')
|
22
|
+
}.to raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/spec/lib/mappy_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path('../../../lib/mappy', __FILE__)
|
2
|
+
require File.expand_path('../model_support', __FILE__)
|
2
3
|
|
3
4
|
describe Mappy do
|
4
5
|
context '.to_type' do
|
@@ -14,7 +15,7 @@ describe Mappy do
|
|
14
15
|
Mappy.configure do |config|
|
15
16
|
config.legend(
|
16
17
|
source: :journal,
|
17
|
-
target: '
|
18
|
+
target: 'mappy/mock_valid_model',
|
18
19
|
legend: [
|
19
20
|
[:title, :title],
|
20
21
|
[lambda{|*|'long-journal'}, :work_type],
|
@@ -27,11 +28,8 @@ describe Mappy do
|
|
27
28
|
end
|
28
29
|
|
29
30
|
let(:title) { 'A Rocking Title' }
|
30
|
-
let(:journal) {
|
31
|
-
|
32
|
-
}
|
33
|
-
|
34
|
-
subject { Mappy.map(journal, target: 'orcid/work') }
|
31
|
+
let(:journal) { double('Journal', to_mappy_type: :journal, title: title) }
|
32
|
+
subject { Mappy.map(journal, target: 'mappy/mock_valid_model') }
|
35
33
|
|
36
34
|
its(:work_type) { should eq('long-journal')}
|
37
35
|
its(:title) { should eq(title) }
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Mappy
|
2
|
+
class MockValidModel
|
3
|
+
attr_accessor :title, :work_type
|
4
|
+
def initialize(attributes)
|
5
|
+
attributes.each_pair do |key, value|
|
6
|
+
send("#{key}=", value) if respond_to?("#{key}=")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class MockInvalidModel
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mappy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Friesen
|
@@ -10,6 +10,20 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2014-02-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
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'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,11 +96,14 @@ files:
|
|
82
96
|
- lib/mappy.rb
|
83
97
|
- lib/mappy/configuration.rb
|
84
98
|
- lib/mappy/resolver.rb
|
99
|
+
- lib/mappy/target_builder_factory.rb
|
85
100
|
- lib/mappy/version.rb
|
86
101
|
- mappy.gemspec
|
87
102
|
- spec/lib/mappy/configuration_spec.rb
|
88
103
|
- spec/lib/mappy/resolver_spec.rb
|
104
|
+
- spec/lib/mappy/target_builder_factory_spec.rb
|
89
105
|
- spec/lib/mappy_spec.rb
|
106
|
+
- spec/lib/model_support.rb
|
90
107
|
homepage: https://github.com/jeremyf/mappy
|
91
108
|
licenses:
|
92
109
|
- APACHE2
|
@@ -114,4 +131,6 @@ summary: Map one object to another
|
|
114
131
|
test_files:
|
115
132
|
- spec/lib/mappy/configuration_spec.rb
|
116
133
|
- spec/lib/mappy/resolver_spec.rb
|
134
|
+
- spec/lib/mappy/target_builder_factory_spec.rb
|
117
135
|
- spec/lib/mappy_spec.rb
|
136
|
+
- spec/lib/model_support.rb
|