ar_doc_store 1.0.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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