vorpal 1.0.3 → 1.1.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -10
  3. data/lib/vorpal/aggregate_mapper.rb +11 -0
  4. data/lib/vorpal/driver/postgresql.rb +39 -3
  5. data/lib/vorpal/version.rb +1 -1
  6. data/vorpal.gemspec +4 -3
  7. metadata +9 -59
  8. data/.editorconfig +0 -13
  9. data/.envrc +0 -4
  10. data/.gitignore +0 -16
  11. data/.rspec +0 -1
  12. data/.ruby-version +0 -1
  13. data/.travis.yml +0 -18
  14. data/.yardopts +0 -1
  15. data/Appraisals +0 -18
  16. data/Gemfile +0 -4
  17. data/Rakefile +0 -39
  18. data/bin/appraisal +0 -29
  19. data/bin/rake +0 -29
  20. data/bin/rspec +0 -29
  21. data/docker-compose.yml +0 -19
  22. data/gemfiles/rails_5_1.gemfile +0 -11
  23. data/gemfiles/rails_5_1.gemfile.lock +0 -101
  24. data/gemfiles/rails_5_2.gemfile +0 -11
  25. data/gemfiles/rails_5_2.gemfile.lock +0 -101
  26. data/gemfiles/rails_6_0.gemfile +0 -9
  27. data/gemfiles/rails_6_0.gemfile.lock +0 -101
  28. data/spec/acceptance/vorpal/aggregate_mapper_spec.rb +0 -910
  29. data/spec/helpers/codecov_helper.rb +0 -7
  30. data/spec/helpers/db_helpers.rb +0 -69
  31. data/spec/helpers/profile_helpers.rb +0 -26
  32. data/spec/integration/vorpal/driver/postgresql_spec.rb +0 -42
  33. data/spec/integration_spec_helper.rb +0 -29
  34. data/spec/performance/vorpal/performance_spec.rb +0 -305
  35. data/spec/unit/vorpal/configs_spec.rb +0 -117
  36. data/spec/unit/vorpal/db_loader_spec.rb +0 -103
  37. data/spec/unit/vorpal/dsl/config_builder_spec.rb +0 -18
  38. data/spec/unit/vorpal/dsl/defaults_generator_spec.rb +0 -75
  39. data/spec/unit/vorpal/identity_map_spec.rb +0 -62
  40. data/spec/unit/vorpal/loaded_objects_spec.rb +0 -22
  41. data/spec/unit/vorpal/util/string_utils_spec.rb +0 -25
  42. data/spec/unit_spec_helper.rb +0 -1
