babik 0.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 (109) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +16 -0
  3. data/README.md +718 -0
  4. data/Rakefile +18 -0
  5. data/lib/babik.rb +122 -0
  6. data/lib/babik/database.rb +16 -0
  7. data/lib/babik/queryset.rb +154 -0
  8. data/lib/babik/queryset/components/aggregation.rb +172 -0
  9. data/lib/babik/queryset/components/limit.rb +22 -0
  10. data/lib/babik/queryset/components/order.rb +161 -0
  11. data/lib/babik/queryset/components/projection.rb +118 -0
  12. data/lib/babik/queryset/components/select_related.rb +78 -0
  13. data/lib/babik/queryset/components/sql_renderer.rb +99 -0
  14. data/lib/babik/queryset/components/where.rb +43 -0
  15. data/lib/babik/queryset/lib/association/foreign_association_chain.rb +97 -0
  16. data/lib/babik/queryset/lib/association/select_related_association_chain.rb +32 -0
  17. data/lib/babik/queryset/lib/condition.rb +103 -0
  18. data/lib/babik/queryset/lib/field.rb +34 -0
  19. data/lib/babik/queryset/lib/join/association_joiner.rb +39 -0
  20. data/lib/babik/queryset/lib/join/join.rb +86 -0
  21. data/lib/babik/queryset/lib/selection/config.rb +19 -0
  22. data/lib/babik/queryset/lib/selection/foreign_selection.rb +39 -0
  23. data/lib/babik/queryset/lib/selection/local_selection.rb +40 -0
  24. data/lib/babik/queryset/lib/selection/operation/base.rb +126 -0
  25. data/lib/babik/queryset/lib/selection/operation/date.rb +178 -0
  26. data/lib/babik/queryset/lib/selection/operation/operations.rb +201 -0
  27. data/lib/babik/queryset/lib/selection/operation/regex.rb +58 -0
  28. data/lib/babik/queryset/lib/selection/path/foreign_path.rb +50 -0
  29. data/lib/babik/queryset/lib/selection/path/local_path.rb +44 -0
  30. data/lib/babik/queryset/lib/selection/path/path.rb +23 -0
  31. data/lib/babik/queryset/lib/selection/select_related_selection.rb +38 -0
  32. data/lib/babik/queryset/lib/selection/selection.rb +19 -0
  33. data/lib/babik/queryset/lib/update/assignment.rb +108 -0
  34. data/lib/babik/queryset/mixins/aggregatable.rb +17 -0
  35. data/lib/babik/queryset/mixins/bounded.rb +38 -0
  36. data/lib/babik/queryset/mixins/clonable.rb +52 -0
  37. data/lib/babik/queryset/mixins/countable.rb +44 -0
  38. data/lib/babik/queryset/mixins/deletable.rb +13 -0
  39. data/lib/babik/queryset/mixins/distinguishable.rb +27 -0
  40. data/lib/babik/queryset/mixins/filterable.rb +51 -0
  41. data/lib/babik/queryset/mixins/limitable.rb +88 -0
  42. data/lib/babik/queryset/mixins/lockable.rb +31 -0
  43. data/lib/babik/queryset/mixins/none.rb +16 -0
  44. data/lib/babik/queryset/mixins/projectable.rb +34 -0
  45. data/lib/babik/queryset/mixins/related_selector.rb +28 -0
  46. data/lib/babik/queryset/mixins/set_operations.rb +32 -0
  47. data/lib/babik/queryset/mixins/sortable.rb +49 -0
  48. data/lib/babik/queryset/mixins/sql_renderizable.rb +17 -0
  49. data/lib/babik/queryset/mixins/updatable.rb +14 -0
  50. data/lib/babik/queryset/templates/default/delete/main.sql.erb +14 -0
  51. data/lib/babik/queryset/templates/default/select/components/aggregation.sql.erb +5 -0
  52. data/lib/babik/queryset/templates/default/select/components/from.sql.erb +16 -0
  53. data/lib/babik/queryset/templates/default/select/components/from_set.sql.erb +3 -0
  54. data/lib/babik/queryset/templates/default/select/components/from_table.sql.erb +2 -0
  55. data/lib/babik/queryset/templates/default/select/components/limit.sql.erb +10 -0
  56. data/lib/babik/queryset/templates/default/select/components/order_by.sql.erb +9 -0
  57. data/lib/babik/queryset/templates/default/select/components/projection.sql.erb +7 -0
  58. data/lib/babik/queryset/templates/default/select/components/select_related.sql.erb +26 -0
  59. data/lib/babik/queryset/templates/default/select/components/where.sql.erb +39 -0
  60. data/lib/babik/queryset/templates/default/select/main.sql.erb +42 -0
  61. data/lib/babik/queryset/templates/default/update/main.sql.erb +15 -0
  62. data/lib/babik/queryset/templates/mssql/select/components/limit.sql.erb +8 -0
  63. data/lib/babik/queryset/templates/mssql/select/components/order_by.sql.erb +21 -0
  64. data/lib/babik/queryset/templates/mysql2/delete/main.sql.erb +15 -0
  65. data/lib/babik/queryset/templates/mysql2/update/main.sql.erb +18 -0
  66. data/lib/babik/queryset/templates/sqlite3/select/components/from_set.sql.erb +5 -0
  67. data/test/config/db/schema.rb +83 -0
  68. data/test/config/models/bad_post.rb +5 -0
  69. data/test/config/models/bad_tag.rb +5 -0
  70. data/test/config/models/category.rb +4 -0
  71. data/test/config/models/geozone.rb +6 -0
  72. data/test/config/models/group.rb +5 -0
  73. data/test/config/models/group_user.rb +5 -0
  74. data/test/config/models/post.rb +24 -0
  75. data/test/config/models/post_tag.rb +5 -0
  76. data/test/config/models/tag.rb +5 -0
  77. data/test/config/models/user.rb +6 -0
  78. data/test/delete/delete_test.rb +60 -0
  79. data/test/delete/foreign_conditions_delete_test.rb +57 -0
  80. data/test/delete/local_conditions_delete_test.rb +20 -0
  81. data/test/enable_coverage.rb +17 -0
  82. data/test/lib/selection/operation/log/test-queries.log +1 -0
  83. data/test/lib/selection/operation/test_date.rb +131 -0
  84. data/test/lib/selection/operation/test_regex.rb +55 -0
  85. data/test/other/clone_test.rb +129 -0
  86. data/test/other/escape_test.rb +21 -0
  87. data/test/other/inverse_of_required_test.rb +33 -0
  88. data/test/select/aggregate_test.rb +151 -0
  89. data/test/select/bounds_test.rb +46 -0
  90. data/test/select/count_test.rb +147 -0
  91. data/test/select/distinct_test.rb +38 -0
  92. data/test/select/exclude_test.rb +72 -0
  93. data/test/select/filter_from_object_test.rb +125 -0
  94. data/test/select/filter_test.rb +207 -0
  95. data/test/select/for_update_test.rb +19 -0
  96. data/test/select/foreign_selection_test.rb +60 -0
  97. data/test/select/get_test.rb +40 -0
  98. data/test/select/limit_test.rb +109 -0
  99. data/test/select/local_selection_test.rb +24 -0
  100. data/test/select/lookup_test.rb +208 -0
  101. data/test/select/none_test.rb +40 -0
  102. data/test/select/order_test.rb +165 -0
  103. data/test/select/project_test.rb +107 -0
  104. data/test/select/select_related_test.rb +124 -0
  105. data/test/select/subquery_test.rb +50 -0
  106. data/test/set_operations/basic_usage_test.rb +121 -0
  107. data/test/test_helper.rb +55 -0
  108. data/test/update/update_test.rb +93 -0
  109. metadata +278 -0
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest/autorun'
4
+ require_relative '../test_helper'
5
+
6
+ # Tests of filter method when being called from an ActiveRecord object
7
+ class FilterFromObjectTest < Minitest::Test
8
+
9
+ def setup
10
+ @asturias = GeoZone.new(name: 'Asturias')
11
+ @cantabria = GeoZone.new(name: 'Cantabria')
12
+ @cangas_de_onis = GeoZone.new(name: 'Cangas de Onís', parent_zone: @asturias)
13
+
14
+ @pelayo = User.create!(first_name: 'Pelayo', zone: @cangas_de_onis)
15
+ User.create!(first_name: 'Favila', zone: @cangas_de_onis)
16
+ User.create!(first_name: 'Alfonso I', last_name: 'Católico', zone: @cantabria)
17
+ User.create!(first_name: 'Fruela I', zone: @cangas_de_onis)
18
+
19
+ battle = Tag.create!(name: 'battle')
20
+ asturias = Tag.create!(name: 'asturias')
21
+ victory = Tag.create!(name: 'victory')
22
+ Tag.create!(name: 'chronicle')
23
+
24
+ @main_category = Category.create!(name: 'Dialogues')
25
+ @other_category = Category.create!(name: 'My reign')
26
+
27
+ @first_post = Post.create!(author: @pelayo, title: 'I\'m not an ass', category: @main_category)
28
+ @second_post = Post.create!(author: @pelayo, title: 'Come and get my land', category: @main_category)
29
+ @third_post = Post.create!(author: @pelayo, title: 'Will keep my kingdom', category: @other_category)
30
+
31
+ @first_post.tags << battle
32
+ @first_post.tags << asturias
33
+ @first_post.tags << victory
34
+ @second_post.tags << asturias
35
+ @second_post.tags << victory
36
+ end
37
+
38
+ def teardown
39
+ User.destroy_all
40
+ GeoZone.destroy_all
41
+ Post.destroy_all
42
+ Tag.destroy_all
43
+ Category.destroy_all
44
+ end
45
+
46
+ def test_belongs_to_or_has_one
47
+ # Returns an ActiveRecord object
48
+ pelayo_zone = @pelayo.objects(:zone)
49
+ assert_equal @cangas_de_onis.class, pelayo_zone.class
50
+ assert_equal @cangas_de_onis.id, pelayo_zone.id
51
+ end
52
+
53
+ def test_direct_has_many_explicit_foreign_key
54
+ # Direct has_many relationship with an explicit foreign_key
55
+ users_from_cangas_de_onis = @cangas_de_onis.objects(:users).order_by(first_name: :ASC)
56
+ assert_equal @cangas_de_onis.users.count, users_from_cangas_de_onis.count
57
+ first_names = ['Favila', 'Fruela I', 'Pelayo']
58
+ users_count = 0
59
+ users_from_cangas_de_onis.each_with_index do |user, user_index|
60
+ assert_equal first_names[user_index], user.first_name
61
+ users_count += 1
62
+ end
63
+ assert_equal first_names.count, users_count
64
+ end
65
+
66
+ def test_deep_has_many
67
+ # Deep has_many relationship
68
+ tags_from_cangas_de_onis = @cangas_de_onis
69
+ .objects(:'users::posts::tags')
70
+ .distinct
71
+ .exclude(name: 'asturias')
72
+ .order_by(name: :ASC)
73
+ tag_names = %w[battle victory]
74
+ tags_count = 0
75
+ tags_from_cangas_de_onis.each_with_index do |tag, tag_index|
76
+ assert_equal tag_names[tag_index], tag.name
77
+ tags_count += 1
78
+ end
79
+ assert_equal tag_names.count, tags_count
80
+ end
81
+
82
+ def test_direct_has_many
83
+ # Direct has_many relationship
84
+ main_category_posts = @main_category.objects(:posts).order_by(created_at: :ASC)
85
+ posts = @main_category.posts
86
+ assert_equal posts.count, main_category_posts.count
87
+ post_titles = [@first_post.title, @second_post.title]
88
+ post_count = 0
89
+ main_category_posts.each_with_index do |post, post_index|
90
+ assert_equal post_titles[post_index], post.title
91
+ post_count += 1
92
+ end
93
+ assert_equal post_titles.count, post_count
94
+ end
95
+
96
+ def test_through_has_many_1
97
+ # has_many through relationship
98
+ assert_equal 5, @pelayo.objects('posts::tags').count
99
+ assert_equal 3, @pelayo.objects('posts::tags').distinct.count
100
+ tag_names = %w[asturias battle victory]
101
+ tag_count = 0
102
+ @pelayo.objects('posts::tags').distinct.order_by(name: :ASC).each_with_index do |tag, tag_index|
103
+ assert_equal tag_names[tag_index], tag.name
104
+ tag_count += 1
105
+ end
106
+ assert_equal tag_names.count, tag_count
107
+ end
108
+
109
+ def test_through_has_many_2
110
+ main_distinct_tags = @main_category.objects('posts::tags').distinct.order_by(name: :ASC)
111
+ main_tags = @main_category.objects('posts::tags').order_by(name: :ASC)
112
+
113
+ assert_equal 3, main_distinct_tags.count
114
+ assert_equal 5, main_tags.count
115
+
116
+ tag_names = %w[asturias battle victory]
117
+ tag_count = 0
118
+ main_distinct_tags.each_with_index do |tag, tag_index|
119
+ assert_equal tag_names[tag_index], tag.name
120
+ tag_count += 1
121
+ end
122
+ assert_equal main_distinct_tags.count, tag_count
123
+ end
124
+
125
+ end
@@ -0,0 +1,207 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest/autorun'
4
+ require_relative '../test_helper'
5
+
6
+ # Tests of filter method
7
+ class FilterTest < Minitest::Test
8
+
9
+ def setup
10
+ @asturias = GeoZone.new(name: 'Asturias')
11
+ @cantabria = GeoZone.new(name: 'Cantabria')
12
+ @cangas_de_onis = GeoZone.new(name: 'Cangas de Onís', parent_zone: @asturias)
13
+
14
+ @pelayo = User.create!(first_name: 'Pelayo', zone: @cangas_de_onis)
15
+ User.create!(first_name: 'Favila', zone: @cangas_de_onis)
16
+ User.create!(first_name: 'Alfonso I', last_name: 'Católico', zone: @cantabria)
17
+ User.create!(first_name: 'Fruela I', zone: @cangas_de_onis)
18
+
19
+ battle = Tag.create!(name: 'battle')
20
+ asturias = Tag.create!(name: 'asturias')
21
+ victory = Tag.create!(name: 'victory')
22
+ Tag.create!(name: 'chronicle')
23
+
24
+ @main_category = Category.create!(name: 'Dialogues')
25
+
26
+ first_post = Post.create!(author: @pelayo, title: 'I\'m not an ass', category: @main_category)
27
+ second_post = Post.create!(author: @pelayo, title: 'Come and get my land', category: @main_category)
28
+
29
+ first_post.tags << battle
30
+ first_post.tags << asturias
31
+ first_post.tags << victory
32
+
33
+ second_post.tags << asturias
34
+ second_post.tags << victory
35
+ end
36
+
37
+ def teardown
38
+ User.destroy_all
39
+ GeoZone.destroy_all
40
+ Post.destroy_all
41
+ BadPost.destroy_all
42
+ Tag.destroy_all
43
+ Category.destroy_all
44
+ end
45
+
46
+ def test_local_filter
47
+ kings = User.objects.filter(first_name__endswith: 'I').order_by(%i[first_name ASC])
48
+ asturian_kings = ['Alfonso I', 'Fruela I']
49
+ user_count = 0
50
+ kings.each_with_index do |king, king_i|
51
+ assert_equal asturian_kings[king_i], king.first_name
52
+ user_count += 1
53
+ end
54
+ assert_equal asturian_kings.count, user_count
55
+ end
56
+
57
+ def test_local_or_filter
58
+ kings = User.objects
59
+ .filter([{ first_name: 'Pelayo' }, {'last_name': 'Católico'}])
60
+ .order_by(%i[first_name ASC])
61
+ asturian_kings = ['Alfonso I', 'Pelayo']
62
+ user_count = 0
63
+ kings.each_with_index do |king, king_i|
64
+ assert_equal asturian_kings[king_i], king.first_name
65
+ user_count += 1
66
+ end
67
+ assert_equal asturian_kings.count, user_count
68
+ end
69
+
70
+ def test_foreign_filter
71
+ kings = User.objects
72
+ .filter('zone::parent_zone::name': 'Asturias')
73
+ .order_by(%i[first_name ASC])
74
+ asturian_kings = ['Favila', 'Fruela I', 'Pelayo']
75
+ user_count = 0
76
+ kings.each_with_index do |king, king_i|
77
+ assert_equal asturian_kings[king_i], king.first_name
78
+ user_count += 1
79
+ end
80
+ assert_equal asturian_kings.count, user_count
81
+ end
82
+
83
+ def test_foreign_filter_by_active_record_object
84
+ kings = User.objects
85
+ .filter('zone::parent_zone': @asturias)
86
+ .order_by(%i[first_name ASC])
87
+ asturian_kings = ['Favila', 'Fruela I', 'Pelayo']
88
+ user_count = 0
89
+ kings.each_with_index do |king, king_i|
90
+ assert_equal asturian_kings[king_i], king.first_name
91
+ user_count += 1
92
+ end
93
+ assert_equal asturian_kings.count, user_count
94
+ end
95
+
96
+ def test_foreign_or_filter
97
+ kings = User.objects
98
+ .filter([{first_name: 'Pelayo'}, {'zone::name': 'Cantabria'}])
99
+ .order_by(%i[first_name ASC])
100
+ asturian_kings = ['Alfonso I', 'Pelayo']
101
+ user_count = 0
102
+ kings.each_with_index do |king, king_i|
103
+ assert_equal asturian_kings[king_i], king.first_name
104
+ user_count += 1
105
+ end
106
+ assert_equal asturian_kings.count, user_count
107
+ end
108
+
109
+ # Different ways of querying with in lookup
110
+ def test_foreign_in
111
+ first_users = [
112
+ User.objects.filter(zone: [@cangas_de_onis, @cantabria]).order_by(created_at: :ASC)[0],
113
+ User.objects.filter(zone_id__in: [@cangas_de_onis, @cantabria]).order_by(created_at: :ASC)[0],
114
+ User.objects.filter(zone__in: [@cangas_de_onis, @cantabria]).order_by(created_at: :ASC)[0],
115
+ User.objects.filter(zone: [@cangas_de_onis.id, @cantabria.id]).order_by(created_at: :ASC)[0],
116
+ User.objects.filter(zone__in: [@cangas_de_onis.id, @cantabria.id]).order_by(created_at: :ASC)[0],
117
+ ]
118
+ different_user_ids = Set.new(first_users.map(&:id))
119
+ assert_equal 1, different_user_ids.length
120
+ end
121
+
122
+ def test_many_to_many_foreign_filter
123
+ tags = Tag.objects.distinct.filter('posts::title__contains': 'an ass').order_by(%i[name ASC])
124
+ tag_names = ['asturias', 'battle', 'victory']
125
+ tag_count = 0
126
+ tags.each_with_index do |tag, tag_index|
127
+ assert_equal tag_names[tag_index], tag.name
128
+ tag_count += 1
129
+ end
130
+ assert_equal tag_names.count, tag_count
131
+ end
132
+
133
+ def test_deep_many_to_many_foreign_filter
134
+ tags = Tag.objects.distinct.filter('posts::category::name': 'Dialogues').order_by(%i[name ASC])
135
+ tag_names = ['asturias', 'battle', 'victory']
136
+ tag_count = 0
137
+ tags.each_with_index do |tag, tag_index|
138
+ assert_equal tag_names[tag_index], tag.name
139
+ tag_count += 1
140
+ end
141
+ assert_equal tag_names.count, tag_count
142
+ end
143
+
144
+ def test_several_foreign_filters
145
+ cangueses_called_pelayo = User.objects.distinct.filter(
146
+ first_name: 'Pelayo', 'zone::name': @cangas_de_onis.name, 'posts::tags::name': 'asturias'
147
+ )
148
+ assert_equal 1, cangueses_called_pelayo.count
149
+ assert_equal @pelayo.id, cangueses_called_pelayo.first.id
150
+ end
151
+
152
+ def test_foreign_filter_by_object
153
+ cangueses = User.objects.distinct.filter('zone': @cangas_de_onis).order_by(%i[first_name ASC])
154
+ names = ['Favila', 'Fruela I', 'Pelayo']
155
+ cangueses.each_with_index do |cangues, cangues_index|
156
+ assert_equal names[cangues_index], cangues.first_name
157
+ end
158
+ assert_equal names.length, cangueses.count
159
+ end
160
+
161
+ def test_wrong_local_filter
162
+ exception = assert_raises RuntimeError do
163
+ User.objects.filter(this_local_field_does_not_exists: 'whatever').all
164
+ end
165
+ assert_equal(
166
+ 'Unrecognized field this_local_field_does_not_exists for model User in filter/exclude', exception.message
167
+ )
168
+ end
169
+
170
+ def test_wrong_many_to_many_foreign_filter
171
+ exception = assert_raises RuntimeError do
172
+ BadTag.objects.distinct.filter('posts::category::name': 'Dialogues').order_by(%i[name ASC])
173
+ end
174
+ assert_equal('Relationship posts is has_and_belongs_to_many. Convert it to has_many-through', exception.message)
175
+ end
176
+
177
+ def test_wrong_association_in_foreign_filter
178
+ exception = assert_raises RuntimeError do
179
+ Tag.objects.filter('posts::bad_association::name': 'Dialogues').order_by(%i[name ASC])
180
+ end
181
+ assert_equal(
182
+ 'Bad selection path: posts::bad_association::name. bad_association not found in model Post when filtering Tag objects',
183
+ exception.message
184
+ )
185
+ end
186
+
187
+ def test_wrong_field_name_of_foreign_model
188
+ exception = assert_raises RuntimeError do
189
+ Tag.objects.filter('posts::category::xxx': 'Dialogues').order_by(%i[name ASC])
190
+ end
191
+ assert_equal(
192
+ 'Unrecognized field xxx for model Category in filter/exclude',
193
+ exception.message
194
+ )
195
+ end
196
+
197
+ def test_wrong_parameter_passed_to_filter
198
+ exception = assert_raises RuntimeError do
199
+ Tag.objects.filter('INVALID VALUE').order_by(%i[name ASC])
200
+ end
201
+ assert_equal(
202
+ '`filter\' parameter must be an Array for OR-based AND-conditions or a hash for a lone AND-condition',
203
+ exception.message
204
+ )
205
+ end
206
+
207
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest/autorun'
4
+ require_relative '../test_helper'
5
+
6
+ # Tests of for_update method
7
+ class ForUpdateTest < Minitest::Test
8
+
9
+ def test_for_update_sql
10
+ queryset = User.objects.for_update.filter(first_name: 'Marcus')
11
+ assert queryset.sql.select.match?('FOR UPDATE'), queryset.sql.select
12
+ end
13
+
14
+ def test_lock_sql
15
+ queryset = User.objects.lock.filter(first_name: 'Marcus')
16
+ assert queryset.sql.select.match?('FOR UPDATE'), queryset.sql.select
17
+ end
18
+
19
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest/autorun'
4
+ require_relative '../test_helper'
5
+
6
+ class ForeignSelectionTest < Minitest::Test
7
+
8
+ def test_equal_in_belongs_to_relationship
9
+ foreign_selection = Babik::Selection::ForeignSelection.new(User, 'zone::name', 'Rome')
10
+ assert_equal foreign_selection.model, User
11
+ assert_equal foreign_selection.associations, [User.reflect_on_association(:zone)]
12
+ assert_equal foreign_selection.selection_path, 'zone::name'
13
+ assert_equal foreign_selection.selected_field, 'name'
14
+ assert_equal foreign_selection.value, 'Rome'
15
+ assert_equal foreign_selection.operator, 'equal'
16
+ assert_equal foreign_selection.sql_where_condition.to_s, 'users__zone_0.name = \'Rome\''
17
+ end
18
+
19
+ def test_equal_in_belongs_to_deep_relationship
20
+ foreign_selection = Babik::Selection::ForeignSelection.new(User, 'zone::parent_zone::name', 'Rome')
21
+ assert_equal foreign_selection.model, User
22
+
23
+ user_to_zone_association = User.reflect_on_association(:zone)
24
+ _associations_are_equal(foreign_selection.associations[0], user_to_zone_association)
25
+
26
+ zone_to_parent_zone_association = GeoZone.reflect_on_association(:parent_zone)
27
+ _associations_are_equal(foreign_selection.associations[1], zone_to_parent_zone_association)
28
+
29
+ assert_equal foreign_selection.selection_path, 'zone::parent_zone::name'
30
+ assert_equal foreign_selection.selected_field, 'name'
31
+ assert_equal foreign_selection.value, 'Rome'
32
+ assert_equal foreign_selection.operator, 'equal'
33
+ assert_equal foreign_selection.sql_where_condition.to_s, 'geo_zones__parent_zone_1.name = \'Rome\''
34
+ end
35
+
36
+ def test_equal_in_has_many_relationship
37
+ foreign_selection = Babik::Selection::ForeignSelection.new(User, 'posts::tags::name', 'Funny')
38
+ assert_equal foreign_selection.model, User
39
+ assert_equal foreign_selection.selection_path, 'posts::tags::name'
40
+ assert_equal foreign_selection.selected_field, 'name'
41
+ assert_equal foreign_selection.value, 'Funny'
42
+ assert_equal foreign_selection.operator, 'equal'
43
+
44
+ assert_equal foreign_selection.sql_where_condition.to_s, 'post_tags__tag_2.name = \'Funny\''
45
+ end
46
+
47
+ def _associations_are_equal(association1, association2)
48
+ assert_equal association1.active_record, association2.active_record
49
+ assert_equal association1.name, association2.name
50
+ %w[foreign_key class_name optional].each do |option_key|
51
+ if association1.options[option_key].nil? || association2.options[option_key].nil?
52
+ assert_nil association1.options[option_key]
53
+ assert_nil association2.options[option_key]
54
+ else
55
+ assert_equal association1.options[option_key], association2.options[option_key]
56
+ end
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest/autorun'
4
+ require_relative '../test_helper'
5
+
6
+ # Test for get method of QuerySet
7
+ class GetTest < Minitest::Test
8
+
9
+ def setup
10
+ User.create!(first_name: 'Rollo', last_name: 'Lothbrok')
11
+ User.create!(first_name: 'Ragnar', last_name: 'Lothbrok')
12
+ User.create!(first_name: 'Sigurd', last_name: 'Ring')
13
+ User.create!(first_name: 'Freydis', last_name: 'Eriksdottir')
14
+ User.create!(first_name: 'Harald', last_name: 'Hardrada')
15
+ end
16
+
17
+ def teardown
18
+ User.delete_all
19
+ end
20
+
21
+ def test_get_ok
22
+ freydis = User.objects.get(last_name: 'Eriksdottir')
23
+ assert_equal 'Freydis', freydis.first_name
24
+ assert_equal 'Eriksdottir', freydis.last_name
25
+ end
26
+
27
+ def test_get_not_found
28
+ exception = assert_raises RuntimeError do
29
+ User.objects.get(last_name: 'Last name that does not exist')
30
+ end
31
+ assert_equal('Does not exist', exception.message)
32
+ end
33
+
34
+ def test_get_not_several_objects_returned
35
+ exception = assert_raises RuntimeError do
36
+ User.objects.get(last_name: 'Lothbrok')
37
+ end
38
+ assert_equal('Multiple objects returned', exception.message)
39
+ end
40
+ end