architect4r 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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