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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/ar_doc_store.gemspec +3 -3
  3. data/lib/ar_doc_store.rb +30 -28
  4. data/lib/ar_doc_store/attributes/array.rb +25 -0
  5. data/lib/ar_doc_store/attributes/base.rb +72 -0
  6. data/lib/ar_doc_store/attributes/boolean.rb +17 -0
  7. data/lib/ar_doc_store/attributes/callback_support.rb +21 -0
  8. data/lib/ar_doc_store/attributes/date.rb +21 -0
  9. data/lib/ar_doc_store/attributes/datetime.rb +21 -0
  10. data/lib/ar_doc_store/attributes/decimal.rb +17 -0
  11. data/lib/ar_doc_store/attributes/embeds_base.rb +35 -0
  12. data/lib/ar_doc_store/attributes/embeds_many.rb +143 -0
  13. data/lib/ar_doc_store/{attribute_types/embeds_one_attribute.rb → attributes/embeds_one.rb} +25 -30
  14. data/lib/ar_doc_store/{attribute_types/enumeration_attribute.rb → attributes/enumeration.rb} +2 -6
  15. data/lib/ar_doc_store/{attribute_types/float_attribute.rb → attributes/float.rb} +5 -8
  16. data/lib/ar_doc_store/{attribute_types/integer_attribute.rb → attributes/integer.rb} +5 -8
  17. data/lib/ar_doc_store/attributes/string.rb +13 -0
  18. data/lib/ar_doc_store/embeddable_model.rb +51 -75
  19. data/lib/ar_doc_store/embedded_collection.rb +14 -0
  20. data/lib/ar_doc_store/embedding.rb +0 -2
  21. data/lib/ar_doc_store/model.rb +18 -8
  22. data/lib/ar_doc_store/storage.rb +4 -127
  23. data/lib/ar_doc_store/types/embeds_many.rb +52 -0
  24. data/lib/ar_doc_store/types/embeds_one.rb +42 -0
  25. data/lib/ar_doc_store/version.rb +1 -1
  26. data/test/{attribute_types → attributes}/array_attribute_test.rb +5 -1
  27. data/test/{attribute_types → attributes}/boolean_attribute_test.rb +7 -1
  28. data/test/attributes/date_attribute_test.rb +52 -0
  29. data/test/attributes/datetime_attribute_test.rb +54 -0
  30. data/test/attributes/decimal_attribute_test.rb +38 -0
  31. data/test/attributes/embeds_many_attribute_test.rb +78 -0
  32. data/test/attributes/embeds_one_attribute_test.rb +80 -0
  33. data/test/{attribute_types → attributes}/enumeration_attribute_test.rb +5 -0
  34. data/test/{attribute_types → attributes}/float_attribute_test.rb +6 -1
  35. data/test/attributes/integer_attribute_test.rb +63 -0
  36. data/test/{attribute_types → attributes}/string_attribute_test.rb +6 -0
  37. data/test/test_helper.rb +22 -94
  38. metadata +57 -35
  39. data/lib/ar_doc_store/attribute_types/array_attribute.rb +0 -30
  40. data/lib/ar_doc_store/attribute_types/base_attribute.rb +0 -61
  41. data/lib/ar_doc_store/attribute_types/boolean_attribute.rb +0 -25
  42. data/lib/ar_doc_store/attribute_types/datetime_attribute.rb +0 -17
  43. data/lib/ar_doc_store/attribute_types/embeds_many_attribute.rb +0 -165
  44. data/lib/ar_doc_store/attribute_types/string_attribute.rb +0 -17
  45. data/lib/ar_doc_store/attribute_types/uuid_attribute.rb +0 -30
  46. data/test/attribute_types/datetime_attribute_test.rb +0 -35
  47. data/test/attribute_types/integer_attribute_test.rb +0 -33
  48. data/test/originals/dirty_attributes_test.rb +0 -35
  49. data/test/originals/embedded_model_attribute_test.rb +0 -23
  50. 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
@@ -1,3 +1,3 @@
1
1
  module ArDocStore
2
- VERSION = "1.0.5"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -21,5 +21,9 @@ class ArrayAttributeTest < MiniTest::Test
21
21
  assert_equal true, b.architects?
22
22
  end
23
23
 
24
- # Type conversion doesn't make sense here...
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