undo-serializer-active_model 0.1.0 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -5
- data/Appraisals +21 -9
- data/README.md +4 -1
- data/VERSION +1 -1
- data/gemfiles/{3.1.gemfile → activerecord_3.1.gemfile} +0 -0
- data/gemfiles/{3.2.gemfile → activerecord_3.2.gemfile} +0 -0
- data/gemfiles/{4.0.gemfile → activerecord_4.0.gemfile} +0 -0
- data/gemfiles/{4.1.gemfile → activerecord_4.1.gemfile} +0 -0
- data/gemfiles/{3.0.gemfile → activerecord_head.gemfile} +1 -1
- data/gemfiles/undo_1.0.0.gemfile +32 -0
- data/gemfiles/undo_head.gemfile +31 -0
- data/lib/undo/serializer/active_model.rb +46 -67
- data/lib/undo/serializer/active_model/connector.rb +61 -0
- data/spec/{undo/serializer/active_model_integration_spec.rb → integration/active_record_spec.rb} +36 -2
- data/spec/integration/undo_spec.rb +20 -0
- data/spec/spec_helper.rb +0 -6
- data/spec/undo/serializer/active_model/connector_spec.rb +38 -0
- data/spec/undo/serializer/active_model_spec.rb +87 -57
- data/undo-serializer-active_model.gemspec +4 -0
- metadata +72 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8576d795a1e019748983cc40635c7f08f5eae3a4
|
4
|
+
data.tar.gz: 3b8e2c05b390f9b5369d401143c34b606580f96a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c1a19f280729c09cc6e5cea07755ed7be7362e157927b5b9749ac0ba95dc8af90a00f67281a1215839d6a8741fc39c0200bbf6ab8796cd45788bb8c2c4a357d
|
7
|
+
data.tar.gz: 68fd5978c65bc28eefb1c1a33a0207873744ec5fa3b5c79ba219bba56f3ebce1d7d261eae5e92cffb62abfe834ce24cfb8a006b41211dab04df22f623a9fedc0
|
data/.travis.yml
CHANGED
@@ -11,11 +11,12 @@ rvm:
|
|
11
11
|
- jruby-head
|
12
12
|
|
13
13
|
gemfile:
|
14
|
-
- gemfiles/
|
15
|
-
- gemfiles/
|
16
|
-
- gemfiles/
|
17
|
-
- gemfiles/
|
18
|
-
- gemfiles/
|
14
|
+
- gemfiles/activerecord_3.1.gemfile
|
15
|
+
- gemfiles/activerecord_3.2.gemfile
|
16
|
+
- gemfiles/activerecord_4.0.gemfile
|
17
|
+
- gemfiles/activerecord_4.1.gemfile
|
18
|
+
- gemfiles/activerecord_head.gemfile
|
19
|
+
- gemfiles/undo_head.gemfile
|
19
20
|
|
20
21
|
matrix:
|
21
22
|
allow_failures:
|
data/Appraisals
CHANGED
@@ -1,24 +1,36 @@
|
|
1
|
-
appraise "3.
|
2
|
-
gem "activerecord", "~> 3.0.20"
|
3
|
-
gem "undo-serializer-active_model", :path => "../"
|
4
|
-
end
|
5
|
-
|
6
|
-
appraise "3.1" do
|
1
|
+
appraise "activerecord-3.1" do
|
7
2
|
gem "activerecord", "~> 3.1.12"
|
8
3
|
gem "undo-serializer-active_model", :path => "../"
|
9
4
|
end
|
10
5
|
|
11
|
-
appraise "3.2" do
|
6
|
+
appraise "activerecord-3.2" do
|
12
7
|
gem "activerecord", "~> 3.2.15"
|
13
8
|
gem "undo-serializer-active_model", :path => "../"
|
14
9
|
end
|
15
10
|
|
16
|
-
appraise "4.0" do
|
11
|
+
appraise "activerecord-4.0" do
|
17
12
|
gem "activerecord", "~> 4.0.0"
|
18
13
|
gem "undo-serializer-active_model", :path => "../"
|
19
14
|
end
|
20
15
|
|
21
|
-
appraise "4.1" do
|
16
|
+
appraise "activerecord-4.1" do
|
22
17
|
gem "activerecord", "~> 4.1.0.beta"
|
23
18
|
gem "undo-serializer-active_model", :path => "../"
|
24
19
|
end
|
20
|
+
|
21
|
+
appraise "activerecord-head" do
|
22
|
+
gem "activerecord"
|
23
|
+
gem "undo-serializer-active_model", :path => "../"
|
24
|
+
end
|
25
|
+
|
26
|
+
appraise "undo-1.0.0" do
|
27
|
+
gem "activerecord"
|
28
|
+
gem "undo", "~> 1.0.0"
|
29
|
+
gem "undo-serializer-active_model", :path => "../"
|
30
|
+
end
|
31
|
+
|
32
|
+
appraise "undo-head" do
|
33
|
+
gem "activerecord"
|
34
|
+
gem "undo"
|
35
|
+
gem "undo-serializer-active_model", :path => "../"
|
36
|
+
end
|
data/README.md
CHANGED
@@ -6,7 +6,9 @@ Undo
|
|
6
6
|
[![Gem Version](https://badge.fury.io/rb/undo-serializer-active_model.png)](http://badge.fury.io/rb/undo-serializer-active_model)
|
7
7
|
[![Code Climate](https://codeclimate.com/github/AlexParamonov/undo-serializer-active_model.png)](https://codeclimate.com/github/AlexParamonov/undo-serializer-active_model)
|
8
8
|
|
9
|
-
ActiveModel serializer for Undo gem.
|
9
|
+
ActiveModel serializer for [Undo gem](https://github.com/AlexParamonov/undo).
|
10
|
+
|
11
|
+
Does not require anything from Rails so is friendly to use with POROs.
|
10
12
|
|
11
13
|
Contents
|
12
14
|
---------
|
@@ -39,6 +41,7 @@ Most likely you'll install undo gem as well:
|
|
39
41
|
Requirements
|
40
42
|
------------
|
41
43
|
1. Ruby >= 1.9
|
44
|
+
1. Undo gem
|
42
45
|
|
43
46
|
Usage
|
44
47
|
------------
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.2
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "rake"
|
6
|
+
gem "activerecord"
|
7
|
+
gem "undo", "~> 1.0.0"
|
8
|
+
gem "undo-serializer-active_model", :path=>"../"
|
9
|
+
|
10
|
+
group :development do
|
11
|
+
gem "pry"
|
12
|
+
gem "appraisal", :github=>"thoughtbot/appraisal"
|
13
|
+
|
14
|
+
platforms :ruby_19, :ruby_20 do
|
15
|
+
gem "pry-plus"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
group :test do
|
20
|
+
gem "coveralls", :require=>false
|
21
|
+
end
|
22
|
+
|
23
|
+
group :test, :development do
|
24
|
+
gem "rspec", ">= 3.0.0.beta1"
|
25
|
+
gem "activerecord", ">= 3.0.0"
|
26
|
+
gem "activerecord-jdbcsqlite3-adapter", :platform=>:jruby
|
27
|
+
gem "sqlite3", :platform=>[:ruby, :mswin, :mingw]
|
28
|
+
gem "factory_girl"
|
29
|
+
gem "faker"
|
30
|
+
end
|
31
|
+
|
32
|
+
gemspec :path=>".././"
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "rake"
|
6
|
+
gem "activerecord"
|
7
|
+
gem "undo"
|
8
|
+
gem "undo-serializer-active_model", :path=>"../"
|
9
|
+
|
10
|
+
group :development do
|
11
|
+
gem "pry"
|
12
|
+
gem "appraisal", :github=>"thoughtbot/appraisal"
|
13
|
+
|
14
|
+
platforms :ruby_19, :ruby_20 do
|
15
|
+
gem "pry-plus"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
group :test do
|
20
|
+
gem "coveralls", :require=>false
|
21
|
+
end
|
22
|
+
|
23
|
+
group :test, :development do
|
24
|
+
gem "rspec", ">= 3.0.0.beta1"
|
25
|
+
gem "activerecord-jdbcsqlite3-adapter", :platform=>:jruby
|
26
|
+
gem "sqlite3", :platform=>[:ruby, :mswin, :mingw]
|
27
|
+
gem "factory_girl"
|
28
|
+
gem "faker"
|
29
|
+
end
|
30
|
+
|
31
|
+
gemspec :path=>".././"
|
@@ -1,8 +1,15 @@
|
|
1
|
+
require_relative "active_model/connector"
|
2
|
+
require "undo/serializer/primitive"
|
3
|
+
|
1
4
|
module Undo
|
2
5
|
module Serializer
|
3
6
|
class ActiveModel
|
4
7
|
def initialize(options = {})
|
5
|
-
|
8
|
+
@connector = self.class.connector.with options
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
"active_model"
|
6
13
|
end
|
7
14
|
|
8
15
|
def serialize(object, options = {})
|
@@ -10,71 +17,76 @@ module Undo
|
|
10
17
|
serialize record, options
|
11
18
|
end if array? object
|
12
19
|
|
13
|
-
|
20
|
+
return primitive_serializer.serialize(object) if primitive_serializer.serialize? object
|
21
|
+
serialize_object(object, options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def deserialize(input, options = {})
|
25
|
+
return input.map do |record|
|
26
|
+
deserialize record
|
27
|
+
end if array? input
|
28
|
+
|
29
|
+
return primitive_serializer.deserialize(input) if primitive_serializer.deserialize? input
|
30
|
+
deserialize_object(input)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
attr_reader :connector
|
14
35
|
|
15
|
-
|
36
|
+
def primitive_serializer
|
37
|
+
@primitive_serializer ||= Serializer::Primitive.new
|
38
|
+
end
|
39
|
+
|
40
|
+
def serialize_object(object, options)
|
41
|
+
attributes = connector.serialize_attributes object
|
42
|
+
|
43
|
+
association_names = Array(options[:include])
|
16
44
|
associations = {}
|
17
|
-
|
45
|
+
association_names.map do |association|
|
18
46
|
associations[association] = serialize(object.public_send association)
|
19
47
|
end
|
20
|
-
|
21
|
-
|
22
|
-
|
48
|
+
|
49
|
+
pk_attributes = connector.primary_key_attributes object, attributes
|
50
|
+
is_persisted = object.respond_to?(:persisted?) && object.persisted?
|
23
51
|
|
24
52
|
{
|
53
|
+
serializer: name,
|
25
54
|
attributes: attributes,
|
26
55
|
associations: associations,
|
27
56
|
meta: {
|
28
57
|
pk_attributes: pk_attributes,
|
29
58
|
class_name: object.class.name,
|
59
|
+
persisted: is_persisted,
|
30
60
|
}
|
31
61
|
}
|
32
62
|
end
|
33
63
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
load_options options
|
40
|
-
|
41
|
-
hash = symbolize_keys object
|
42
|
-
object_meta = hash.fetch :meta
|
43
|
-
associations = hash.fetch :associations
|
44
|
-
attributes = hash.fetch :attributes
|
64
|
+
def deserialize_object(object_data)
|
65
|
+
object_meta = connector.get_option :meta, object_data
|
66
|
+
associations = connector.get_option :associations, object_data
|
67
|
+
attributes = connector.get_option :attributes, object_data
|
45
68
|
|
46
69
|
with_transaction do
|
47
|
-
initialize_object(object_meta).tap do |object|
|
70
|
+
connector.initialize_object(object_meta).tap do |object|
|
71
|
+
return if object.nil?
|
72
|
+
|
48
73
|
attributes.each do |field, value|
|
49
74
|
deserialize_field object, field, value
|
50
75
|
end
|
51
76
|
|
52
|
-
# QUESTION: Set associations? object.association_name = deserialize association ?
|
53
77
|
associations.each do |(association_name, association)|
|
54
|
-
deserialize
|
78
|
+
connector.associate object, association_name, deserialize(association)
|
55
79
|
end
|
56
80
|
|
57
|
-
persist object
|
81
|
+
connector.persist object, object_meta
|
58
82
|
end
|
59
83
|
end
|
60
84
|
end
|
61
85
|
|
62
|
-
private
|
63
|
-
attr_reader :serialize_attributes_source,
|
64
|
-
:initialize_object_source,
|
65
|
-
:persist_object_source
|
66
|
-
|
67
86
|
def deserialize_field(object, field, value)
|
68
87
|
object.send "#{field}=", value # not public_send!
|
69
88
|
end
|
70
89
|
|
71
|
-
def initialize_object(meta)
|
72
|
-
object_class = constantize meta.fetch(:class_name)
|
73
|
-
pk_attributes = meta.fetch :pk_attributes
|
74
|
-
|
75
|
-
find_or_initialize object_class, pk_attributes
|
76
|
-
end
|
77
|
-
|
78
90
|
def with_transaction(&block)
|
79
91
|
if defined? ActiveRecord
|
80
92
|
ActiveRecord::Base.transaction(&block)
|
@@ -83,43 +95,10 @@ module Undo
|
|
83
95
|
end
|
84
96
|
end
|
85
97
|
|
86
|
-
def load_options(options)
|
87
|
-
@serialize_attributes_source = options.fetch :serialize_attributes, @serialize_attributes_source ||
|
88
|
-
->(object) { object.attributes }
|
89
|
-
|
90
|
-
@initialize_object_source = options.fetch :find_or_initialize, @initialize_object_source ||
|
91
|
-
->(object_class, pk_query) { object_class.respond_to?(:where) && object_class.where(pk_query).first || object_class.new(pk_query) }
|
92
|
-
|
93
|
-
@persist_object_source = options.fetch :persist, @persist_object_source ||
|
94
|
-
->(object) { object.respond_to?(:save!) && object.save! }
|
95
|
-
|
96
|
-
@primary_key_fields = options.fetch :primary_key, @primary_key_fields || :id
|
97
|
-
end
|
98
|
-
|
99
|
-
def primary_key_fields
|
100
|
-
Array(@primary_key_fields)
|
101
|
-
end
|
102
|
-
|
103
|
-
def serialize_attributes(*args); serialize_attributes_source.call(*args) end
|
104
|
-
def find_or_initialize(*args); initialize_object_source.call(*args) end
|
105
|
-
def persist(*args); persist_object_source.call(*args) end
|
106
|
-
|
107
98
|
def array?(object)
|
108
99
|
object.respond_to?(:map) && ! object.is_a?(Hash)
|
109
100
|
end
|
110
|
-
# ActiveSupport methods
|
111
|
-
def symbolize_keys(hash)
|
112
|
-
hash.each_with_object({}) do |(key, value), result|
|
113
|
-
new_key = key.is_a?(String) ? key.to_sym : key
|
114
|
-
new_value = value.is_a?(Hash) ? symbolize_keys(value) : value
|
115
101
|
|
116
|
-
result[new_key] = new_value
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
def constantize(class_name)
|
121
|
-
class_name.split('::').inject(Kernel) { |object, name| object = object.const_get(name); object }
|
122
|
-
end
|
123
102
|
end
|
124
103
|
end
|
125
104
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "virtus"
|
2
|
+
|
3
|
+
module Undo
|
4
|
+
module Serializer
|
5
|
+
class ActiveModel
|
6
|
+
def self.connector
|
7
|
+
@config ||= Connector.new
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
class Connector
|
12
|
+
include Virtus.value_object
|
13
|
+
values do
|
14
|
+
attribute :attribute_serializer, Proc, default: proc { -> object { object.attributes } }
|
15
|
+
attribute :persister, Proc, default: proc { -> object { object.respond_to?(:save!) && object.save! } }
|
16
|
+
attribute :primary_key_fetcher, Proc, default: proc { -> object { object.respond_to?(:primary_key) && object.primary_key || :id }}
|
17
|
+
attribute :associator, Proc, default: proc { -> object, association_name, value { setter = "#{association_name}="; object.respond_to?(setter) && object.send(setter, value) }}
|
18
|
+
attribute :object_initializer, Proc, default: proc { -> object_class, attributes { object_class.respond_to?(:where) && object_class.where(attributes).first || object_class.new(attributes) }}
|
19
|
+
end
|
20
|
+
|
21
|
+
def primary_key_attributes(object, attributes)
|
22
|
+
fields = Array(primary_key_fetcher.call(object)).map(&:to_sym)
|
23
|
+
|
24
|
+
fields.each_with_object({}) do |field, pk_attributes|
|
25
|
+
pk_attributes[field] = attributes[field] || attributes[field.to_s]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize_object(meta)
|
30
|
+
object_class = constantize get_option :class_name, meta
|
31
|
+
pk_attributes = get_option :pk_attributes, meta
|
32
|
+
|
33
|
+
object_initializer.call object_class, pk_attributes
|
34
|
+
end
|
35
|
+
|
36
|
+
def persist(object, object_meta)
|
37
|
+
persister.call object unless [false, nil, 0, "false"].include? get_option :persisted, object_meta
|
38
|
+
end
|
39
|
+
|
40
|
+
def associate(object, association, associations)
|
41
|
+
associator.call object, association, associations
|
42
|
+
end
|
43
|
+
|
44
|
+
def serialize_attributes(object)
|
45
|
+
attribute_serializer.call(object) || {}
|
46
|
+
end
|
47
|
+
|
48
|
+
def constantize(class_name)
|
49
|
+
class_name.split('::').inject(Kernel) { |object, name| object = object.const_get(name); object }
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_option(name, options)
|
53
|
+
options.fetch name.to_sym do
|
54
|
+
options.fetch name.to_s
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/spec/{undo/serializer/active_model_integration_spec.rb → integration/active_record_spec.rb}
RENAMED
@@ -18,16 +18,37 @@ describe Undo::Serializer::ActiveModel do
|
|
18
18
|
expect(restored_user).to be_persisted
|
19
19
|
end
|
20
20
|
|
21
|
+
describe "not persisted object" do
|
22
|
+
let(:user) { build :user }
|
23
|
+
|
24
|
+
it "restores object" do
|
25
|
+
hash = serializer.serialize user
|
26
|
+
restored_user = serializer.deserialize hash
|
27
|
+
|
28
|
+
expect(restored_user.attributes).to eq user.attributes
|
29
|
+
expect(restored_user).not_to be_persisted
|
30
|
+
end
|
31
|
+
|
32
|
+
it "restores provided associations" do
|
33
|
+
roles = build_list :role, 3
|
34
|
+
user.roles = roles
|
35
|
+
hash = serializer.serialize user, include: :roles
|
36
|
+
|
37
|
+
restored_user = serializer.deserialize hash
|
38
|
+
|
39
|
+
expect(restored_user).not_to be_persisted
|
40
|
+
expect(restored_user.roles.map(&:attributes)).to match roles.map(&:attributes)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
21
44
|
describe "associations" do
|
22
45
|
it "restores provided associations" do
|
23
46
|
roles = create_list :role, 3, user: user
|
24
47
|
hash = serializer.serialize user, include: :roles
|
25
48
|
user.delete
|
26
|
-
Role.delete_all # HACK for ActiveRecord 3.0
|
27
49
|
|
28
50
|
restored_user = serializer.deserialize hash
|
29
51
|
|
30
|
-
restored_user.reload # HACK for ActiveRecord 3.0
|
31
52
|
expect(restored_user).to eq user
|
32
53
|
expect(restored_user.roles).to eq roles
|
33
54
|
end
|
@@ -54,4 +75,17 @@ describe Undo::Serializer::ActiveModel do
|
|
54
75
|
expect(restored_users).to eq users
|
55
76
|
end
|
56
77
|
end
|
78
|
+
|
79
|
+
describe "json store" do
|
80
|
+
it "restores object" do
|
81
|
+
hash = serializer.serialize user
|
82
|
+
hash = hash.to_json
|
83
|
+
user.delete
|
84
|
+
restored_user = serializer.deserialize JSON.load(hash)
|
85
|
+
|
86
|
+
expect(restored_user).to eq user
|
87
|
+
expect(user).not_to be_persisted
|
88
|
+
expect(restored_user).to be_persisted
|
89
|
+
end
|
90
|
+
end
|
57
91
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "undo"
|
3
|
+
require "support/active_record"
|
4
|
+
require "user"
|
5
|
+
require 'undo/integration/shared_undo_integration_examples.rb'
|
6
|
+
|
7
|
+
Undo.configure do |config|
|
8
|
+
config.serializer = Undo::Serializer::ActiveModel.new
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Undo do
|
12
|
+
let(:object) { create :user }
|
13
|
+
|
14
|
+
include_examples "undo integration"
|
15
|
+
|
16
|
+
it "stores and restores symbols" do
|
17
|
+
uuid = subject.store :foo
|
18
|
+
expect(subject.restore uuid).to eq :foo
|
19
|
+
end
|
20
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Undo::Serializer::ActiveModel::Connector do
|
4
|
+
let(:object) { double :object }
|
5
|
+
let(:serializer) { subject }
|
6
|
+
|
7
|
+
describe "#primary_key_attributes" do
|
8
|
+
let(:attributes) { { uuid: "identifier", foo: :bar, "hello" => "world" } }
|
9
|
+
|
10
|
+
it "extracts object primary key attributes" do
|
11
|
+
expect(object).to receive(:primary_key) { "uuid" }
|
12
|
+
|
13
|
+
expect(serializer.primary_key_attributes object, attributes).to eq uuid: "identifier"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "redefines primary key attribute names by primary_key_fetcher" do
|
17
|
+
serializer = described_class.new primary_key_fetcher: -> object { %w[hello uuid] }
|
18
|
+
|
19
|
+
expect(serializer.primary_key_attributes object, attributes).to eq ({
|
20
|
+
hello: "world",
|
21
|
+
uuid: "identifier"
|
22
|
+
})
|
23
|
+
end
|
24
|
+
|
25
|
+
it "use nil value when no primary_key attributes available" do
|
26
|
+
allow(object).to receive(:primary_key) { "unknown" }
|
27
|
+
|
28
|
+
expect(serializer.primary_key_attributes object, attributes).to eq unknown: nil
|
29
|
+
end
|
30
|
+
|
31
|
+
it "accepts string and symbol as uuid key" do
|
32
|
+
allow(object).to receive(:primary_key) { "uuid" }
|
33
|
+
expect(serializer.primary_key_attributes object, attributes).to eq uuid: "identifier"
|
34
|
+
allow(object).to receive(:primary_key) { :uuid }
|
35
|
+
expect(serializer.primary_key_attributes object, attributes).to eq uuid: "identifier"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,73 +1,103 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
+
class FooBarTestObject < OpenStruct
|
4
|
+
def attributes; marshal_dump end
|
5
|
+
end
|
6
|
+
|
3
7
|
describe Undo::Serializer::ActiveModel do
|
4
8
|
subject { described_class }
|
5
9
|
let(:serializer) { subject.new }
|
6
|
-
let(:
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
expect(attribute_serializer).to receive(:call).with(object)
|
27
|
-
serializer.serialize object
|
10
|
+
let(:object_class) { FooBarTestObject }
|
11
|
+
let(:object) { FooBarTestObject.new }
|
12
|
+
|
13
|
+
describe "options" do
|
14
|
+
describe "attribute_serializer" do
|
15
|
+
let(:attribute_serializer) { double :attribute_serializer }
|
16
|
+
let(:serializer) { subject.new attribute_serializer: attribute_serializer }
|
17
|
+
|
18
|
+
it "uses provided attribute serialization" do
|
19
|
+
expect(attribute_serializer).to receive(:call).with(object) { {} }
|
20
|
+
serializer.serialize object
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when nil" do
|
24
|
+
let(:attribute_serializer) { proc { nil } }
|
25
|
+
|
26
|
+
it "does not raise" do
|
27
|
+
expect { serializer.serialize object }.not_to raise_error
|
28
|
+
end
|
29
|
+
end
|
28
30
|
end
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
serializer
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
describe "object_initializer" do
|
33
|
+
let(:initializer) { double :initializer }
|
34
|
+
let(:serializer) { subject.new object_initializer: initializer }
|
35
|
+
before do
|
36
|
+
object.id = 1
|
37
|
+
object.foo = :bar
|
38
|
+
end
|
39
|
+
|
40
|
+
it "uses provided initializer" do
|
41
|
+
hash = serializer.serialize object
|
42
|
+
expect(initializer).to receive(:call).with(object.class, id: 1) { double.as_null_object }
|
43
|
+
serializer.deserialize hash
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when nil" do
|
47
|
+
let(:initializer) { proc { nil } }
|
48
|
+
|
49
|
+
it "returns nil" do
|
50
|
+
hash = serializer.serialize object
|
51
|
+
expect(serializer.deserialize hash).to eq nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it "does not assigns attributes" do
|
55
|
+
hash = serializer.serialize object
|
56
|
+
expect{ serializer.deserialize hash }.not_to raise_error
|
57
|
+
expect(serializer.deserialize hash).to eq nil
|
58
|
+
end
|
59
|
+
end
|
37
60
|
end
|
38
61
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
allow(deserializer).to receive(:call) { object.as_null_object }
|
44
|
-
serializer = subject.new persist: persister, find_or_initialize: deserializer
|
45
|
-
|
46
|
-
hash = serializer.serialize object
|
47
|
-
expect(persister).to receive(:call).with(object)
|
48
|
-
serializer.deserialize hash
|
49
|
-
end
|
50
|
-
end
|
62
|
+
describe "assign associations" do
|
63
|
+
it "uses provided way of assigning associations" do
|
64
|
+
associated_object = object_class.new name: "association"
|
65
|
+
object.association_name = [associated_object]
|
51
66
|
|
52
|
-
|
53
|
-
|
54
|
-
attribute_serializer = double :attribute_serializer
|
55
|
-
serializer = subject.new
|
67
|
+
associator = double :associator
|
68
|
+
serializer = subject.new associator: associator
|
56
69
|
|
57
|
-
|
58
|
-
|
59
|
-
|
70
|
+
hash = serializer.serialize object, include: :association_name
|
71
|
+
expect(associator).to receive(:call) do |object, name, associations|
|
72
|
+
expect(associations.map(&:name)).to eq [associated_object.name]
|
73
|
+
end
|
74
|
+
serializer.deserialize hash
|
75
|
+
end
|
60
76
|
end
|
61
77
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
78
|
+
describe "persist object" do
|
79
|
+
it "uses provided way of persisting object" do
|
80
|
+
allow(object).to receive(:persisted?) { true }
|
81
|
+
persister = double :persister
|
82
|
+
serializer = subject.new persister: persister,
|
83
|
+
object_initializer: proc { object }
|
84
|
+
|
85
|
+
hash = serializer.serialize object
|
86
|
+
expect(persister).to receive(:call).with(object)
|
87
|
+
serializer.deserialize hash
|
88
|
+
end
|
89
|
+
|
90
|
+
it "does not persist new record objects" do
|
91
|
+
persister = double :persister
|
92
|
+
serializer = subject.new persister: persister,
|
93
|
+
object_initializer: proc { object }
|
94
|
+
|
95
|
+
allow(object).to receive(:persisted?) { false }
|
96
|
+
|
97
|
+
hash = serializer.serialize object
|
98
|
+
expect(persister).not_to receive(:call)
|
99
|
+
serializer.deserialize hash
|
100
|
+
end
|
70
101
|
end
|
71
102
|
end
|
72
|
-
|
73
103
|
end
|
@@ -17,5 +17,9 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
+
spec.add_dependency 'undo', '~> 1.0'
|
21
|
+
spec.add_dependency 'undo-serializer-primitive', '~> 0.1'
|
22
|
+
spec.add_dependency 'virtus', '~> 1.0'
|
20
23
|
spec.add_development_dependency 'bundler', '~> 1.0'
|
24
|
+
spec.add_development_dependency "rspec", ">= 3.0.0.beta1"
|
21
25
|
end
|
metadata
CHANGED
@@ -1,15 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: undo-serializer-active_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Paramonov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-05-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: undo
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: undo-serializer-primitive
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: virtus
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
13
55
|
- !ruby/object:Gem::Dependency
|
14
56
|
name: bundler
|
15
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,6 +66,20 @@ dependencies:
|
|
24
66
|
- - "~>"
|
25
67
|
- !ruby/object:Gem::Version
|
26
68
|
version: '1.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 3.0.0.beta1
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 3.0.0.beta1
|
27
83
|
description: ActiveModel serializer for Undo gem. Does not require anything from Rails
|
28
84
|
so is friendly to use with POROs.
|
29
85
|
email:
|
@@ -44,12 +100,17 @@ files:
|
|
44
100
|
- README.md
|
45
101
|
- Rakefile
|
46
102
|
- VERSION
|
47
|
-
- gemfiles/
|
48
|
-
- gemfiles/
|
49
|
-
- gemfiles/
|
50
|
-
- gemfiles/
|
51
|
-
- gemfiles/
|
103
|
+
- gemfiles/activerecord_3.1.gemfile
|
104
|
+
- gemfiles/activerecord_3.2.gemfile
|
105
|
+
- gemfiles/activerecord_4.0.gemfile
|
106
|
+
- gemfiles/activerecord_4.1.gemfile
|
107
|
+
- gemfiles/activerecord_head.gemfile
|
108
|
+
- gemfiles/undo_1.0.0.gemfile
|
109
|
+
- gemfiles/undo_head.gemfile
|
52
110
|
- lib/undo/serializer/active_model.rb
|
111
|
+
- lib/undo/serializer/active_model/connector.rb
|
112
|
+
- spec/integration/active_record_spec.rb
|
113
|
+
- spec/integration/undo_spec.rb
|
53
114
|
- spec/spec_helper.rb
|
54
115
|
- spec/support/active_record.rb
|
55
116
|
- spec/support/active_record/role.rb
|
@@ -57,7 +118,7 @@ files:
|
|
57
118
|
- spec/support/active_record/user.rb
|
58
119
|
- spec/support/ci_helper.rb
|
59
120
|
- spec/support/factories.rb
|
60
|
-
- spec/undo/serializer/
|
121
|
+
- spec/undo/serializer/active_model/connector_spec.rb
|
61
122
|
- spec/undo/serializer/active_model_spec.rb
|
62
123
|
- undo-serializer-active_model.gemspec
|
63
124
|
homepage: http://github.com/AlexParamonov/undo-serializer-active_model
|
@@ -86,6 +147,8 @@ specification_version: 4
|
|
86
147
|
summary: ActiveModel serializer for Undo gem. Does not require anything from Rails
|
87
148
|
so is friendly to use with POROs.
|
88
149
|
test_files:
|
150
|
+
- spec/integration/active_record_spec.rb
|
151
|
+
- spec/integration/undo_spec.rb
|
89
152
|
- spec/spec_helper.rb
|
90
153
|
- spec/support/active_record.rb
|
91
154
|
- spec/support/active_record/role.rb
|
@@ -93,5 +156,5 @@ test_files:
|
|
93
156
|
- spec/support/active_record/user.rb
|
94
157
|
- spec/support/ci_helper.rb
|
95
158
|
- spec/support/factories.rb
|
96
|
-
- spec/undo/serializer/
|
159
|
+
- spec/undo/serializer/active_model/connector_spec.rb
|
97
160
|
- spec/undo/serializer/active_model_spec.rb
|