architect4r 0.3.2

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 (110) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +53 -0
  4. data/Guardfile +10 -0
  5. data/License +20 -0
  6. data/README.md +62 -0
  7. data/Rakefile +40 -0
  8. data/ReleaseNotes.md +33 -0
  9. data/Roadmap.md +31 -0
  10. data/Specs.md +21 -0
  11. data/architect4r.gemspec +31 -0
  12. data/lib/architect4r.rb +66 -0
  13. data/lib/architect4r/adapters/carrier_wave.rb +64 -0
  14. data/lib/architect4r/core/configuration.rb +148 -0
  15. data/lib/architect4r/core/cypher_methods.rb +47 -0
  16. data/lib/architect4r/core/management_methods.rb +129 -0
  17. data/lib/architect4r/core/node_methods.rb +73 -0
  18. data/lib/architect4r/core/relationship_methods.rb +82 -0
  19. data/lib/architect4r/generic_node.rb +7 -0
  20. data/lib/architect4r/has_node.rb +80 -0
  21. data/lib/architect4r/instance_manager.rb +47 -0
  22. data/lib/architect4r/model/callbacks.rb +19 -0
  23. data/lib/architect4r/model/connection.rb +29 -0
  24. data/lib/architect4r/model/links_query_interface.rb +23 -0
  25. data/lib/architect4r/model/node.rb +117 -0
  26. data/lib/architect4r/model/persistency.rb +95 -0
  27. data/lib/architect4r/model/properties.rb +166 -0
  28. data/lib/architect4r/model/queries.rb +38 -0
  29. data/lib/architect4r/model/relationship.rb +105 -0
  30. data/lib/architect4r/model/relationships.rb +16 -0
  31. data/lib/architect4r/model/validations.rb +11 -0
  32. data/lib/architect4r/server.rb +96 -0
  33. data/lib/architect4r/version.rb +3 -0
  34. data/spec/architect4r_spec.rb +9 -0
  35. data/spec/core/configuration_spec.rb +54 -0
  36. data/spec/core/cypher_methods_spec.rb +29 -0
  37. data/spec/core/node_methods_spec.rb +47 -0
  38. data/spec/core/relationship_methods_spec.rb +92 -0
  39. data/spec/fixtures/architect4r.yml +21 -0
  40. data/spec/fixtures/graph.db.default/active_tx_log +1 -0
  41. data/spec/fixtures/graph.db.default/index/lucene-store.db +0 -0
  42. data/spec/fixtures/graph.db.default/index/lucene.log.1 +0 -0
  43. data/spec/fixtures/graph.db.default/index/lucene.log.active +0 -0
  44. data/spec/fixtures/graph.db.default/index/lucene.log.v0 +0 -0
  45. data/spec/fixtures/graph.db.default/index/lucene.log.v1 +0 -0
  46. data/spec/fixtures/graph.db.default/index/lucene.log.v2 +0 -0
  47. data/spec/fixtures/graph.db.default/lock +0 -0
  48. data/spec/fixtures/graph.db.default/messages.log +183 -0
  49. data/spec/fixtures/graph.db.default/neostore +0 -0
  50. data/spec/fixtures/graph.db.default/neostore.id +0 -0
  51. data/spec/fixtures/graph.db.default/neostore.nodestore.db +0 -0
  52. data/spec/fixtures/graph.db.default/neostore.nodestore.db.id +0 -0
  53. data/spec/fixtures/graph.db.default/neostore.propertystore.db +0 -0
  54. data/spec/fixtures/graph.db.default/neostore.propertystore.db.arrays +0 -0
  55. data/spec/fixtures/graph.db.default/neostore.propertystore.db.arrays.id +0 -0
  56. data/spec/fixtures/graph.db.default/neostore.propertystore.db.id +0 -0
  57. data/spec/fixtures/graph.db.default/neostore.propertystore.db.index +0 -0
  58. data/spec/fixtures/graph.db.default/neostore.propertystore.db.index.id +0 -0
  59. data/spec/fixtures/graph.db.default/neostore.propertystore.db.index.keys +0 -0
  60. data/spec/fixtures/graph.db.default/neostore.propertystore.db.index.keys.id +0 -0
  61. data/spec/fixtures/graph.db.default/neostore.propertystore.db.strings +0 -0
  62. data/spec/fixtures/graph.db.default/neostore.propertystore.db.strings.id +0 -0
  63. data/spec/fixtures/graph.db.default/neostore.relationshipstore.db +0 -0
  64. data/spec/fixtures/graph.db.default/neostore.relationshipstore.db.id +0 -0
  65. data/spec/fixtures/graph.db.default/neostore.relationshiptypestore.db +0 -0
  66. data/spec/fixtures/graph.db.default/neostore.relationshiptypestore.db.id +0 -0
  67. data/spec/fixtures/graph.db.default/neostore.relationshiptypestore.db.names +0 -0
  68. data/spec/fixtures/graph.db.default/neostore.relationshiptypestore.db.names.id +0 -0
  69. data/spec/fixtures/graph.db.default/nioneo_logical.log.1 +0 -0
  70. data/spec/fixtures/graph.db.default/nioneo_logical.log.active +0 -0
  71. data/spec/fixtures/graph.db.default/tm_tx_log.1 +0 -0
  72. data/spec/fixtures/graph.db.default/upgrade_backup/active_tx_log +1 -0
  73. data/spec/fixtures/graph.db.default/upgrade_backup/messages.log +142 -0
  74. data/spec/fixtures/graph.db.default/upgrade_backup/neostore +0 -0
  75. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.id +0 -0
  76. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.nodestore.db +0 -0
  77. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.nodestore.db.id +0 -0
  78. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db +0 -0
  79. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.arrays +0 -0
  80. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.arrays.id +0 -0
  81. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.id +0 -0
  82. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.index +0 -0
  83. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.index.id +0 -0
  84. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.index.keys +0 -0
  85. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.index.keys.id +0 -0
  86. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.strings +0 -0
  87. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.strings.id +0 -0
  88. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.relationshipstore.db +0 -0
  89. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.relationshipstore.db.id +0 -0
  90. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.relationshiptypestore.db +0 -0
  91. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.relationshiptypestore.db.id +0 -0
  92. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.relationshiptypestore.db.names +0 -0
  93. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.relationshiptypestore.db.names.id +0 -0
  94. data/spec/fixtures/graph.db.default/upgrade_backup/nioneo_logical.log.active +0 -0
  95. data/spec/fixtures/graph.db.default/upgrade_backup/nioneo_logical.log.v0 +0 -0
  96. data/spec/fixtures/graph.db.default/upgrade_backup/nioneo_logical.log.v1 +0 -0
  97. data/spec/fixtures/graph.db.default/upgrade_backup/nioneo_logical.log.v2 +0 -0
  98. data/spec/fixtures/graph.db.default/upgrade_backup/tm_tx_log.1 +0 -0
  99. data/spec/has_node_spec.rb +87 -0
  100. data/spec/model/links_query_interface_spec.rb +22 -0
  101. data/spec/model/links_spec.rb +26 -0
  102. data/spec/model/node_spec.rb +48 -0
  103. data/spec/model/persistency_spec.rb +98 -0
  104. data/spec/model/properties_spec.rb +165 -0
  105. data/spec/model/queries_spec.rb +50 -0
  106. data/spec/model/relationship_spec.rb +63 -0
  107. data/spec/model/validations_spec.rb +31 -0
  108. data/spec/server_spec.rb +33 -0
  109. data/spec/spec_helper.rb +115 -0
  110. metadata +377 -0
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ describe Architect4r::HasNode do
4
+
5
+ subject { SomeDatabaseModel.new }
6
+
7
+ describe "setup" do
8
+
9
+ it "should have a node method" do
10
+ subject.should respond_to(:node)
11
+ end
12
+
13
+ it "should have a architect4r_create_node method" do
14
+ subject.should respond_to(:architect4r_create_node)
15
+ end
16
+
17
+ it "should have a architect4r_destroy_node method" do
18
+ subject.should respond_to(:architect4r_destroy_node)
19
+ end
20
+
21
+ it "should have a architect4r_sync_node method" do
22
+ subject.should respond_to(:architect4r_sync_node)
23
+ end
24
+
25
+ end
26
+
27
+ describe "node retrieval" do
28
+
29
+ it "should return nil if the parent record does not have an id" do
30
+ subject.should_receive(:id).and_return(nil)
31
+ subject.node.should be_nil
32
+ end
33
+
34
+ it "should try to retrieve the node when an id is present" do
35
+ mock_node = mock(SomeDatabaseModelNode)
36
+ subject.should_receive(:id).at_least(2).times.and_return(1)
37
+ SomeDatabaseModelNode.should_receive(:find_by_cypher).at_least(1).times.and_return(mock(:first => mock_node))
38
+ subject.node.should == mock_node
39
+ end
40
+
41
+ end
42
+
43
+ describe "node creation" do
44
+
45
+ it "should not create a new node if there is no record id" do
46
+ subject.should_receive(:id).and_return(nil)
47
+ subject.architect4r_create_node.should be_nil
48
+ end
49
+
50
+ it "should trigger the node creating after create" do
51
+ subject.should_receive(:architect4r_create_node).once
52
+ subject.create
53
+ end
54
+
55
+ it "should create a sync node" do
56
+ subject.id = 2
57
+ subject.name = 'My little test'
58
+ subject.create
59
+ subject.node.should be_a(SomeDatabaseModelNode)
60
+ end
61
+
62
+ it "should check the node for required attributes" do
63
+ pending
64
+ end
65
+
66
+ it "should save the sync attributes when creating the node" do
67
+ subject.id = 3
68
+ subject.name = "My little test"
69
+ subject.create
70
+ subject.node.name.should == subject.name
71
+ end
72
+
73
+ end
74
+
75
+ describe "node sync" do
76
+ it "should store the changed attributes to the node" do
77
+ subject.id = 4
78
+ subject.name = "My sync test"
79
+ subject.create
80
+ subject.node.name.should == subject.name
81
+ subject.name = "My changed sync test"
82
+ subject.update
83
+ subject.node.name.should == subject.name
84
+ end
85
+ end
86
+
87
+ end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+
3
+ describe Architect4r::Model::LinksQueryInterface do
4
+
5
+ before(:all) { @node = Person.create(:name => 'Neo') }
6
+ after(:all) { @node.destroy }
7
+
8
+ subject { Architect4r::Model::LinksQueryInterface.new(@node) }
9
+
10
+ it "should respond to :incoming" do
11
+ subject.should respond_to(:incoming)
12
+ end
13
+
14
+ it "should respond to :incoming" do
15
+ subject.should respond_to(:outgoing)
16
+ end
17
+
18
+ it "should respond to :incoming" do
19
+ subject.should respond_to(:both)
20
+ end
21
+
22
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe "links to and from nodes" do
4
+
5
+ before(:all) { @node = Person.create(:name => 'Neo') }
6
+ after(:all) { @node.destroy }
7
+
8
+ it "should respond to :links" do
9
+ @node.should respond_to(:links)
10
+ end
11
+
12
+ subject { @node.links }
13
+
14
+ it "should respond to :incoming" do
15
+ subject.should respond_to(:incoming)
16
+ end
17
+
18
+ it "should respond to :incoming" do
19
+ subject.should respond_to(:outgoing)
20
+ end
21
+
22
+ it "should respond to :incoming" do
23
+ subject.should respond_to(:both)
24
+ end
25
+
26
+ end
@@ -0,0 +1,48 @@
1
+ require "spec_helper"
2
+
3
+ describe "Model Node" do
4
+
5
+ subject { Person }
6
+
7
+ describe :new do
8
+
9
+ it { should respond_to(:new) }
10
+
11
+ it "should accept a hash of properties with strings as keys" do
12
+ piano = subject.new({ 'name' => 'Neo' })
13
+ piano.should respond_to(:name)
14
+ piano.name.should eql('Neo')
15
+ end
16
+
17
+ it "should accept a hash of properties with symbols as keys" do
18
+ piano = subject.new({ :name => 'Neo' })
19
+ piano.should respond_to(:name)
20
+ piano.name.should eql('Neo')
21
+ end
22
+ end
23
+
24
+ describe "connection" do
25
+
26
+ it { should respond_to(:connection) }
27
+
28
+ its(:connection) { should respond_to(:get) }
29
+
30
+ end
31
+
32
+ describe "node model_root" do
33
+
34
+ it "should create a model_root node if there is none" do
35
+ Person.create(:name => 'Morpheus', :human => true)
36
+ Person.model_root.should_not be_nil
37
+ end
38
+
39
+ it "should reuse an existing model_root if there is already one" do
40
+ Person.create(:name => 'Morpheus', :human => true)
41
+ m_root = Person.model_root
42
+ Person.create(:name => 'Trinity', :human => true)
43
+ Person.model_root.should == m_root
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Persistency extension" do
4
+
5
+ describe :create do
6
+
7
+ subject { Person.new }
8
+
9
+ it "should create a new node" do
10
+ subject.name = 'Neo'
11
+ subject.human = true
12
+ subject.create.should be_true
13
+ end
14
+
15
+ it "should save a new node" do
16
+ subject.name = 'Neo'
17
+ subject.human = true
18
+ subject.save.should be_true
19
+ end
20
+
21
+ end
22
+
23
+ describe :update do
24
+
25
+ subject { Person.create(:name => 'Neo', :human => true, :note => 'Important person') }
26
+
27
+ it "should update the name" do
28
+ subject.name = "Agent Smith"
29
+ subject.update.should be_true
30
+ subject.name.should == "Agent Smith"
31
+ reloaded = Person.find_by_id(subject.id)
32
+ reloaded.name.should == "Agent Smith"
33
+ end
34
+
35
+ it "should add new properties" do
36
+ subject.age_when_enlightend.should be_nil
37
+ subject.age_when_enlightend = 18
38
+ subject.update.should be_true
39
+ subject.age_when_enlightend.should == 18
40
+
41
+ reloaded = Person.find_by_id(subject.id)
42
+ reloaded.age_when_enlightend.should == 18
43
+ end
44
+
45
+ it "should remove empty properties" do
46
+ subject.note.should_not be_nil
47
+ subject.note = nil
48
+
49
+ subject.update.should be_true
50
+ subject.note.should be_nil
51
+
52
+ reloaded = Person.find_by_id(subject.id)
53
+ reloaded.note.should be_nil
54
+ end
55
+
56
+ end
57
+
58
+ describe :delete do
59
+
60
+ subject { Person.create(:name => 'Max Mustermann', :human => true) }
61
+
62
+ it "should delete an existing node" do
63
+ deleted_id = subject.id
64
+ subject.destroy.should be_true
65
+ Person.find_by_id(deleted_id).should be_nil
66
+ end
67
+
68
+ it "should mark the object as deleted" do
69
+ subject.destroy.should be_true
70
+ subject.destroyed?.should be_true
71
+ end
72
+
73
+ it "should not be possible to update a deleted object" do
74
+ subject.destroy.should be_true
75
+ expect { subject.update }.to raise_error
76
+ end
77
+
78
+ it "should delete an existing node with relationships"
79
+
80
+ end
81
+
82
+ describe :new? do
83
+
84
+ subject { Person.new(:name => 'Name', :human => true) }
85
+
86
+ it "should be true if its a new record" do
87
+ subject.new?.should be_true
88
+ end
89
+
90
+ it "should be false if the record is created" do
91
+ subject.create
92
+ subject.new?.should be_false
93
+ subject.destroy
94
+ end
95
+
96
+ end
97
+
98
+ end
@@ -0,0 +1,165 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Model properties based on test class Person" do
4
+
5
+ describe "casting properties" do
6
+
7
+ subject { Person.new }
8
+
9
+ it "should cast strings to integers" do
10
+ subject.age_when_enlightend = "4"
11
+ subject.age_when_enlightend.should == 4
12
+ end
13
+
14
+ it "should cast the integer 1 to boolean true" do
15
+ subject.human = 1
16
+ subject.human.should == true
17
+ end
18
+
19
+ it "should cast the integer 0 to boolean false" do
20
+ subject.human = 0
21
+ subject.human.should == false
22
+ end
23
+
24
+ it "should cast the string 'true' to boolean true" do
25
+ subject.human = "true"
26
+ subject.human.should == true
27
+ end
28
+
29
+ it "should cast the string 'false' to boolean false" do
30
+ subject.human = "false"
31
+ subject.human.should == false
32
+ end
33
+
34
+ it "should cast the string '1' to boolean true" do
35
+ subject.human = "1"
36
+ subject.human.should == true
37
+ end
38
+
39
+ it "should cast the string '0' to boolean false" do
40
+ subject.human = "0"
41
+ subject.human.should == false
42
+ end
43
+
44
+ it "should create a ? method for boolean attributes" do
45
+ subject.human = true
46
+ subject.should respond_to(:human?)
47
+ subject.human?.should == true
48
+ end
49
+
50
+ end
51
+
52
+ describe "are nullified" do
53
+
54
+ context "when no property value is set" do
55
+ subject { Person.new }
56
+
57
+ its(:name) { should be_nil }
58
+ its(:age_when_enlightend) { should be_nil }
59
+ its(:human) { should be_nil }
60
+
61
+ end
62
+
63
+ context "when setting property value to nil" do
64
+ subject { Person.new(:name => 'Neo', :age_when_enlightend => 23, :human => true) }
65
+
66
+ it "should remove nil strings" do
67
+ subject.name = nil
68
+ subject.name.should be_nil
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+ describe "database properties json" do
75
+
76
+ subject { Person }
77
+
78
+ it "should include the type when casted to database hash" do
79
+ obj = subject.new
80
+ data_hash = obj.send(:_to_database_hash)
81
+ data_hash['architect4r_type'].should == 'Person'
82
+ end
83
+
84
+ it "should include all valid properties" do
85
+ obj = subject.new('name' => 'Neo', 'size' => 3)
86
+ data_hash = obj.send(:_to_database_hash)
87
+ data_hash['name'].should == 'Neo'
88
+ data_hash.has_key?('human').should be_false
89
+ end
90
+
91
+ it "should not include nil values" do
92
+ obj = subject.new(:name => 'Max Mustermann')
93
+ obj.send(:_to_database_hash).has_key?(:age).should be_false
94
+ end
95
+
96
+ end
97
+
98
+ describe "store in different localizations" do
99
+
100
+ subject { Person.new }
101
+
102
+ it "should provide a list of available locales"
103
+
104
+ it "should allow specifying a default locale"
105
+
106
+ it "should return the localized version based on the I18n locale" do
107
+ subject.write_attribute(:vita, "Neo the savior", :en)
108
+ subject.write_attribute(:vita, "Neo der Retter", :de)
109
+
110
+ I18n.locale = :en
111
+ subject.vita.should == "Neo the savior"
112
+
113
+ I18n.locale = :de
114
+ subject.vita.should == "Neo der Retter"
115
+ end
116
+
117
+ it "should fall back to the default value if no other is present" do
118
+ subject.write_attribute(:vita, "Hello there", :en)
119
+ # do not set a german title
120
+
121
+ I18n.locale = :de
122
+ subject.vita.should == "Hello there"
123
+ end
124
+
125
+ it "should not fall back to another localized value if not wanted" do
126
+ subject.write_attribute(:note, "This is my description", :en)
127
+ # do not set a german description
128
+
129
+ I18n.locale = :de
130
+ subject.note.should be_nil
131
+ I18n.locale = :en
132
+ subject.note.should == "This is my description"
133
+ end
134
+
135
+ it "should allow to force the returned locale" do
136
+ subject.write_attribute(:vita, "Hello there", :en)
137
+ subject.write_attribute(:vita, "Hallo du da", :de)
138
+
139
+ subject.read_attribute(:vita, :en).should == "Hello there"
140
+ subject.read_attribute(:vita, :de).should == "Hallo du da"
141
+ end
142
+
143
+ it "should set the localized version based on the I18n locale" do
144
+ I18n.locale = :en
145
+ subject.vita = "Hello there"
146
+
147
+ I18n.locale = :de
148
+ subject.vita = "Hallo du da"
149
+ I18n.locale = :en
150
+
151
+ subject.read_attribute('vita_en').should == "Hello there"
152
+ subject.read_attribute('vita_de').should == "Hallo du da"
153
+ end
154
+
155
+ it "should allow to force the locale in the setter" do
156
+ subject.write_attribute(:vita, "Hello there", :en)
157
+ subject.write_attribute(:vita, "Hallo du da", :de)
158
+
159
+ subject.read_attribute('vita_en').should == "Hello there"
160
+ subject.read_attribute('vita_de').should == "Hallo du da"
161
+ end
162
+
163
+ end
164
+
165
+ end