vorpal 0.1.0.rc3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,42 +0,0 @@
1
- require 'integration_spec_helper'
2
- require 'vorpal'
3
-
4
- describe Vorpal::DbDriver do
5
- describe '#build_db_class' do
6
- let(:db_class) { subject.build_db_class(DbDriverSpec::Foo, 'example') }
7
-
8
- it 'generates a valid class name so that rails auto-reloading works' do
9
- expect { Vorpal.const_defined?(db_class.name) }.to_not raise_error
10
- end
11
-
12
- it 'does not let the user access the generated class' do
13
- expect { Vorpal.const_get(db_class.name) }.to raise_error(NameError)
14
- end
15
-
16
- it 'isolates two POROs that map to the same db table' do
17
- db_class1 = build_db_class(DbDriverSpec::Foo)
18
- db_class2 = build_db_class(DbDriverSpec::Bar)
19
-
20
- expect(db_class1).to_not eq(db_class2)
21
- expect(db_class1.name).to_not eq(db_class2.name)
22
- end
23
-
24
- it 'uses the model class name to make the generated AR::Base class name unique' do
25
- db_class = build_db_class(DbDriverSpec::Foo)
26
-
27
- expect(db_class.name).to match("DbDriverSpec__Foo")
28
- end
29
- end
30
-
31
- private
32
-
33
- module DbDriverSpec
34
- class Foo; end
35
- class Bar; end
36
- end
37
-
38
- def build_db_class(clazz)
39
- db_driver = Vorpal::DbDriver.new
40
- db_driver.build_db_class(clazz, 'example')
41
- end
42
- end
@@ -1,195 +0,0 @@
1
- require 'integration_spec_helper'
2
- require 'vorpal'
3
- require 'virtus'
4
- require 'activerecord-import/base'
5
-
6
- module Performance
7
- describe 'performance' do
8
-
9
- class Bug
10
- include Virtus.model
11
-
12
- attribute :id, Integer
13
- attribute :name, String
14
- attribute :lives_on, Object
15
- end
16
-
17
- class Tree; end
18
-
19
- class Trunk
20
- include Virtus.model
21
-
22
- attribute :id, Integer
23
- attribute :length, Decimal
24
- attribute :bugs, Array[Bug]
25
- attribute :tree, Tree
26
- end
27
-
28
- class Branch
29
- include Virtus.model
30
-
31
- attribute :id, Integer
32
- attribute :length, Decimal
33
- attribute :tree, Tree
34
- attribute :branches, Array[Branch]
35
- attribute :bugs, Array[Bug]
36
-
37
- def add_branch(branch_options)
38
- branch = Branch.new(branch_options.merge(branch: self))
39
- branches << branch
40
- branch
41
- end
42
- end
43
-
44
- class Tree
45
- include Virtus.model
46
-
47
- attribute :id, Integer
48
- attribute :name, String
49
- attribute :trunk, Trunk
50
- attribute :branches, Array[Branch]
51
-
52
- def set_trunk(trunk)
53
- trunk.tree = self
54
- self.trunk = trunk
55
- end
56
-
57
- def add_branch(branch_options)
58
- branch = Branch.new(branch_options.merge(tree: self))
59
- branches << branch
60
- branch
61
- end
62
- end
63
-
64
- before(:all) do
65
- define_table('branches_perf', {length: :decimal, tree_id: :integer, branch_id: :integer}, false)
66
- define_table('bugs_perf', {name: :text, lives_on_id: :integer, lives_on_type: :string}, false)
67
- define_table('trees_perf', {name: :text, trunk_id: :integer}, false)
68
- define_table('trunks_perf', {length: :decimal}, false)
69
- end
70
-
71
- let(:tree_mapper) { build_mapper }
72
-
73
- # Vorpal 0.0.5:
74
- # user system total real
75
- # create 4.160000 0.440000 4.600000 ( 6.071752)
76
- # update 7.990000 0.730000 8.720000 ( 15.281017)
77
- # load 10.120000 0.730000 10.850000 ( 21.087785)
78
- # destroy 6.090000 0.620000 6.710000 ( 12.541420)
79
- #
80
- # Vorpal 0.0.6:
81
- # user system total real
82
- # create 0.990000 0.100000 1.090000 ( 1.415715)
83
- # update 2.240000 0.180000 2.420000 ( 2.745321)
84
- # load 2.130000 0.020000 2.150000 ( 2.223182)
85
- # destroy 0.930000 0.010000 0.940000 ( 1.038624)
86
- #
87
- # Vorpal 0.1.0:
88
- # user system total real
89
- # create 0.870000 0.100000 0.970000 ( 1.320534)
90
- # update 1.820000 0.210000 2.030000 ( 2.351518)
91
- # load 1.310000 0.010000 1.320000 ( 1.394192)
92
- # destroy 0.930000 0.010000 0.940000 ( 1.030910)
93
- it 'benchmarks all operations' do
94
- trees = build_trees(1000)
95
- Benchmark.bm(7) do |x|
96
- x.report('create') { tree_mapper.persist(trees) }
97
- x.report('update') { tree_mapper.persist(trees) }
98
- x.report('load') { tree_mapper.query.where(id: trees.map(&:id)).load_many }
99
- x.report('destroy') { tree_mapper.destroy(trees) }
100
- end
101
- end
102
-
103
- # it 'creates aggregates quickly' do
104
- # trees = build_trees(1000)
105
- #
106
- # puts 'starting persistence benchmark'
107
- # puts Benchmark.measure {
108
- # tree_mapper.persist(trees)
109
- # }
110
- # end
111
- #
112
- # it 'updates aggregates quickly' do
113
- # trees = build_trees(1000)
114
- #
115
- # tree_mapper.persist(trees)
116
- #
117
- # puts 'starting update benchmark'
118
- # puts Benchmark.measure {
119
- # tree_mapper.persist(trees)
120
- # }
121
- # end
122
- #
123
- # it 'loads aggregates quickly' do
124
- # trees = build_trees(1000)
125
- # tree_mapper.persist(trees)
126
- # ids = trees.map(&:id)
127
- #
128
- # puts 'starting loading benchmark'
129
- # puts Benchmark.measure {
130
- # tree_mapper.query.where(id: ids).load_many
131
- # }
132
- # end
133
- #
134
- # it 'destroys aggregates quickly' do
135
- # trees = build_trees(1000)
136
- # tree_mapper.persist(trees)
137
- #
138
- # puts 'starting destruction benchmark'
139
- # puts Benchmark.measure {
140
- # tree_mapper.destroy(trees)
141
- # }
142
- # end
143
-
144
- def build_trees(count)
145
- (1..count).map do |i|
146
- tree = Tree.new
147
- trunk = Trunk.new(length: i)
148
- tree.set_trunk(trunk)
149
-
150
- branch1 = tree.add_branch(length: i * 10)
151
- branch2 = tree.add_branch(length: i * 20)
152
- branch2.add_branch(length: i * 30)
153
-
154
- build_bug(trunk)
155
- build_bug(branch1)
156
-
157
- tree
158
- end
159
- end
160
-
161
- def build_bug(bug_home)
162
- bug = Bug.new(lives_on: bug_home)
163
- bug_home.bugs = [bug]
164
- end
165
-
166
- def build_mapper
167
- engine = Vorpal.define do
168
- map Tree, table_name: "trees_perf" do
169
- attributes :name
170
- belongs_to :trunk
171
- has_many :branches
172
- end
173
-
174
- map Trunk, table_name: "trunks_perf" do
175
- attributes :length
176
- has_one :tree
177
- has_many :bugs, fk: :lives_on_id, fk_type: :lives_on_type
178
- end
179
-
180
- map Branch, table_name: "branches_perf" do
181
- attributes :length
182
- belongs_to :tree
183
- has_many :bugs, fk: :lives_on_id, fk_type: :lives_on_type
184
- has_many :branches
185
- end
186
-
187
- map Bug, table_name: "bugs_perf" do
188
- attributes :name
189
- belongs_to :lives_on, fk: :lives_on_id, fk_type: :lives_on_type, child_classes: [Trunk, Branch]
190
- end
191
- end
192
- engine.mapper_for(Tree)
193
- end
194
- end
195
- end
@@ -1,117 +0,0 @@
1
- require 'unit_spec_helper'
2
- require 'vorpal/configs'
3
-
4
- describe Vorpal::MasterConfig do
5
- class Post
6
- attr_accessor :comments
7
- attr_accessor :best_comment
8
- end
9
-
10
- class Comment
11
- attr_accessor :post
12
- end
13
-
14
- let(:post_config) { Vorpal::ClassConfig.new(domain_class: Post) }
15
- let(:comment_config) { Vorpal::ClassConfig.new(domain_class: Comment) }
16
- let(:post_has_many_comments_config) { Vorpal::HasManyConfig.new(name: 'comments', fk: 'post_id', child_class: Comment) }
17
- let(:post_has_one_comment_config) { Vorpal::HasOneConfig.new(name: 'best_comment', fk: 'post_id', child_class: Comment) }
18
- let(:comment_belongs_to_post_config) { Vorpal::BelongsToConfig.new(name: 'post', fk: 'post_id', child_classes: [Post]) }
19
-
20
- describe 'local_association_configs' do
21
- it 'builds an association_config for a belongs_to' do
22
- comment_config.belongs_tos << comment_belongs_to_post_config
23
-
24
- Vorpal::MasterConfig.new([post_config, comment_config])
25
-
26
- expect(comment_config.local_association_configs.size).to eq(1)
27
- expect(post_config.local_association_configs.size).to eq(0)
28
- end
29
-
30
- it 'sets the association end configs' do
31
- comment_config.belongs_tos << comment_belongs_to_post_config
32
- post_config.has_manys << post_has_many_comments_config
33
-
34
- Vorpal::MasterConfig.new([post_config, comment_config])
35
-
36
- association_config = comment_config.local_association_configs.first
37
-
38
- expect(association_config.remote_end_config).to eq(post_has_many_comments_config)
39
- expect(association_config.local_end_config).to eq(comment_belongs_to_post_config)
40
- end
41
-
42
- it 'builds an association_config for a has_many' do
43
- post_config.has_manys << post_has_many_comments_config
44
-
45
- Vorpal::MasterConfig.new([post_config, comment_config])
46
-
47
- expect(comment_config.local_association_configs.size).to eq(1)
48
- expect(post_config.local_association_configs.size).to eq(0)
49
- end
50
- end
51
-
52
- describe 'nice user feedback' do
53
- it 'lets the user know what the problem is when a configuration is missing' do
54
- master_config = Vorpal::MasterConfig.new([])
55
-
56
- expect {
57
- master_config.config_for(String)
58
- }.to raise_error(Vorpal::ConfigurationNotFound, "No configuration found for String")
59
- end
60
- end
61
-
62
- describe Vorpal::AssociationConfig do
63
- describe 'associate' do
64
- let(:post) { Post.new }
65
- let(:comment) { Comment.new }
66
-
67
- it 'sets both ends of a one-to-one association' do
68
- config = Vorpal::AssociationConfig.new(comment_config, 'post_id', nil)
69
- config.add_remote_class_config(post_config)
70
-
71
- config.local_end_config = comment_belongs_to_post_config
72
- config.remote_end_config = post_has_one_comment_config
73
-
74
- config.associate(comment, post)
75
-
76
- expect(comment.post).to eq(post)
77
- expect(post.best_comment).to eq(comment)
78
- end
79
-
80
- it 'sets both ends of a one-to-many association' do
81
- config = Vorpal::AssociationConfig.new(comment_config, 'post_id', nil)
82
- config.add_remote_class_config(post_config)
83
-
84
- config.local_end_config = comment_belongs_to_post_config
85
- config.remote_end_config = post_has_many_comments_config
86
-
87
- config.associate(comment, post)
88
-
89
- expect(comment.post).to eq(post)
90
- expect(post.comments).to eq([comment])
91
- end
92
- end
93
-
94
- describe 'remote_class_config' do
95
- it 'works with non-polymorphic associations' do
96
- config = Vorpal::AssociationConfig.new(comment_config, 'post_id', nil)
97
- config.add_remote_class_config(post_config)
98
-
99
- post = Post.new
100
- class_config = config.remote_class_config(post)
101
-
102
- expect(class_config).to eq(post_config)
103
- end
104
-
105
- it 'works with polymorphic associations' do
106
- config = Vorpal::AssociationConfig.new(comment_config, 'commented_upon_id', 'commented_upon_type')
107
- config.add_remote_class_config(post_config)
108
- config.add_remote_class_config(comment_config)
109
-
110
- comment = double('comment', commented_upon_type: 'Comment')
111
- class_config = config.remote_class_config(comment)
112
-
113
- expect(class_config).to eq(comment_config)
114
- end
115
- end
116
- end
117
- end
@@ -1,103 +0,0 @@
1
- require 'unit_spec_helper'
2
- require 'vorpal'
3
- require 'virtus'
4
-
5
- describe Vorpal::DbLoader do
6
-
7
- class Post; end
8
-
9
- class Comment
10
- include Virtus.model
11
-
12
- attribute :id, Integer
13
- attribute :post, Post
14
- end
15
-
16
- class Post
17
- include Virtus.model
18
-
19
- attribute :id, Integer
20
- attribute :best_comment, Comment
21
- attribute :comments, Array[Comment]
22
- end
23
-
24
- class PostDB
25
- include Virtus.model
26
- attribute :id, Integer
27
- attribute :best_comment_id, Integer
28
- end
29
-
30
- class CommentDB
31
- include Virtus.model
32
- attribute :id, Integer
33
- attribute :post_id, Integer
34
- end
35
-
36
- before(:all) do
37
- # define_table('comments', {post_id: :integer}, false)
38
- # CommentDB = defineAr('comments')
39
-
40
- # define_table('posts', {best_comment_id: :integer}, false)
41
- # PostDB = defineAr('posts')
42
- end
43
-
44
- # it 'loads an object once even when referred to by different associations of different types2' do
45
- # post_config = Vorpal.build_class_config(Post) do
46
- # attributes :name
47
- # belongs_to :best_comment, child_class: Comment
48
- # has_many :comments
49
- # end
50
- #
51
- # comment_config = Vorpal.build_class_config(Comment) do
52
- # attributes :length
53
- # end
54
- #
55
- # master_config = Vorpal::MasterConfig.new([post_config, comment_config])
56
- #
57
- # driver = Vorpal::DbDriver.new
58
- #
59
- # best_comment_db = CommentDB.create!
60
- # post_db = PostDB.create!(best_comment_id: best_comment_db.id)
61
- # best_comment_db.update_attributes!(post_id: post_db.id)
62
- #
63
- # loader = Vorpal::DbLoader.new(false, driver)
64
- # loaded_objects = loader.load_from_db([post_db.id], master_config.config_for(Post))
65
- # p loaded_objects.all_objects
66
- # # expect(loaded_objects.all_objects.size).to eq(2)
67
- #
68
- # repo = Vorpal::AggregateMapper.new(driver, master_config)
69
- # post = repo.load(post_db.id, Post)
70
- # p post
71
- # expect(post.comments.size).to eq(1)
72
- # end
73
-
74
- it 'loads an object once even when referred to by different associations of different types with stubs' do
75
- post_config = Vorpal.build_class_config(Post, to: PostDB) do
76
- attributes :name
77
- belongs_to :best_comment, child_class: Comment
78
- has_many :comments
79
- end
80
-
81
- comment_config = Vorpal.build_class_config(Comment, to: CommentDB) do
82
- attributes :length
83
- end
84
-
85
- Vorpal::MasterConfig.new([post_config, comment_config])
86
-
87
- best_comment_db = CommentDB.new
88
- best_comment_db.id = 99
89
- post_db = PostDB.new(best_comment_id: best_comment_db.id)
90
- post_db.id = 100
91
- best_comment_db.post_id = post_db.id
92
-
93
- driver = instance_double("Vorpal::DbDriver")
94
- expect(driver).to receive(:load_by_id).with(post_config, [post_db.id]).and_return([post_db])
95
- expect(driver).to receive(:load_by_id).with(comment_config, [best_comment_db.id]).and_return([best_comment_db])
96
- expect(driver).to receive(:load_by_foreign_key).and_return([best_comment_db])
97
-
98
- loader = Vorpal::DbLoader.new(false, driver)
99
- loaded_objects = loader.load_from_db([post_db.id], post_config)
100
-
101
- expect(loaded_objects.all_objects).to contain_exactly(post_db, best_comment_db)
102
- end
103
- end