ar_doc_store 1.0.5 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ar_doc_store.gemspec +3 -3
- data/lib/ar_doc_store.rb +30 -28
- data/lib/ar_doc_store/attributes/array.rb +25 -0
- data/lib/ar_doc_store/attributes/base.rb +72 -0
- data/lib/ar_doc_store/attributes/boolean.rb +17 -0
- data/lib/ar_doc_store/attributes/callback_support.rb +21 -0
- data/lib/ar_doc_store/attributes/date.rb +21 -0
- data/lib/ar_doc_store/attributes/datetime.rb +21 -0
- data/lib/ar_doc_store/attributes/decimal.rb +17 -0
- data/lib/ar_doc_store/attributes/embeds_base.rb +35 -0
- data/lib/ar_doc_store/attributes/embeds_many.rb +143 -0
- data/lib/ar_doc_store/{attribute_types/embeds_one_attribute.rb → attributes/embeds_one.rb} +25 -30
- data/lib/ar_doc_store/{attribute_types/enumeration_attribute.rb → attributes/enumeration.rb} +2 -6
- data/lib/ar_doc_store/{attribute_types/float_attribute.rb → attributes/float.rb} +5 -8
- data/lib/ar_doc_store/{attribute_types/integer_attribute.rb → attributes/integer.rb} +5 -8
- data/lib/ar_doc_store/attributes/string.rb +13 -0
- data/lib/ar_doc_store/embeddable_model.rb +51 -75
- data/lib/ar_doc_store/embedded_collection.rb +14 -0
- data/lib/ar_doc_store/embedding.rb +0 -2
- data/lib/ar_doc_store/model.rb +18 -8
- data/lib/ar_doc_store/storage.rb +4 -127
- data/lib/ar_doc_store/types/embeds_many.rb +52 -0
- data/lib/ar_doc_store/types/embeds_one.rb +42 -0
- data/lib/ar_doc_store/version.rb +1 -1
- data/test/{attribute_types → attributes}/array_attribute_test.rb +5 -1
- data/test/{attribute_types → attributes}/boolean_attribute_test.rb +7 -1
- data/test/attributes/date_attribute_test.rb +52 -0
- data/test/attributes/datetime_attribute_test.rb +54 -0
- data/test/attributes/decimal_attribute_test.rb +38 -0
- data/test/attributes/embeds_many_attribute_test.rb +78 -0
- data/test/attributes/embeds_one_attribute_test.rb +80 -0
- data/test/{attribute_types → attributes}/enumeration_attribute_test.rb +5 -0
- data/test/{attribute_types → attributes}/float_attribute_test.rb +6 -1
- data/test/attributes/integer_attribute_test.rb +63 -0
- data/test/{attribute_types → attributes}/string_attribute_test.rb +6 -0
- data/test/test_helper.rb +22 -94
- metadata +57 -35
- data/lib/ar_doc_store/attribute_types/array_attribute.rb +0 -30
- data/lib/ar_doc_store/attribute_types/base_attribute.rb +0 -61
- data/lib/ar_doc_store/attribute_types/boolean_attribute.rb +0 -25
- data/lib/ar_doc_store/attribute_types/datetime_attribute.rb +0 -17
- data/lib/ar_doc_store/attribute_types/embeds_many_attribute.rb +0 -165
- data/lib/ar_doc_store/attribute_types/string_attribute.rb +0 -17
- data/lib/ar_doc_store/attribute_types/uuid_attribute.rb +0 -30
- data/test/attribute_types/datetime_attribute_test.rb +0 -35
- data/test/attribute_types/integer_attribute_test.rb +0 -33
- data/test/originals/dirty_attributes_test.rb +0 -35
- data/test/originals/embedded_model_attribute_test.rb +0 -23
- data/test/originals/embedding_test.rb +0 -82
@@ -0,0 +1,52 @@
|
|
1
|
+
module ArDocStore
|
2
|
+
module Types
|
3
|
+
class EmbedsMany < ActiveModel::Type::Value
|
4
|
+
attr_accessor :class_name
|
5
|
+
|
6
|
+
def initialize(class_name)
|
7
|
+
@class_name = class_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def cast(values)
|
11
|
+
@class_name = @class_name.constantize if class_name.respond_to?(:constantize)
|
12
|
+
collection = EmbeddedCollection.new
|
13
|
+
values && values.each do |value|
|
14
|
+
collection << if value.nil?
|
15
|
+
value
|
16
|
+
elsif value.kind_of?(class_name)
|
17
|
+
value
|
18
|
+
elsif value.respond_to?(:to_hash)
|
19
|
+
class_name.new value
|
20
|
+
else
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
collection
|
25
|
+
end
|
26
|
+
|
27
|
+
def serialize(values)
|
28
|
+
if values.nil?
|
29
|
+
nil
|
30
|
+
elsif values.respond_to?(:each)
|
31
|
+
values.map { |value|
|
32
|
+
if value.nil?
|
33
|
+
nil
|
34
|
+
elsif value.kind_of?(class_name)
|
35
|
+
value.serializable_hash
|
36
|
+
else
|
37
|
+
cast(value).serializable_hash
|
38
|
+
end
|
39
|
+
}.compact
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def deserialize(value)
|
44
|
+
cast(value)
|
45
|
+
end
|
46
|
+
|
47
|
+
def changed_in_place?(raw_old_value, new_value)
|
48
|
+
serialize(new_value) != raw_old_value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module ArDocStore
|
2
|
+
module Types
|
3
|
+
class EmbedsOne < ActiveModel::Type::Value
|
4
|
+
attr_accessor :class_name
|
5
|
+
|
6
|
+
def initialize(class_name)
|
7
|
+
@class_name = class_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def cast(value)
|
11
|
+
@class_name = @class_name.constantize if class_name.respond_to?(:constantize)
|
12
|
+
if value.nil?
|
13
|
+
value
|
14
|
+
elsif value.kind_of?(class_name)
|
15
|
+
value
|
16
|
+
elsif value.respond_to?(:to_hash)
|
17
|
+
class_name.new value
|
18
|
+
else
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def serialize(value)
|
24
|
+
if value.nil?
|
25
|
+
nil
|
26
|
+
elsif value.kind_of?(class_name)
|
27
|
+
value.serializable_hash
|
28
|
+
else
|
29
|
+
cast(value).serializable_hash
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def deserialize(value)
|
34
|
+
cast(value)
|
35
|
+
end
|
36
|
+
|
37
|
+
def changed_in_place?(raw_old_value, new_value)
|
38
|
+
serialize(new_value) != raw_old_value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/ar_doc_store/version.rb
CHANGED
@@ -21,5 +21,9 @@ class ArrayAttributeTest < MiniTest::Test
|
|
21
21
|
assert_equal true, b.architects?
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
def test_persistence
|
25
|
+
b = Building.new name: 'Test', stories: 5, architects: %W{Bob John}
|
26
|
+
assert b.save
|
27
|
+
assert_equal b.architects, Building.find(b.id).architects
|
28
|
+
end
|
25
29
|
end
|
@@ -32,5 +32,11 @@ class BooleanAttributeTest < MiniTest::Test
|
|
32
32
|
b.finished = '1'
|
33
33
|
assert_equal true, b.finished
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
|
+
def test_persistence
|
37
|
+
b = Building.new name: 'Test', finished: true
|
38
|
+
assert b.save
|
39
|
+
assert_equal true, Building.find(b.id).finished?
|
40
|
+
end
|
41
|
+
|
36
42
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative './../test_helper'
|
2
|
+
|
3
|
+
class DateAttributeTest < MiniTest::Test
|
4
|
+
|
5
|
+
def test_attribute_on_model_init
|
6
|
+
finished_on = Date.new(1984, 3, 6)
|
7
|
+
b = Building.new finished_on: finished_on
|
8
|
+
assert finished_on == b.finished_on
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_attribute_on_existing_model
|
12
|
+
finished_on = Date.new(1984, 3, 6)
|
13
|
+
b = Building.new
|
14
|
+
b.finished_on = finished_on
|
15
|
+
assert finished_on == b.finished_on
|
16
|
+
assert b.finished_on_changed?
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_question_mark_method
|
20
|
+
finished_on = Date.new(1984, 3, 6)
|
21
|
+
b = Building.new finished_on: finished_on
|
22
|
+
assert_equal true, b.finished_on?
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_conversion
|
26
|
+
finished_on = Date.new(1984, 3, 6)
|
27
|
+
b = Building.new finished_on: finished_on.to_s
|
28
|
+
assert_kind_of Date, b.finished_on
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_no_op
|
32
|
+
b = Building.new
|
33
|
+
assert_nil b.finished_on
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_multiparameter_assignment
|
37
|
+
finished_on = {
|
38
|
+
"finished_on(2i)" => "4",
|
39
|
+
"finished_on(1i)" => "2014",
|
40
|
+
"finished_on(3i)" => "21",
|
41
|
+
}
|
42
|
+
b = Building.new finished_on
|
43
|
+
assert_equal Date.new(2014, 4, 21), b.finished_on
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_persistence
|
47
|
+
finished_on = Date.new(2014, 4, 21)
|
48
|
+
b = Building.new finished_on: finished_on
|
49
|
+
assert b.save
|
50
|
+
assert_equal Date.new(2014, 4, 21), Building.find(b.id).finished_on
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative './../test_helper'
|
2
|
+
|
3
|
+
class DatetimeAttributeTest < MiniTest::Test
|
4
|
+
|
5
|
+
def test_attribute_on_model_init
|
6
|
+
inspected_at = Time.new(1984, 3, 6)
|
7
|
+
b = Building.new inspected_at: inspected_at
|
8
|
+
assert inspected_at == b.inspected_at
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_attribute_on_existing_model
|
12
|
+
inspected_at = Time.new(1984, 3, 6)
|
13
|
+
b = Building.new
|
14
|
+
b.inspected_at = inspected_at
|
15
|
+
assert inspected_at == b.inspected_at
|
16
|
+
assert b.inspected_at_changed?
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_question_mark_method
|
20
|
+
inspected_at = Time.new(1984, 3, 6)
|
21
|
+
b = Building.new inspected_at: inspected_at
|
22
|
+
assert_equal true, b.inspected_at?
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_conversion
|
26
|
+
inspected_at = Time.new(1984, 3, 6)
|
27
|
+
b = Building.new inspected_at: inspected_at.to_s
|
28
|
+
assert_kind_of Time, b.inspected_at
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_no_op
|
32
|
+
b = Building.new
|
33
|
+
assert_nil b.inspected_at
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_multiparameter_assignment
|
37
|
+
inspected_at = {
|
38
|
+
"inspected_at(2i)" => "4",
|
39
|
+
"inspected_at(4i)" => "12",
|
40
|
+
"inspected_at(1i)" => "2014",
|
41
|
+
"inspected_at(3i)" => "21",
|
42
|
+
"inspected_at(5i)" => "53",
|
43
|
+
}
|
44
|
+
b = Building.new inspected_at
|
45
|
+
assert_equal DateTime.new(2014, 4, 21, 12, 53), b.inspected_at
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_persistence
|
49
|
+
inspected_at = DateTime.new(2014, 4, 21, 12, 53)
|
50
|
+
b = Building.new inspected_at: inspected_at
|
51
|
+
assert b.save
|
52
|
+
assert_equal DateTime.new(2014, 4, 21, 12, 53), Building.find(b.id).inspected_at
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative './../test_helper'
|
2
|
+
|
3
|
+
class DecimalAttributeTest < MiniTest::Test
|
4
|
+
|
5
|
+
def test_attribute_on_model_init
|
6
|
+
b = Building.new cost: 5.42
|
7
|
+
assert_equal 5.42, b.cost
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_attribute_on_existing_model
|
11
|
+
b = Building.new
|
12
|
+
b.cost = 5.42
|
13
|
+
assert_equal 5.42, b.cost
|
14
|
+
assert b.cost_changed?
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_question_mark_method
|
18
|
+
b = Building.new cost: 5.42
|
19
|
+
assert_equal true, b.cost?
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_type_conversion_on_init
|
23
|
+
b = Building.new cost: '5.42'
|
24
|
+
assert_equal 5.42, b.cost
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_type_conversion_on_existing
|
28
|
+
b = Building.new
|
29
|
+
b.cost = '5.42'
|
30
|
+
assert_equal 5.42, b.cost
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_persistence
|
34
|
+
b = Building.new name: 'Test', cost: 87.4
|
35
|
+
assert b.save
|
36
|
+
assert_equal 87.4, Building.find(b.id).cost.to_f
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require_relative './../test_helper'
|
2
|
+
|
3
|
+
class EmbedsManyAttributeTest < MiniTest::Test
|
4
|
+
|
5
|
+
def test_initialized_on_model_init
|
6
|
+
r = Restroom.new name: 'Foo'
|
7
|
+
b = Building.new restrooms: [r]
|
8
|
+
assert_equal r.name, b.restrooms.first.name
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_hash_on_model_init
|
12
|
+
r = { name: 'Foo' }
|
13
|
+
b = Building.new restrooms: [r]
|
14
|
+
assert_equal r[:name], b.restrooms.first.name
|
15
|
+
assert_equal b, b.restrooms.first.parent.parent
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_persistence
|
19
|
+
r = { name: 'Foo' }
|
20
|
+
b = Building.new restrooms: [r]
|
21
|
+
b.save
|
22
|
+
assert_equal r[:name], Building.find(b.id).restrooms.first.name
|
23
|
+
assert_equal b, b.restrooms.first.parent.parent
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_build_method
|
27
|
+
b = Building.new
|
28
|
+
b.build_restroom name: 'Test'
|
29
|
+
assert_equal 'Test', b.restrooms.first.name
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_ensure_method
|
33
|
+
b = Building.new
|
34
|
+
b.ensure_restroom
|
35
|
+
assert !!b.restrooms.first
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_autosave
|
39
|
+
a = Building.new name: 'Foo'
|
40
|
+
r = a.build_restroom
|
41
|
+
r.name = 'Bar'
|
42
|
+
a.save
|
43
|
+
b = Building.find(a.id)
|
44
|
+
assert_equal r.name, b.restrooms.first.name
|
45
|
+
b.restrooms.first.name = 'Baz'
|
46
|
+
b.save
|
47
|
+
c = Building.find(a.id)
|
48
|
+
assert_equal 'Baz', c.restrooms.first.name
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_attributes_method
|
52
|
+
a = Building.new name: 'Foo', restrooms_attributes: { 0 => { name: 'Bar' } }
|
53
|
+
assert_equal 'Bar', a.restrooms.first.name
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_dirty_on_init
|
57
|
+
b = Building.new name: 'Foo', restrooms: [{ name: 'Foo' }]
|
58
|
+
assert b.restrooms.first.name_changed?
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_dirty_persisted
|
62
|
+
a = Building.create name: 'Foo', restrooms: [{ name: 'Foo' }]
|
63
|
+
b = Building.find a.id
|
64
|
+
assert !b.restrooms.first.name_changed?
|
65
|
+
b.restrooms.first.name = 'Bar'
|
66
|
+
assert_equal 'Bar', b.restrooms.first.name
|
67
|
+
assert b.restrooms.first.name_changed?
|
68
|
+
assert_equal 'Foo', b.restrooms.first.name_was
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_rejects_all_blank
|
72
|
+
a = Building.new name: 'Foo'
|
73
|
+
a.restrooms_attributes = { 0 => { name: nil }}
|
74
|
+
a.save
|
75
|
+
b = Building.find a.id
|
76
|
+
assert_equal 0, b.restrooms.size
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require_relative './../test_helper'
|
2
|
+
|
3
|
+
class EmbedsOneAttributeTest < MiniTest::Test
|
4
|
+
|
5
|
+
def test_initialized_on_model_init
|
6
|
+
entrance = Entrance.new name: 'Foo'
|
7
|
+
b = Building.new entrance: entrance
|
8
|
+
assert_equal entrance.name, b.entrance.name
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_hash_on_model_init
|
12
|
+
entrance = { name: 'Foo' }
|
13
|
+
b = Building.new entrance: entrance
|
14
|
+
assert_equal entrance[:name], b.entrance.name
|
15
|
+
assert_equal b, b.entrance.parent
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_persistence
|
19
|
+
entrance = { name: 'Foo' }
|
20
|
+
b = Building.new entrance: entrance
|
21
|
+
b.save
|
22
|
+
assert_equal entrance[:name], Building.find(b.id).entrance.name
|
23
|
+
assert_equal b, b.entrance.parent
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_build_method
|
27
|
+
b = Building.new
|
28
|
+
b.build_entrance name: 'Test'
|
29
|
+
assert_equal 'Test', b.entrance.name
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_ensure_method
|
33
|
+
b = Building.new
|
34
|
+
b.ensure_entrance
|
35
|
+
assert !!b.entrance
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_autosave
|
39
|
+
a = Building.new name: 'Foo'
|
40
|
+
a.build_entrance
|
41
|
+
a.entrance.name = 'Bar'
|
42
|
+
a.save
|
43
|
+
b = Building.find(a.id)
|
44
|
+
assert_equal a.entrance.name, b.entrance.name
|
45
|
+
b.entrance.name = 'Baz'
|
46
|
+
assert b.entrance_changed?
|
47
|
+
assert b.entrance.name_changed?
|
48
|
+
assert_equal b.data['entrance']['name'], b.entrance.name
|
49
|
+
b.save
|
50
|
+
c = Building.find(a.id)
|
51
|
+
assert_equal b.data, c.data
|
52
|
+
assert_equal 'Baz', c.entrance.name
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_attributes_method
|
56
|
+
a = Building.new name: 'Foo', entrance_attributes: { name: 'Bar' }
|
57
|
+
assert_equal 'Bar', a.entrance.name
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_class_name_option
|
61
|
+
a = Building.new main_entrance: { name: 'Foo' }
|
62
|
+
assert a.main_entrance.is_a?(Entrance)
|
63
|
+
assert_equal 'Foo', a.main_entrance.name
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_dirty_on_init
|
67
|
+
b = Building.new name: 'Foo', entrance: { name: 'Foo' }
|
68
|
+
assert b.entrance.name_changed?
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_dirty_persisted
|
72
|
+
a = Building.create name: 'Foo', entrance: { name: 'Foo' }
|
73
|
+
b = Building.find a.id
|
74
|
+
assert b.entrance.id.present?
|
75
|
+
assert !b.entrance.name_changed?
|
76
|
+
b.entrance.name = 'Bar'
|
77
|
+
assert b.entrance.name_changed?
|
78
|
+
assert_equal 'Foo', b.entrance.name_was
|
79
|
+
end
|
80
|
+
end
|
@@ -59,4 +59,9 @@ class EnumerationAttributeTest < MiniTest::Test
|
|
59
59
|
assert_equal true, b.strict_multi_enumeration?
|
60
60
|
end
|
61
61
|
|
62
|
+
def test_persistence
|
63
|
+
b = Building.new name: 'Test', strict_multi_enumeration: %w{glad bad}
|
64
|
+
assert b.save
|
65
|
+
assert_equal %w{glad bad}, Building.find(b.id).strict_multi_enumeration
|
66
|
+
end
|
62
67
|
end
|
@@ -29,5 +29,10 @@ class FloatAttributeTest < MiniTest::Test
|
|
29
29
|
b.height = '5.42'
|
30
30
|
assert_equal 5.42, b.height
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
|
+
def test_persistence
|
34
|
+
b = Building.new name: 'Test', height: 87.4
|
35
|
+
assert b.save
|
36
|
+
assert_equal 87.4, Building.find(b.id).height
|
37
|
+
end
|
33
38
|
end
|