mappy 0.0.5 → 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 +4 -4
- data/README.md +50 -15
- data/Rakefile +6 -0
- data/lib/mappy.rb +37 -14
- data/lib/mappy/configuration.rb +4 -3
- data/lib/mappy/exceptions.rb +3 -0
- data/lib/mappy/map_store.rb +2 -0
- data/lib/mappy/resolver.rb +2 -0
- data/lib/mappy/target_builder_factory.rb +3 -2
- data/lib/mappy/version.rb +1 -1
- data/mappy.gemspec +1 -0
- data/spec/lib/mappy/configuration_spec.rb +6 -4
- data/spec/lib/mappy_spec.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4bbb59217a36e78e7771bc6cfb785ee4e98927df
|
4
|
+
data.tar.gz: 95c90b75b8e56c6db422fc253fbc0f176813666c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0c28bc091328590967f0e28d3828877822fd3ee53fe28ef6f986764337c7bad65d1a4d886c71ba272eb51e29260f8b81b109026eb0f6a1c3b2deafb507586c6
|
7
|
+
data.tar.gz: c240762fa3bee3d3caa09078c0ea6fab1f56612fbc995906fa0937a78bd7c0adb85244f1fa91f1afee560dffa5a378d470b6cd22d197df1127fef39c682c7025
|
data/README.md
CHANGED
@@ -3,21 +3,6 @@
|
|
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
|
-
|
21
6
|
## Installation
|
22
7
|
|
23
8
|
Add this line to your application's Gemfile:
|
@@ -31,3 +16,53 @@ And then execute:
|
|
31
16
|
Or install it yourself as:
|
32
17
|
|
33
18
|
$ gem install mappy
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
You can certainly read the documentation. In particular the [Mappy module](lib/mappy.rb).
|
23
|
+
But if you are like me, you won't trust the documentation.
|
24
|
+
Instead I would recommend reading the specs, especially [mappy_spec](spec/mappy_spec.rb)
|
25
|
+
|
26
|
+
### TL;DR
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
class Book
|
30
|
+
attr_accessor :name
|
31
|
+
def initialize(attributes = {})
|
32
|
+
attributes.each {|key, value| send("#{key}=", value) if respond_to?("#{key}=") }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Orcid::Work
|
37
|
+
attr_accessor :title
|
38
|
+
def initialize(attributes = {})
|
39
|
+
attributes.each {|key, value| send("#{key}=", value) if respond_to?("#{key}=") }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Mappy.configure do |config|
|
44
|
+
config.register(source: 'book', target: 'orcid/work', legend: [:name, :title])
|
45
|
+
end
|
46
|
+
|
47
|
+
book = Book.new(title: 'Hello World')
|
48
|
+
orcid_work = Mappy.map(book, target: 'orcid/work')
|
49
|
+
|
50
|
+
assert_equal orcid_work.title, book.name
|
51
|
+
```
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
## Why?
|
56
|
+
|
57
|
+
Because I have discovered that I am regularly working with a heterogenious set of
|
58
|
+
objects that need to be handled via some other service. And that service has its
|
59
|
+
expected data structure. And there are quite a few services.
|
60
|
+
|
61
|
+
That is to say, I'm attempting to submit a work to my Orcid Profile. I need some
|
62
|
+
method for defining how to map my home grown "Article" object to the attributes
|
63
|
+
that are needed for an Orcide work. And I don't want to infect my Article class
|
64
|
+
with a #to_orcid_profile_attributes method.
|
65
|
+
|
66
|
+
Or I want to create a DOI for my Article.
|
67
|
+
|
68
|
+
In essence, Mappy provides a configurable seam in an application.
|
data/Rakefile
CHANGED
data/lib/mappy.rb
CHANGED
@@ -3,43 +3,66 @@ require "mappy/configuration"
|
|
3
3
|
|
4
4
|
module Mappy
|
5
5
|
class << self
|
6
|
-
|
6
|
+
attr_writer :configuration
|
7
|
+
def configuration
|
8
|
+
@configuration ||= Configuration.new
|
9
|
+
end
|
10
|
+
private :configuration
|
11
|
+
|
7
12
|
end
|
8
13
|
|
9
14
|
module_function
|
10
|
-
|
15
|
+
# Determines the object's Mappy type
|
16
|
+
#
|
17
|
+
# @param object [Object] the source object
|
18
|
+
# @return [String] the Mappy type which should be used in configuring Mappy
|
19
|
+
# @see Mappy.configure
|
11
20
|
def to_type(object)
|
12
21
|
return object.to_mappy_type if object.respond_to?(:to_mappy_type)
|
13
22
|
object.class.to_s.underscore
|
14
23
|
end
|
15
24
|
|
16
|
-
#
|
17
|
-
# initialization requirements for those RemoteServices (i.e. credentials)
|
25
|
+
# Registers a collection of maps.
|
18
26
|
#
|
19
27
|
# @example
|
28
|
+
# Mappy.configure do |config|
|
29
|
+
# config.register(source: 'book', target: 'orcid/work', legend: [:name, :title])
|
30
|
+
# end
|
20
31
|
#
|
21
32
|
# @yieldparam config [Configuration]
|
22
33
|
# @see Mappy::Railtie
|
23
34
|
def configure(&block)
|
24
|
-
|
25
|
-
|
26
|
-
# The Rails load sequence means that some of the configured Targets may
|
27
|
-
# not be loaded; As such I am not calling configure! instead relying on
|
28
|
-
# Mappy::Railtie to handle the configure! call
|
29
|
-
finalize! unless defined?(Rails)
|
35
|
+
yield(configuration)
|
30
36
|
end
|
31
37
|
|
38
|
+
# Converts the source object to an instance of the options[:target].
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# Mappy.configure do |config|
|
42
|
+
# config.register(source: 'book', target: 'orcid/work', legend: [:name, :title])
|
43
|
+
# end
|
44
|
+
# book = Book.new(title: 'Hello World')
|
45
|
+
# orcid_work = Mappy.map(book, target: 'orcid/work')
|
46
|
+
#
|
47
|
+
# assert_equal orcid_work.title, book.name
|
48
|
+
#
|
49
|
+
# @param source [Object] :source - the instance of a class that you are mapping from
|
50
|
+
# @param options [Hash]
|
51
|
+
# @options options [String] :target - the class name of the target that you are mapping to.
|
52
|
+
# @return [Object] an instance of the :target that has been instantiated by mapping the :source object
|
53
|
+
#
|
54
|
+
# @see Mappy.configure
|
32
55
|
def map(source, options = {})
|
33
56
|
configuration.map(source, options)
|
34
57
|
end
|
35
58
|
|
59
|
+
# @deprecated
|
36
60
|
def finalize!
|
37
|
-
if @configuration_block.respond_to?(:call)
|
38
|
-
self.configuration ||= Configuration.new
|
39
|
-
@configuration_block.call(configuration)
|
40
|
-
end
|
41
61
|
end
|
42
62
|
|
63
|
+
# Because sometimes, when you are testing things, you might want a new
|
64
|
+
# configuration.
|
65
|
+
# :nodoc:
|
43
66
|
def reset!
|
44
67
|
self.configuration = Configuration.new
|
45
68
|
end
|
data/lib/mappy/configuration.rb
CHANGED
@@ -7,16 +7,16 @@ module Mappy
|
|
7
7
|
class Configuration
|
8
8
|
attr_reader :map_store
|
9
9
|
def initialize(config = {})
|
10
|
-
@map_store = config.fetch(:map_store) {
|
10
|
+
@map_store = config.fetch(:map_store) { MapStore.new }
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
13
|
+
def register(options = {})
|
14
14
|
map_store.write(options)
|
15
15
|
end
|
16
16
|
|
17
17
|
def map(source_instance, options = {})
|
18
18
|
target = options.fetch(:target)
|
19
|
-
target_builder_finder = options.fetch(:target_builder_finder) {
|
19
|
+
target_builder_finder = options.fetch(:target_builder_finder) { TargetBuilderFactory }
|
20
20
|
target_builder = target_builder_finder.call(target)
|
21
21
|
|
22
22
|
return source_instance if source_instance.is_a?(target_builder)
|
@@ -43,4 +43,5 @@ module Mappy
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
private_constant :Configuration
|
46
47
|
end
|
data/lib/mappy/exceptions.rb
CHANGED
data/lib/mappy/map_store.rb
CHANGED
data/lib/mappy/resolver.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'active_support/inflector'
|
2
|
+
require File.expand_path('../exceptions', __FILE__)
|
2
3
|
|
3
4
|
module Mappy
|
4
|
-
class InvalidTargetBuilder < RuntimeError
|
5
|
-
end
|
6
5
|
|
7
6
|
# Responsible for taking a symbol, finding the appropriate class then
|
8
7
|
# verifying that the class is "well formed."
|
@@ -34,4 +33,6 @@ module Mappy
|
|
34
33
|
|
35
34
|
end
|
36
35
|
end
|
36
|
+
|
37
|
+
private_constant :TargetBuilderFactory
|
37
38
|
end
|
data/lib/mappy/version.rb
CHANGED
data/mappy.gemspec
CHANGED
@@ -2,14 +2,16 @@ require File.expand_path('../../../../lib/mappy/configuration', __FILE__)
|
|
2
2
|
|
3
3
|
module Mappy
|
4
4
|
describe Configuration do
|
5
|
-
let(:map_store) {
|
5
|
+
let(:map_store) { MapStore.new }
|
6
6
|
let(:legend) { [[:title, :title]] }
|
7
7
|
|
8
8
|
subject { described_class.new(map_store: map_store) }
|
9
9
|
|
10
|
-
context '#
|
10
|
+
context '#register' do
|
11
|
+
before(:each) do
|
12
|
+
end
|
11
13
|
it 'should yield a map storage' do
|
12
|
-
subject.
|
14
|
+
subject.register(source: :article, target: :document, legend: legend)
|
13
15
|
expect(map_store.read(source: :article, target: :document)).to eq(legend)
|
14
16
|
end
|
15
17
|
end
|
@@ -22,7 +24,7 @@ module Mappy
|
|
22
24
|
let(:target_builder_finder) { double("Finder") }
|
23
25
|
|
24
26
|
before(:each) do
|
25
|
-
subject.
|
27
|
+
subject.register(source: source_type, target: target_type, legend: legend)
|
26
28
|
end
|
27
29
|
it 'should yield a map storage' do
|
28
30
|
target_builder_finder.should_receive(:call).with(target_type).and_return(target_builder)
|
data/spec/lib/mappy_spec.rb
CHANGED
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
|
4
|
+
version: 0.1.0
|
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-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - '>='
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
description: Map one object to another
|
84
98
|
email:
|
85
99
|
- jeremy.n.friesen@gmail.com
|
@@ -138,3 +152,4 @@ test_files:
|
|
138
152
|
- spec/lib/mappy/target_builder_factory_spec.rb
|
139
153
|
- spec/lib/mappy_spec.rb
|
140
154
|
- spec/lib/model_support.rb
|
155
|
+
has_rdoc:
|