vorpal 1.0.0 → 1.2.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.
@@ -1,42 +0,0 @@
1
- require 'integration_spec_helper'
2
- require 'vorpal'
3
-
4
- describe Vorpal::Driver::Postgresql do
5
- describe '#build_db_class' do
6
- let(:db_class) { subject.build_db_class(PostgresDriverSpec::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(PostgresDriverSpec::Foo)
18
- db_class2 = build_db_class(PostgresDriverSpec::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(PostgresDriverSpec::Foo)
26
-
27
- expect(db_class.name).to match("PostgresDriverSpec__Foo")
28
- end
29
- end
30
-
31
- private
32
-
33
- module PostgresDriverSpec
34
- class Foo; end
35
- class Bar; end
36
- end
37
-
38
- def build_db_class(clazz)
39
- db_driver = Vorpal::Driver::Postgresql.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::Postgresql.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::Driver::Postgresql")
94
- expect(driver).to receive(:load_by_id).with(PostDB, [post_db.id]).and_return([post_db])
95
- expect(driver).to receive(:load_by_id).with(CommentDB, [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