karta 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.reek +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +3 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.yardopts +3 -0
- data/Gemfile +5 -0
- data/LICENSE +22 -0
- data/README.md +106 -0
- data/Rakefile +2 -0
- data/karta.gemspec +29 -0
- data/lib/karta.rb +69 -0
- data/lib/karta/error.rb +19 -0
- data/lib/karta/mapper.rb +79 -0
- data/lib/karta/mapper_registry.rb +67 -0
- data/lib/karta/version.rb +4 -0
- data/spec/acceptance/map_instance_to_class_spec.rb +43 -0
- data/spec/acceptance/map_instance_to_instance_spec.rb +46 -0
- data/spec/karta/mapper_registry_spec.rb +120 -0
- data/spec/karta/mapper_spec.rb +131 -0
- data/spec/karta_spec.rb +154 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/macros/define_constant.rb +57 -0
- metadata +173 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 231b33f0743a4ef1e663dd75c255b172f99d30f1
|
4
|
+
data.tar.gz: 081df11b8bd73cc4ca3c9ba8b52ed98e91b79221
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7dbf32d707430e58f73cdd13fc91420ed11902bd866c361e50713c73a90b883145bd7451738bd57050df219a4c80b96fb08b696145c1b0c0bb6d16a0499b2b44
|
7
|
+
data.tar.gz: d694e2de81f5088196ae1b9a56859e36f001c43f77679a6fda2df234010f9658cee79329ec92ecbea20bf84fcc914849362c46f1dacb193090702fb11bbe0c64
|
data/.gitignore
ADDED
data/.reek
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
karta
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.1
|
data/.yardopts
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 Samuel Nilsson
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# Karta
|
2
|
+
|
3
|
+
Karta is a very light-weight Ruby library that makes it easy to create mapper objects in a Ruby application. The mapper object makes it easy to map or transform one object into an other. The main use case is to transform data objects from an domain to another domain, e.g. map a `Twitter::User` to `User`. Instead of having to, for example, define a method `#from_twitter_user` on the `User` class which sets all attributes correctly a mapper object is created which defines all mappings.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'karta'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install karta
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
### Setting up a mapper
|
24
|
+
The main functionality of Karta is used by letting a class inherit from `Karta::Mapper`. By doing so the class gets a `#map` method which will run all methods starting with `map_` with the two objects as arguments.
|
25
|
+
|
26
|
+
##### Example
|
27
|
+
```ruby
|
28
|
+
class MyTwitterMapper < Karta::Mapper
|
29
|
+
def map_email(twitter_user, user)
|
30
|
+
user.email = twitter_user.twitter_email
|
31
|
+
end
|
32
|
+
|
33
|
+
def map_username(twitter_user, user)
|
34
|
+
user.username = twitter_user.twitter_handle.gsub('@', '')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Mapping from one instance to another, overriding
|
39
|
+
# values if already set
|
40
|
+
twitter_user = ...
|
41
|
+
user = ...
|
42
|
+
mapped_user = MyTwitterMapper.new.map(from: twitter_user, to: user)
|
43
|
+
|
44
|
+
# Mapping from an instance to a class, will return
|
45
|
+
# a new instance of the class
|
46
|
+
twitter_user = ...
|
47
|
+
user = MyTwitterMapper.new.map(from: twitter_user, to: User)
|
48
|
+
|
49
|
+
# Using class method (which instantiates before running map on the instance)
|
50
|
+
twitter_user = ...
|
51
|
+
user = MyTwitterMapper.map(from: twitter_user, to: User)
|
52
|
+
```
|
53
|
+
|
54
|
+
### Using the mapper registry
|
55
|
+
To simplify cases when an application has several mappers it is possible to register mappers and then only use `Karta.map` to map between two objects.
|
56
|
+
|
57
|
+
##### Example
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
class MyMapper < Karta::Mapper
|
61
|
+
# map methods...
|
62
|
+
end
|
63
|
+
|
64
|
+
Karta.register_mapper MyMapper, from_klass: Twitter::User, to_klass: User
|
65
|
+
|
66
|
+
# There is an option to not have to specify from and to class
|
67
|
+
# when registering the mapper. This relies on reflection and
|
68
|
+
# requires the mapper to have a class name on the correct format
|
69
|
+
# (`[from class]To[to class]Mapper`) for example `FooToBarMapper`.
|
70
|
+
class FooToBarMapper < Karta::Mapper
|
71
|
+
# map methods
|
72
|
+
end
|
73
|
+
|
74
|
+
# Register mapper with from_klass = Foo and to_klass = Bar
|
75
|
+
Karta.register_mapper FooToBarMapper
|
76
|
+
|
77
|
+
# Using Karta.map to map between two objects
|
78
|
+
twitter_user = ...
|
79
|
+
user = Karta.map(from: twitter_user, to: User)
|
80
|
+
|
81
|
+
foo = ...
|
82
|
+
bar = Karta.map(from: foo, to Bar)
|
83
|
+
```
|
84
|
+
|
85
|
+
### One to one mappings
|
86
|
+
Sometimes you have fields that could be mapped directly without performing any transformations instead of having to define mapping methods for each you can use `one_to_one_mapping :attr`.
|
87
|
+
|
88
|
+
##### Example
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
class FooToBarMapper < Karta::Mapper
|
92
|
+
one_to_one_mapping :email
|
93
|
+
end
|
94
|
+
|
95
|
+
foo = ...
|
96
|
+
bar = FooToBarMapper.map(from: foo, to Bar)
|
97
|
+
puts foo.email == bar.email # => true
|
98
|
+
```
|
99
|
+
|
100
|
+
## Contributing
|
101
|
+
|
102
|
+
1. Fork it ( https://github.com/samuel02/karta/fork )
|
103
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
104
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
105
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
106
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/karta.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'karta/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'karta'
|
9
|
+
spec.version = Karta::VERSION
|
10
|
+
spec.authors = ['Samuel Nilsson']
|
11
|
+
spec.email = ['mail@samuelnilsson.me']
|
12
|
+
spec.summary = 'A simple Ruby gem for creating mappers which map one '\
|
13
|
+
'object to another.'
|
14
|
+
spec.homepage = ''
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
23
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
24
|
+
spec.add_development_dependency 'rspec', '~> 3.5'
|
25
|
+
spec.add_development_dependency 'byebug', '~> 9.0'
|
26
|
+
spec.add_development_dependency 'rubocop', '~> 0.46.0'
|
27
|
+
spec.add_development_dependency 'simplecov', '~> 0.12.0'
|
28
|
+
spec.add_development_dependency 'fuubar', '~> 2.2'
|
29
|
+
end
|
data/lib/karta.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'karta/version'
|
3
|
+
require 'karta/mapper_registry'
|
4
|
+
require 'karta/error'
|
5
|
+
require 'karta/mapper'
|
6
|
+
|
7
|
+
# The module that contains everything relating to Karta
|
8
|
+
#
|
9
|
+
# @author Samuel Nilsson <mail@samuelnilsson.me>
|
10
|
+
module Karta
|
11
|
+
# Holds the global registry of mappers
|
12
|
+
#
|
13
|
+
# @return [MapperRegistry] the mapper registry
|
14
|
+
def self.mapper_registry
|
15
|
+
@mapper_registry ||= MapperRegistry.new
|
16
|
+
end
|
17
|
+
|
18
|
+
# Register a new mapper to the registry
|
19
|
+
#
|
20
|
+
# @param mapper [Karta::Mapper] the mapper to be registered
|
21
|
+
# @param from_klass [Class] the class the mapper is supposed to map from
|
22
|
+
# @param to_klass [Class] the class the mapper is supposed to map to
|
23
|
+
#
|
24
|
+
# @return [MapperRegistry]
|
25
|
+
def self.register_mapper(mapper, from_klass: nil, to_klass: nil)
|
26
|
+
mapper_registry.register(mapper: mapper,
|
27
|
+
from_klass: from_klass,
|
28
|
+
to_klass: to_klass)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Map an object to another using a registered mapper. Returns a new instance
|
32
|
+
# of the mapped object.
|
33
|
+
#
|
34
|
+
# @param from [Object] the object to map from
|
35
|
+
# @param to [Object, Class] the object or class to map to
|
36
|
+
#
|
37
|
+
# @raise [ArgumentError] if trying to map from a class rather than an instance
|
38
|
+
#
|
39
|
+
# @return [Object] a new instance of the same type as `to`
|
40
|
+
def self.map(from:, to:)
|
41
|
+
to, to_klass, from, from_klass = *_handle_map_args(from, to)
|
42
|
+
|
43
|
+
mapper_registry.find(from_klass: from_klass, to_klass: to_klass)
|
44
|
+
.map(from: from, to: to)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Map an object to another using a registered mapper. Performs the mapping
|
48
|
+
# "in place" and thus modifies the 'to' object and overrides attributes.
|
49
|
+
#
|
50
|
+
# @param from [Object] the object to map from
|
51
|
+
# @param to [Object, Class] the object or class to map to
|
52
|
+
#
|
53
|
+
# @raise [ArgumentError] if trying to map from a class rather than an instance
|
54
|
+
#
|
55
|
+
# @return [Object] returns modified version of 'to'
|
56
|
+
def self.map!(from:, to:)
|
57
|
+
to, to_klass, from, from_klass = *_handle_map_args(from, to)
|
58
|
+
|
59
|
+
mapper_registry.find(from_klass: from_klass, to_klass: to_klass)
|
60
|
+
.map!(from: from, to: to)
|
61
|
+
end
|
62
|
+
|
63
|
+
# @api private
|
64
|
+
def self._handle_map_args(from, to)
|
65
|
+
raise ArgumentError, 'cannot map from a class' if from.is_a?(Class)
|
66
|
+
to_klass = to.is_a?(Class) ? to : to.class
|
67
|
+
[to, to_klass, from, from.class]
|
68
|
+
end
|
69
|
+
end
|
data/lib/karta/error.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Karta
|
3
|
+
# Basic class for exceptions in Karta
|
4
|
+
class Error < StandardError; end
|
5
|
+
|
6
|
+
# Exception for case when a mapper cannot be found
|
7
|
+
class MapperNotFoundError < Error
|
8
|
+
def initialize(from, to)
|
9
|
+
super("no mapper found (#{from} → #{to})")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Exception for case when a mapper has an invalid name
|
14
|
+
class InvalidNameError < Error
|
15
|
+
def initialize
|
16
|
+
super('mapper name must be on format [Foo]To[Bar]Mapper')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/karta/mapper.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Karta
|
3
|
+
# Contains the basic functionality for a mapper object,
|
4
|
+
# the class is meant to be inherited by a mapper class
|
5
|
+
# in order to get the `#map method as well as being able
|
6
|
+
# to specify one-to-one mappings
|
7
|
+
class Mapper
|
8
|
+
# Maps an object to another using all mapping methods defined on the mapper.
|
9
|
+
# Mapping methods are defined as "one-to-one mappings" by using
|
10
|
+
# `.one_to_one_mapping`or by defining methods with names starting with
|
11
|
+
# 'map_'. The mapping methods are supposed to take the object which it is
|
12
|
+
# mapping from as well as the object which it should map into.
|
13
|
+
#
|
14
|
+
# @param from [Object] the object to map from
|
15
|
+
# @param to [Object, Class] the object or class to map to
|
16
|
+
#
|
17
|
+
# @return [Object] a new instance of the same type as `to`
|
18
|
+
def map(from:, to:)
|
19
|
+
to_klass = to.is_a?(Class) ? to : to.class
|
20
|
+
_map(from, to_klass.new)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Maps an object to another using all mapping methods defined on the mapper.
|
24
|
+
# see #map
|
25
|
+
#
|
26
|
+
# @param from [Object] the object to map from
|
27
|
+
# @param to [Object, Class] the object or class to map to
|
28
|
+
#
|
29
|
+
# @return [Object] a new instance of the same type as `to`
|
30
|
+
def map!(from:, to:)
|
31
|
+
to = to.new if to.is_a?(Class)
|
32
|
+
_map(from, to)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Find all mapping methods defined on the mapper.
|
36
|
+
#
|
37
|
+
# @return [Array<Symbol>] names of all methods beginning with `map_`
|
38
|
+
def self.mapping_methods
|
39
|
+
public_instance_methods(true).grep(/^map_/)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Defines a one-to-one mapping on the mapper as a method.
|
43
|
+
#
|
44
|
+
# A one-to-one-mapping is a mapping where the attribute names are equal
|
45
|
+
# and no transformation is supposed to take place. E.g. `foo.id = bar.id`.
|
46
|
+
def self.one_to_one_mapping(attr)
|
47
|
+
define_method("map_#{attr}") do |from, to|
|
48
|
+
to.send("#{attr}=", from.send(attr))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Instantiates a mapper and runs the `#map` method
|
53
|
+
#
|
54
|
+
# @param from [Object] the object to map from
|
55
|
+
# @param to [Object, Class] the object or class to map to
|
56
|
+
#
|
57
|
+
# @return [Object] a new instance of the same type as `to`
|
58
|
+
def self.map(from:, to:)
|
59
|
+
new.map(from: from, to: to)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Instantiates a mapper and runs the `#map!` method
|
63
|
+
#
|
64
|
+
# @param from [Object] the object to map from
|
65
|
+
# @param to [Object, Class] the object or class to map to
|
66
|
+
#
|
67
|
+
# @return [Object] a new instance of the same type as `to`
|
68
|
+
def self.map!(from:, to:)
|
69
|
+
new.map!(from: from, to: to)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def _map(from, to)
|
75
|
+
self.class.mapping_methods.each { |meth| send(meth, from, to) }
|
76
|
+
to
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Karta
|
3
|
+
# Simple collection class for mappers
|
4
|
+
class MapperRegistry
|
5
|
+
attr_reader :mappers
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@mappers = []
|
9
|
+
end
|
10
|
+
|
11
|
+
# Register a mapper to the registry.
|
12
|
+
#
|
13
|
+
# If no from_klass or to_klass are specified it will try to parse this
|
14
|
+
# from the class name of the mapper. This assumes that the class name
|
15
|
+
# of the mapper is on the form `[from class]To[to class]Mapper`, e.g.
|
16
|
+
# `FooToBarMapper`. For obvious reasons this makes it hard to handle
|
17
|
+
# cases where one of the classes is namespaced, e.g. `Baz::Bar`. For
|
18
|
+
# those cases the `from_klass` and `to_klass` must be specified.
|
19
|
+
#
|
20
|
+
# @param mapper [Karta::Mapper] the mapper to register
|
21
|
+
# @param from_klass [Class] the class the mapper is supposed to map from
|
22
|
+
# @param to_klass [Class] the class the mapper is supposed to map to
|
23
|
+
#
|
24
|
+
# @raise [InvalidNameError] if no `from_klass` or `to_klass` is specified
|
25
|
+
# and the class name of the mapper does not follow the correct format.
|
26
|
+
#
|
27
|
+
# @return [MapperRegistry] the mapper registry after the mapper has been
|
28
|
+
# added
|
29
|
+
def register(mapper:, from_klass: nil, to_klass: nil)
|
30
|
+
unless from_klass && to_klass
|
31
|
+
from_klass, to_klass = *klasses_from_class_name(mapper.to_s)
|
32
|
+
end
|
33
|
+
|
34
|
+
mappers.push(mapper: mapper,
|
35
|
+
from_klass: from_klass,
|
36
|
+
to_klass: to_klass)
|
37
|
+
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
# Find a mapper in the registry
|
42
|
+
#
|
43
|
+
# @param from_klass [Class] the class the mapper is supposed to map from
|
44
|
+
# @param to_klass [Class] the class the mapper is supposed to map to
|
45
|
+
#
|
46
|
+
# @raise [MapperNotFoundError] if no applicable mapper is found
|
47
|
+
#
|
48
|
+
# @return [Karta::Mapper] the found mapper
|
49
|
+
def find(from_klass:, to_klass:)
|
50
|
+
mappers.find(lambda do
|
51
|
+
raise MapperNotFoundError.new(from_klass, to_klass)
|
52
|
+
end) do |mapper|
|
53
|
+
mapper[:from_klass] == from_klass && mapper[:to_klass] == to_klass
|
54
|
+
end.fetch(:mapper)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def klasses_from_class_name(klass_name)
|
60
|
+
raise InvalidNameError unless klass_name =~ /.*To.*Mapper/
|
61
|
+
|
62
|
+
klass_name.gsub('Mapper', '')
|
63
|
+
.split('To')
|
64
|
+
.map(&Kernel.method(:const_get))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'mapping from one instance to a class' do
|
5
|
+
before do
|
6
|
+
define_klass 'Foo', attrs: [:id, :foo_name]
|
7
|
+
define_klass 'Bar', attrs: [:id, :name]
|
8
|
+
|
9
|
+
define_klass 'FooToBarMapper', base: Karta::Mapper do
|
10
|
+
one_to_one_mapping :id
|
11
|
+
|
12
|
+
def map_name(foo, bar)
|
13
|
+
bar.name = foo.foo_name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:foo) { Foo.new(id: 1, foo_name: 'Foo') }
|
19
|
+
|
20
|
+
describe 'using a mapper object' do
|
21
|
+
subject { FooToBarMapper.map(from: foo, to: Bar) }
|
22
|
+
|
23
|
+
it 'creates a new instance and maps all fields defined in the mapper' do
|
24
|
+
expect(subject.class).to eq Bar
|
25
|
+
expect(subject.id).to eq foo.id
|
26
|
+
expect(subject.name).to eq foo.foo_name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'using the mapper registry' do
|
31
|
+
before do
|
32
|
+
Karta.register_mapper FooToBarMapper
|
33
|
+
end
|
34
|
+
|
35
|
+
subject { Karta.map(from: foo, to: Bar) }
|
36
|
+
|
37
|
+
it 'creates a new instance and maps all fields defined in the mapper' do
|
38
|
+
expect(subject.class).to eq Bar
|
39
|
+
expect(subject.id).to eq foo.id
|
40
|
+
expect(subject.name).to eq foo.foo_name
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'mapping from one instance to another' do
|
5
|
+
before do
|
6
|
+
define_klass 'Foo', attrs: [:id, :foo_name]
|
7
|
+
define_klass 'Bar', attrs: [:id, :name]
|
8
|
+
|
9
|
+
define_klass 'FooToBarMapper', base: Karta::Mapper do
|
10
|
+
one_to_one_mapping :id
|
11
|
+
|
12
|
+
def map_name(foo, bar)
|
13
|
+
bar.name = foo.foo_name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:foo) { Foo.new(id: 1, foo_name: 'Foo') }
|
19
|
+
let(:bar) { Bar.new(id: 2, name: '') }
|
20
|
+
|
21
|
+
describe 'using a mapper object' do
|
22
|
+
subject { FooToBarMapper.map!(from: foo, to: bar) }
|
23
|
+
|
24
|
+
it 'maps all fields defined in the mapper' do
|
25
|
+
expect(subject.class).to eq Bar
|
26
|
+
expect(subject.id).to eq foo.id
|
27
|
+
expect(subject.name).to eq foo.foo_name
|
28
|
+
expect(bar.id).to eq 1
|
29
|
+
expect(bar.name).to eq 'Foo'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'using the mapper registry' do
|
34
|
+
before do
|
35
|
+
Karta.register_mapper FooToBarMapper
|
36
|
+
end
|
37
|
+
|
38
|
+
subject { Karta.map!(from: foo, to: bar) }
|
39
|
+
|
40
|
+
it 'maps all fields defined in the mapper' do
|
41
|
+
expect(subject.class).to eq Bar
|
42
|
+
expect(subject.id).to eq foo.id
|
43
|
+
expect(subject.name).to eq foo.foo_name
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Karta::MapperRegistry do
|
5
|
+
describe '#register' do
|
6
|
+
subject(:mapper_registry) { Karta::MapperRegistry.new }
|
7
|
+
|
8
|
+
context 'when from_klass or to_klass are not specified' do
|
9
|
+
context 'when the class name of the mapper follows the correct format' do
|
10
|
+
before do
|
11
|
+
define_klass 'Foo'
|
12
|
+
define_klass 'Bar'
|
13
|
+
define_klass 'FooToBarMapper', base: Karta::Mapper
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'parses the class names from the mapper name and adds the mapper' do
|
17
|
+
mapper_registry.register(mapper: FooToBarMapper)
|
18
|
+
|
19
|
+
expect(mapper_registry.mappers.count).to eq 1
|
20
|
+
|
21
|
+
mapper = mapper_registry.mappers.first
|
22
|
+
|
23
|
+
expect(mapper[:mapper]).to eq FooToBarMapper
|
24
|
+
expect(mapper[:from_klass]).to eq Foo
|
25
|
+
expect(mapper[:to_klass]).to eq Bar
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when the class name of the mapper contains a namespaced class' do
|
30
|
+
before do
|
31
|
+
define_klass 'Baz'
|
32
|
+
define_klass 'Baz::Foo'
|
33
|
+
define_klass 'Bar'
|
34
|
+
define_klass 'Baz::FooToBarMapper', base: Karta::Mapper
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'parses the class names from the mapper name and adds the mapper' do
|
38
|
+
mapper_registry.register(mapper: Baz::FooToBarMapper)
|
39
|
+
|
40
|
+
expect(mapper_registry.mappers.count).to eq 1
|
41
|
+
|
42
|
+
mapper = mapper_registry.mappers.first
|
43
|
+
|
44
|
+
expect(mapper[:mapper]).to eq Baz::FooToBarMapper
|
45
|
+
expect(mapper[:from_klass]).to eq Baz::Foo
|
46
|
+
expect(mapper[:to_klass]).to eq Bar
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "when the class name of the mapper isn't on the correct format" do
|
51
|
+
before do
|
52
|
+
define_klass 'CustomMapper', base: Karta::Mapper
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'raises an error' do
|
56
|
+
expect do
|
57
|
+
mapper_registry.register(mapper: CustomMapper)
|
58
|
+
end.to raise_error Karta::InvalidNameError,
|
59
|
+
'mapper name must be on format [Foo]To[Bar]Mapper'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when from_klass and to_klass are specified' do
|
65
|
+
before do
|
66
|
+
define_klass 'Foo'
|
67
|
+
define_klass 'Bar'
|
68
|
+
define_klass 'CustomMapper', base: Karta::Mapper
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'adds the mapper to the registry' do
|
72
|
+
mapper_registry.register mapper: CustomMapper,
|
73
|
+
from_klass: Foo,
|
74
|
+
to_klass: Bar
|
75
|
+
|
76
|
+
expect(mapper_registry.mappers.count).to eq 1
|
77
|
+
|
78
|
+
mapper = mapper_registry.mappers.first
|
79
|
+
|
80
|
+
expect(mapper[:mapper]).to eq CustomMapper
|
81
|
+
expect(mapper[:from_klass]).to eq Foo
|
82
|
+
expect(mapper[:to_klass]).to eq Bar
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe '#find' do
|
88
|
+
subject(:mapper_registry) { Karta::MapperRegistry.new }
|
89
|
+
|
90
|
+
context 'when an appropriate mapper exists' do
|
91
|
+
before do
|
92
|
+
define_klass 'Foo'
|
93
|
+
define_klass 'Bar'
|
94
|
+
define_klass 'FooToBarMapper', base: Karta::Mapper
|
95
|
+
|
96
|
+
allow(mapper_registry).to\
|
97
|
+
receive(:mappers).and_return([{
|
98
|
+
mapper: FooToBarMapper,
|
99
|
+
from_klass: Foo,
|
100
|
+
to_klass: Bar
|
101
|
+
}])
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'returns the mapper from the registry' do
|
105
|
+
expect(
|
106
|
+
mapper_registry.find(from_klass: Foo, to_klass: Bar)
|
107
|
+
).to eq FooToBarMapper
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'when no appropriate mapper can be found' do
|
112
|
+
it 'raises an error with a good error message' do
|
113
|
+
expect do
|
114
|
+
mapper_registry.find(from_klass: Integer, to_klass: Array)
|
115
|
+
end.to raise_error Karta::MapperNotFoundError,
|
116
|
+
'no mapper found (Integer → Array)'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Karta::Mapper do
|
5
|
+
describe '#map' do
|
6
|
+
before do
|
7
|
+
define_klass 'Foo'
|
8
|
+
define_klass 'Bar'
|
9
|
+
end
|
10
|
+
|
11
|
+
let!(:mapper) do
|
12
|
+
define_klass('MyMapper', base: Karta::Mapper).new
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
allow(MyMapper).to receive(:mapping_methods).and_return([:method])
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when to is an instance' do
|
20
|
+
let(:from) { Foo.new }
|
21
|
+
let(:to) { Bar.new }
|
22
|
+
|
23
|
+
it 'calls all mapping methods with from and to \
|
24
|
+
and returns new instance' do
|
25
|
+
expect(mapper).to receive(:send).with(:method, from, Bar)
|
26
|
+
mapper.map(from: from, to: to)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when to is a class' do
|
31
|
+
let(:from) { Foo.new }
|
32
|
+
let(:to) { Bar }
|
33
|
+
|
34
|
+
it 'calls all mapping methods with from and a to instance' do
|
35
|
+
expect(mapper).to receive(:send).with(:method, from, to)
|
36
|
+
|
37
|
+
mapper.map(from: from, to: to)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#map!' do
|
43
|
+
before do
|
44
|
+
define_klass 'Foo'
|
45
|
+
define_klass 'Bar'
|
46
|
+
end
|
47
|
+
|
48
|
+
let!(:mapper) do
|
49
|
+
define_klass('MyMapper', base: Karta::Mapper).new
|
50
|
+
end
|
51
|
+
|
52
|
+
before do
|
53
|
+
allow(MyMapper).to receive(:mapping_methods).and_return([:method])
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when to is an instance' do
|
57
|
+
let(:from) { Foo.new }
|
58
|
+
let(:to) { Bar.new }
|
59
|
+
|
60
|
+
it 'calls all mapping methods with from and to \
|
61
|
+
and modifies to in place' do
|
62
|
+
expect(mapper).to receive(:send).with(:method, from, to)
|
63
|
+
mapper.map!(from: from, to: to)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when to is a class' do
|
68
|
+
let(:from) { Foo.new }
|
69
|
+
let(:to) { Bar }
|
70
|
+
|
71
|
+
it 'calls all mapping methods with from and a to instance' do
|
72
|
+
expect(mapper).to receive(:send).with(:method, from, to)
|
73
|
+
|
74
|
+
mapper.map!(from: from, to: to)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '#mapping_methods' do
|
80
|
+
let(:mapper_klass) do
|
81
|
+
define_klass 'MyMapper', base: Karta::Mapper do
|
82
|
+
def map_foo; end
|
83
|
+
|
84
|
+
def bar; end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def map_baz; end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'finds all instance methods that starts with map_' do
|
93
|
+
expect(mapper_klass.mapping_methods).to include :map_foo
|
94
|
+
expect(mapper_klass.mapping_methods).to_not include :bar
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'skips private methods' do
|
98
|
+
expect(mapper_klass.private_method_defined?(:map_baz)).to \
|
99
|
+
be true
|
100
|
+
expect(mapper_klass.mapping_methods).to_not \
|
101
|
+
include :map_baz
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '.one_to_one_mapping' do
|
106
|
+
let(:mapper) do
|
107
|
+
define_klass 'Foo', base: Karta::Mapper do
|
108
|
+
one_to_one_mapping :foo
|
109
|
+
end.new
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'defines a mapping method on the instance' do
|
113
|
+
expect(mapper).to respond_to :map_foo
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '.map' do
|
118
|
+
let(:mapper) { double('mapper') }
|
119
|
+
let(:from) { double('from') }
|
120
|
+
let(:to) { double('to') }
|
121
|
+
|
122
|
+
let(:mapper_klass) { define_klass 'Mapper', base: Karta::Mapper }
|
123
|
+
|
124
|
+
it 'instantiates self and runs the map method on the instance' do
|
125
|
+
expect(mapper_klass).to receive(:new).and_return(mapper)
|
126
|
+
expect(mapper).to receive(:map).with(from: from, to: to)
|
127
|
+
|
128
|
+
mapper_klass.map(from: from, to: to)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
data/spec/karta_spec.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Karta do
|
5
|
+
describe '.mapper_registry' do
|
6
|
+
context 'when a mapper registry has already been initialized' do
|
7
|
+
let(:mapper_registry) { double('mapper_registry') }
|
8
|
+
|
9
|
+
it 'returns the mapper registry' do
|
10
|
+
Karta.instance_variable_set('@mapper_registry', mapper_registry)
|
11
|
+
expect(Karta.mapper_registry).to eq mapper_registry
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when no mapper registry has been initialized' do
|
16
|
+
it 'initializes the mapper registry to an empty array' do
|
17
|
+
expect(Karta.instance_variable_get('@mapper_registry')).to be_nil
|
18
|
+
|
19
|
+
Karta.mapper_registry
|
20
|
+
|
21
|
+
expect(Karta.instance_variable_get('@mapper_registry')).to \
|
22
|
+
be_a Karta::MapperRegistry
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '.register_mapper' do
|
28
|
+
let(:mapper_registry) { double('mapper_registry') }
|
29
|
+
let(:mapper) { double('mapper') }
|
30
|
+
let(:from_klass) { double('from_klass') }
|
31
|
+
let(:to_klass) { double('to_klass') }
|
32
|
+
|
33
|
+
before do
|
34
|
+
expect(Karta).to receive(:mapper_registry).and_return(mapper_registry)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'registers a mapper' do
|
38
|
+
expect(mapper_registry).to receive(:register)\
|
39
|
+
.with(mapper: mapper, from_klass: from_klass, to_klass: to_klass)
|
40
|
+
|
41
|
+
Karta.register_mapper(mapper, from_klass: from_klass, to_klass: to_klass)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '.map' do
|
46
|
+
context 'when trying to map from a class' do
|
47
|
+
let(:foo) { double('foo') }
|
48
|
+
|
49
|
+
before do
|
50
|
+
define_klass 'Bar'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'raises an ArgumentError' do
|
54
|
+
expect do
|
55
|
+
Karta.map(from: Bar, to: foo)
|
56
|
+
end.to raise_error(ArgumentError, 'cannot map from a class')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when mapping to a class' do
|
61
|
+
let(:mapper) { double('mapper') }
|
62
|
+
let(:mapper_registry) { double('mapper_registry') }
|
63
|
+
let(:bar) { double('bar') }
|
64
|
+
|
65
|
+
before do
|
66
|
+
define_klass 'Foo'
|
67
|
+
allow(Karta).to receive(:mapper_registry).and_return(mapper_registry)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'finds a a mapper and maps' do
|
71
|
+
expect(mapper_registry).to receive(:find).and_return(mapper)
|
72
|
+
expect(mapper).to receive(:map).with(from: bar, to: Foo)
|
73
|
+
|
74
|
+
Karta.map(from: bar, to: Foo)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when mapping to an instance' do
|
79
|
+
let(:mapper) { double('mapper') }
|
80
|
+
let(:mapper_registry) { double('mapper_registry') }
|
81
|
+
let(:bar) { double('bar') }
|
82
|
+
let(:foo) { double('foo') }
|
83
|
+
|
84
|
+
before do
|
85
|
+
allow(Karta).to receive(:mapper_registry).and_return(mapper_registry)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'performs the mapping and returns a new instance' do
|
89
|
+
expect(mapper_registry).to receive(:find).and_return(mapper)
|
90
|
+
expect(mapper).to receive(:map).with(from: bar, to: foo)
|
91
|
+
.and_return(double('new-foo'))
|
92
|
+
|
93
|
+
result = Karta.map(from: bar, to: foo)
|
94
|
+
|
95
|
+
expect(result).to_not eq foo
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '.map!' do
|
101
|
+
context 'when trying to map from a class' do
|
102
|
+
let(:foo) { double('foo') }
|
103
|
+
|
104
|
+
before do
|
105
|
+
define_klass 'Bar'
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'raises an ArgumentError' do
|
109
|
+
expect do
|
110
|
+
Karta.map!(from: Bar, to: foo)
|
111
|
+
end.to raise_error(ArgumentError, 'cannot map from a class')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'when mapping to a class' do
|
116
|
+
let(:mapper) { double('mapper') }
|
117
|
+
let(:mapper_registry) { double('mapper_registry') }
|
118
|
+
let(:bar) { double('bar') }
|
119
|
+
|
120
|
+
before do
|
121
|
+
define_klass 'Foo'
|
122
|
+
allow(Karta).to receive(:mapper_registry).and_return(mapper_registry)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'finds a a mapper and maps' do
|
126
|
+
expect(mapper_registry).to receive(:find).and_return(mapper)
|
127
|
+
expect(mapper).to receive(:map!).with(from: bar, to: Foo)
|
128
|
+
|
129
|
+
Karta.map!(from: bar, to: Foo)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'when mapping to an instance' do
|
134
|
+
let(:mapper) { double('mapper') }
|
135
|
+
let(:mapper_registry) { double('mapper_registry') }
|
136
|
+
let(:bar) { double('bar') }
|
137
|
+
let(:foo) { double('foo') }
|
138
|
+
|
139
|
+
before do
|
140
|
+
allow(Karta).to receive(:mapper_registry).and_return(mapper_registry)
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'performs the mapping and returns the instance' do
|
144
|
+
expect(mapper_registry).to receive(:find).and_return(mapper)
|
145
|
+
expect(mapper).to receive(:map!).with(from: bar, to: foo)
|
146
|
+
.and_return(foo)
|
147
|
+
|
148
|
+
result = Karta.map!(from: bar, to: foo)
|
149
|
+
|
150
|
+
expect(result).to eq foo
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__))
|
4
|
+
|
5
|
+
require 'simplecov'
|
6
|
+
SimpleCov.start
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'rspec'
|
10
|
+
require 'byebug'
|
11
|
+
|
12
|
+
require 'karta'
|
13
|
+
|
14
|
+
Dir['spec/support/**/*.rb'].each { |f| require File.expand_path(f) }
|
15
|
+
|
16
|
+
RSpec.configure do |config|
|
17
|
+
config.after do
|
18
|
+
Karta.instance_variables.each do |ivar|
|
19
|
+
Karta.instance_variable_set(ivar, nil)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module DefineConstantMacros
|
3
|
+
# Simple class used for making flexible objects
|
4
|
+
# in tests
|
5
|
+
class FlexibleObject
|
6
|
+
def initialize(data = {})
|
7
|
+
data.each { |attr, val| instance_variable_set("@#{attr}", val) }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def define_klass(path, attrs: [], base: FlexibleObject, &block)
|
12
|
+
namespace, class_name = *constant_path(path)
|
13
|
+
klass = Class.new(base)
|
14
|
+
namespace.const_set(class_name, klass)
|
15
|
+
|
16
|
+
klass.class_eval do
|
17
|
+
attrs.each { |attr| attr_accessor attr }
|
18
|
+
end
|
19
|
+
|
20
|
+
klass.class_eval(&block) if block_given?
|
21
|
+
|
22
|
+
@defined_constants << path
|
23
|
+
klass
|
24
|
+
end
|
25
|
+
|
26
|
+
def constant_path(constant_name)
|
27
|
+
names = constant_name.split('::')
|
28
|
+
class_name = names.pop
|
29
|
+
namespace = names.inject(Object) { |acc, elem| acc.const_get(elem) }
|
30
|
+
[namespace, class_name]
|
31
|
+
end
|
32
|
+
|
33
|
+
def default_constants
|
34
|
+
@defined_constants ||= []
|
35
|
+
end
|
36
|
+
|
37
|
+
def clear_generated_constants
|
38
|
+
@defined_constants.reverse.each do |path|
|
39
|
+
namespace, class_name = *constant_path(path)
|
40
|
+
namespace.send(:remove_const, class_name)
|
41
|
+
end
|
42
|
+
|
43
|
+
@defined_constants.clear
|
44
|
+
end
|
45
|
+
|
46
|
+
RSpec.configure do |config|
|
47
|
+
config.include DefineConstantMacros
|
48
|
+
|
49
|
+
config.before do
|
50
|
+
default_constants
|
51
|
+
end
|
52
|
+
|
53
|
+
config.after do
|
54
|
+
clear_generated_constants
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
metadata
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: karta
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Samuel Nilsson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.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: '3.5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '9.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '9.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.46.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.46.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.12.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.12.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: fuubar
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.2'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.2'
|
111
|
+
description:
|
112
|
+
email:
|
113
|
+
- mail@samuelnilsson.me
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".gitignore"
|
119
|
+
- ".reek"
|
120
|
+
- ".rspec"
|
121
|
+
- ".rubocop.yml"
|
122
|
+
- ".ruby-gemset"
|
123
|
+
- ".ruby-version"
|
124
|
+
- ".yardopts"
|
125
|
+
- Gemfile
|
126
|
+
- LICENSE
|
127
|
+
- README.md
|
128
|
+
- Rakefile
|
129
|
+
- karta.gemspec
|
130
|
+
- lib/karta.rb
|
131
|
+
- lib/karta/error.rb
|
132
|
+
- lib/karta/mapper.rb
|
133
|
+
- lib/karta/mapper_registry.rb
|
134
|
+
- lib/karta/version.rb
|
135
|
+
- spec/acceptance/map_instance_to_class_spec.rb
|
136
|
+
- spec/acceptance/map_instance_to_instance_spec.rb
|
137
|
+
- spec/karta/mapper_registry_spec.rb
|
138
|
+
- spec/karta/mapper_spec.rb
|
139
|
+
- spec/karta_spec.rb
|
140
|
+
- spec/spec_helper.rb
|
141
|
+
- spec/support/macros/define_constant.rb
|
142
|
+
homepage: ''
|
143
|
+
licenses:
|
144
|
+
- MIT
|
145
|
+
metadata: {}
|
146
|
+
post_install_message:
|
147
|
+
rdoc_options: []
|
148
|
+
require_paths:
|
149
|
+
- lib
|
150
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
151
|
+
requirements:
|
152
|
+
- - ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '0'
|
155
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
requirements: []
|
161
|
+
rubyforge_project:
|
162
|
+
rubygems_version: 2.5.1
|
163
|
+
signing_key:
|
164
|
+
specification_version: 4
|
165
|
+
summary: A simple Ruby gem for creating mappers which map one object to another.
|
166
|
+
test_files:
|
167
|
+
- spec/acceptance/map_instance_to_class_spec.rb
|
168
|
+
- spec/acceptance/map_instance_to_instance_spec.rb
|
169
|
+
- spec/karta/mapper_registry_spec.rb
|
170
|
+
- spec/karta/mapper_spec.rb
|
171
|
+
- spec/karta_spec.rb
|
172
|
+
- spec/spec_helper.rb
|
173
|
+
- spec/support/macros/define_constant.rb
|