@@ -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
@@ -1,18 +0,0 @@
1
- require 'unit_spec_helper'
2
-
3
- require 'vorpal/dsl/config_builder'
4
-
5
- describe Vorpal::Dsl::ConfigBuilder do
6
- class Tester; end
7
-
8
- let(:builder) { Vorpal::Dsl::ConfigBuilder.new(Tester, {}, nil) }
9
-
10
- describe 'mapping attributes' do
11
- it 'allows the \'attributes\' method to be called multiple times' do
12
- builder.attributes :first
13
- builder.attributes :second
14
-
15
- expect(builder.attributes_with_id).to eq([:id, :first, :second])
16
- end
17
- end
18
- end
@@ -1,75 +0,0 @@
1
- require 'unit_spec_helper'
2
-
3
- require 'vorpal/dsl/defaults_generator'
4
- require 'vorpal/driver/postgresql'
5
-
6
- describe Vorpal::Dsl::DefaultsGenerator do
7
- class Tester; end
8
- class Author; end
9
- module Namespace
10
- class Tester; end
11
- class Author; end
12
- end
13
-
14
- let(:db_driver) { instance_double(Vorpal::Driver::Postgresql)}
15
-
16
- describe '#build_db_class' do
17
- it 'derives the table_name from the domain class name' do
18
- generator = build_generator(Tester)
19
- expect(db_driver).to receive(:build_db_class).with(Tester, "testers")
20
-
21
- generator.build_db_class(nil)
22
- end
23
-
24
- it 'specifies the table_name manually' do
25
- generator = build_generator(Tester)
26
- expect(db_driver).to receive(:build_db_class).with(Tester, "override")
27
-
28
- generator.build_db_class("override")
29
- end
30
- end
31
-
32
- describe '#table_name' do
33
- it 'namespaces the table name' do
34
- generator = build_generator(Namespace::Tester)
35
-
36
- expect(generator.table_name).to eq("namespace/testers")
37
- end
38
- end
39
-
40
- describe '#child_class' do
41
- it 'resolves the associated class' do
42
- generator = build_generator(Tester)
43
- clazz = generator.child_class("author")
44
-
45
- expect(clazz.name).to eq("Author")
46
- end
47
-
48
- it 'resolves the associated class in the same namespace as the owning class' do
49
- generator = build_generator(Namespace::Tester)
50
- clazz = generator.child_class("author")
51
-
52
- expect(clazz.name).to eq("Namespace::Author")
53
- end
54
- end
55
-
56
- describe '#foreign_key' do
57
- it 'generates a foreign key from an association name' do
58
- generator = build_generator(Tester)
59
- fk_name = generator.foreign_key("author")
60
-
61
- expect(fk_name).to eq("author_id")
62
- end
63
-
64
- it 'generates a foreign key from an association name regardless of the namespace of the owning class' do
65
- generator = build_generator(Namespace::Tester)
66
- fk_name = generator.foreign_key("author")
67
-
68
- expect(fk_name).to eq("author_id")
69
- end
70
- end
71
-
72
- def build_generator(domain_clazz)
73
- Vorpal::Dsl::DefaultsGenerator.new(domain_clazz, db_driver)
74
- end
75
- end
@@ -1,62 +0,0 @@
1
- require 'unit_spec_helper'
2
-
3
- require 'vorpal/identity_map'
4
-
5
- describe Vorpal::IdentityMap do
6
- let(:map) { Vorpal::IdentityMap.new }
7
-
8
- it "does not rely on the key object's implementation of hash and eql?" do
9
- funny1 = build_funny_entity(1)
10
- map.set(funny1, 'funny 1')
11
-
12
- funny2 = build_funny_entity(2)
13
- map.set(funny2, 'funny 2')
14
-
15
- expect(map.get(funny1)).to eq('funny 1')
16
- end
17
-
18
- it "raises an exception when the key object does not have an id set" do
19
- entity = build_entity(nil)
20
-
21
- expect { map.set(entity, 'something') }.to raise_error(/Cannot map a DB row/)
22
- end
23
-
24
- it 'raises an exception when the key object extends a class with no name (such as anonymous classes)' do
25
- anonymous_class = Class.new do
26
- attr_accessor :id
27
- end
28
-
29
- entity = anonymous_class.new
30
- entity.id = 1
31
-
32
- expect { map.set(entity, 'something') }.to raise_error(/Cannot map a DB row/)
33
- end
34
-
35
- def build_entity(id)
36
- entity = Entity.new
37
- entity.id = id
38
- entity
39
- end
40
-
41
- class Entity
42
- attr_accessor :id
43
- end
44
-
45
- def build_funny_entity(id)
46
- funny1 = Funny.new
47
- funny1.id = id
48
- funny1
49
- end
50
-
51
- class Funny
52
- attr_accessor :id
53
-
54
- def hash
55
- 1
56
- end
57
-
58
- def eql?(other)
59
- true
60
- end
61
- end
62
- end
@@ -1,22 +0,0 @@
1
- require 'unit_spec_helper'
2
-
3
- require 'virtus'
4
- require 'vorpal/loaded_objects'
5
- require 'vorpal/configs'
6
-
7
- describe Vorpal::LoadedObjects do
8
- class TestObject
9
- include Virtus.model
10
- attribute :id, Integer
11
- end
12
-
13
- it 'does not accept duplicate objects' do
14
- object = TestObject.new(id: 22)
15
- config = Vorpal::ClassConfig.new({domain_class: Object})
16
-
17
- subject.add(config, [object, object])
18
- subject.add(config, [object])
19
-
20
- expect(subject.objects.values.flatten).to contain_exactly(object)
21
- end
22
- end
@@ -1,25 +0,0 @@
1
- require 'unit_spec_helper'
2
- require 'vorpal/util/string_utils'
3
-
4
- describe Vorpal::Util::StringUtils do
5
-
6
- describe '.escape_class_name' do
7
- it 'does nothing when there are no :: in the class name' do
8
- expect(escape_class_name("Foo")).to eq("Foo")
9
- end
10
-
11
- it 'converts :: into __' do
12
- expect(escape_class_name("Foo::Bar")).to eq("Foo__Bar")
13
- end
14
-
15
- it 'converts multiple :: into __' do
16
- expect(escape_class_name("Foo::Bar::Baz")).to eq("Foo__Bar__Baz")
17
- end
18
- end
19
-
20
- private
21
-
22
- def escape_class_name(class_name)
23
- Vorpal::Util::StringUtils.escape_class_name(class_name)
24
- end
25
- end
@@ -1 +0,0 @@
1
- require 'helpers/codecov_helper'