rasti-db 2.0.1 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -3
  3. data/lib/rasti/db.rb +11 -1
  4. data/lib/rasti/db/collection.rb +10 -1
  5. data/lib/rasti/db/computed_attribute.rb +22 -0
  6. data/lib/rasti/db/nql/filter_condition_strategies/base.rb +17 -0
  7. data/lib/rasti/db/nql/filter_condition_strategies/postgres.rb +21 -0
  8. data/lib/rasti/db/nql/filter_condition_strategies/sqlite.rb +21 -0
  9. data/lib/rasti/db/nql/filter_condition_strategies/types/generic.rb +49 -0
  10. data/lib/rasti/db/nql/filter_condition_strategies/types/pg_array.rb +32 -0
  11. data/lib/rasti/db/nql/filter_condition_strategies/types/sqlite_array.rb +34 -0
  12. data/lib/rasti/db/nql/filter_condition_strategies/unsupported_type_comparison.rb +22 -0
  13. data/lib/rasti/db/nql/nodes/array_content.rb +21 -0
  14. data/lib/rasti/db/nql/nodes/attribute.rb +37 -0
  15. data/lib/rasti/db/nql/nodes/binary_node.rb +4 -0
  16. data/lib/rasti/db/nql/nodes/comparisons/base.rb +15 -1
  17. data/lib/rasti/db/nql/nodes/comparisons/equal.rb +0 -4
  18. data/lib/rasti/db/nql/nodes/comparisons/greater_than.rb +0 -4
  19. data/lib/rasti/db/nql/nodes/comparisons/greater_than_or_equal.rb +0 -4
  20. data/lib/rasti/db/nql/nodes/comparisons/include.rb +0 -4
  21. data/lib/rasti/db/nql/nodes/comparisons/less_than.rb +0 -4
  22. data/lib/rasti/db/nql/nodes/comparisons/less_than_or_equal.rb +0 -4
  23. data/lib/rasti/db/nql/nodes/comparisons/like.rb +0 -4
  24. data/lib/rasti/db/nql/nodes/comparisons/not_equal.rb +0 -4
  25. data/lib/rasti/db/nql/nodes/comparisons/not_include.rb +0 -4
  26. data/lib/rasti/db/nql/nodes/conjunction.rb +2 -2
  27. data/lib/rasti/db/nql/nodes/constants/array.rb +17 -0
  28. data/lib/rasti/db/nql/nodes/constants/base.rb +17 -0
  29. data/lib/rasti/db/nql/nodes/constants/false.rb +1 -1
  30. data/lib/rasti/db/nql/nodes/constants/float.rb +1 -1
  31. data/lib/rasti/db/nql/nodes/constants/integer.rb +1 -1
  32. data/lib/rasti/db/nql/nodes/constants/literal_string.rb +1 -1
  33. data/lib/rasti/db/nql/nodes/constants/string.rb +1 -1
  34. data/lib/rasti/db/nql/nodes/constants/time.rb +1 -1
  35. data/lib/rasti/db/nql/nodes/constants/true.rb +1 -1
  36. data/lib/rasti/db/nql/nodes/disjunction.rb +2 -2
  37. data/lib/rasti/db/nql/nodes/parenthesis_sentence.rb +6 -2
  38. data/lib/rasti/db/nql/nodes/sentence.rb +6 -2
  39. data/lib/rasti/db/nql/syntax.rb +262 -44
  40. data/lib/rasti/db/nql/syntax.treetop +27 -14
  41. data/lib/rasti/db/query.rb +38 -8
  42. data/lib/rasti/db/type_converters/postgres.rb +32 -36
  43. data/lib/rasti/db/type_converters/postgres_types/array.rb +11 -9
  44. data/lib/rasti/db/type_converters/postgres_types/hstore.rb +10 -9
  45. data/lib/rasti/db/type_converters/postgres_types/json.rb +17 -14
  46. data/lib/rasti/db/type_converters/postgres_types/jsonb.rb +17 -14
  47. data/lib/rasti/db/type_converters/sqlite.rb +62 -0
  48. data/lib/rasti/db/type_converters/sqlite_types/array.rb +34 -0
  49. data/lib/rasti/db/version.rb +1 -1
  50. data/rasti-db.gemspec +1 -0
  51. data/spec/collection_spec.rb +8 -0
  52. data/spec/computed_attribute_spec.rb +32 -0
  53. data/spec/minitest_helper.rb +32 -5
  54. data/spec/model_spec.rb +1 -1
  55. data/spec/nql/computed_attributes_spec.rb +29 -0
  56. data/spec/nql/filter_condition_spec.rb +23 -4
  57. data/spec/nql/filter_condition_strategies_spec.rb +112 -0
  58. data/spec/nql/syntax_parser_spec.rb +36 -5
  59. data/spec/query_spec.rb +235 -34
  60. data/spec/type_converters/sqlite_spec.rb +66 -0
  61. metadata +38 -3
  62. data/lib/rasti/db/nql/nodes/field.rb +0 -23
@@ -31,7 +31,7 @@ describe 'NQL::SyntaxParser' do
31
31
  proposition = tree.proposition
32
32
  proposition.must_be_instance_of node_class
33
33
  proposition.comparator.text_value.must_equal comparator
34
- proposition.field.text_value.must_equal 'column'
34
+ proposition.attribute.text_value.must_equal 'column'
35
35
  proposition.argument.text_value.must_equal 'value'
36
36
  end
37
37
  end
@@ -44,7 +44,7 @@ describe 'NQL::SyntaxParser' do
44
44
  proposition = tree.proposition
45
45
  proposition.must_be_instance_of Rasti::DB::NQL::Nodes::Comparisons::Equal
46
46
  proposition.comparator.text_value.must_equal '='
47
- proposition.field.text_value.must_equal 'column'
47
+ proposition.attribute.text_value.must_equal 'column'
48
48
  proposition.argument.text_value.must_equal 'value'
49
49
  end
50
50
 
@@ -128,12 +128,19 @@ describe 'NQL::SyntaxParser' do
128
128
 
129
129
  end
130
130
 
131
- it 'must parse expression with field with tables' do
131
+ it 'must parse expression with attribute with tables' do
132
132
  tree = parse 'relation_table_one.relation_table_two.column = 1'
133
133
 
134
- left_hand_operand = tree.proposition.field
134
+ left_hand_operand = tree.proposition.attribute
135
135
  left_hand_operand.tables.must_equal ['relation_table_one', 'relation_table_two']
136
- left_hand_operand.column.must_equal 'column'
136
+ left_hand_operand.column.must_equal :column
137
+ end
138
+
139
+ it 'must parse expression with computed attribute' do
140
+ tree = parse 'comments_count = 1'
141
+ computed = tree.proposition.attribute
142
+ computed.tables.must_equal []
143
+ computed.computed_attributes(Users).must_equal [:comments_count]
137
144
  end
138
145
 
139
146
  end
@@ -206,4 +213,28 @@ describe 'NQL::SyntaxParser' do
206
213
 
207
214
  end
208
215
 
216
+ describe 'Array' do
217
+
218
+ it 'must parse array with one element' do
219
+ tree = parse 'column = [ a ]'
220
+ tree.proposition.argument.value.must_equal ['a']
221
+ end
222
+
223
+ it 'must parse array with many elements' do
224
+ tree = parse 'column = [ a, b, c ]'
225
+ tree.proposition.argument.value.must_equal ['a', 'b', 'c']
226
+ end
227
+
228
+ it 'must parse array respecting content types' do
229
+ tree = parse 'column = [ true, 12:00, 1.1, 1, "literal string", string ]'
230
+ tree.proposition.argument.value.must_equal [true, Timing::TimeInZone.parse('12:00').to_s, 1.1, 1, "literal string", 'string']
231
+ end
232
+
233
+ it 'must parse array with literal string allowing reserved characters in conflict with array' do
234
+ tree = parse 'column = [ ",", "[", "]", "[,", "],", "[,]", "simple literal" ]'
235
+ tree.proposition.argument.value.must_equal [ ',', '[', ']', '[,', '],', '[,]', 'simple literal' ]
236
+ end
237
+
238
+ end
239
+
209
240
  end
data/spec/query_spec.rb CHANGED
@@ -5,13 +5,13 @@ describe 'Query' do
5
5
  before do
6
6
  custom_db[:languages].insert name: 'Spanish'
7
7
 
8
- 1.upto(10) do |i|
8
+ 1.upto(10) do |i|
9
9
  db[:users].insert name: "User #{i}"
10
10
 
11
- db[:people].insert user_id: i,
12
- document_number: "document_#{i}",
13
- first_name: "Name #{i}",
14
- last_name: "Last Name #{i}",
11
+ db[:people].insert user_id: i,
12
+ document_number: "document_#{i}",
13
+ first_name: "Name #{i}",
14
+ last_name: "Last Name #{i}",
15
15
  birth_date: Date.parse('2020-04-24')
16
16
 
17
17
  db[:languages_people].insert language_id: 1, document_number: "document_#{i}"
@@ -22,7 +22,7 @@ describe 'Query' do
22
22
  db[:posts].insert user_id: 4, title: 'Best post', body: '...', language_id: 1
23
23
 
24
24
  1.upto(3) { |i| db[:categories].insert name: "Category #{i}" }
25
-
25
+
26
26
  db[:comments].insert post_id: 1, user_id: 5, text: 'Comment 1'
27
27
  db[:comments].insert post_id: 1, user_id: 7, text: 'Comment 2'
28
28
  db[:comments].insert post_id: 2, user_id: 2, text: 'Comment 3'
@@ -35,11 +35,13 @@ describe 'Query' do
35
35
  end
36
36
 
37
37
  let(:users_query) { Rasti::DB::Query.new collection_class: Users, dataset: db[:users], environment: environment }
38
-
38
+
39
39
  let(:posts_query) { Rasti::DB::Query.new collection_class: Posts, dataset: db[:posts], environment: environment }
40
-
40
+
41
41
  let(:comments_query) { Rasti::DB::Query.new collection_class: Comments, dataset: db[:comments], environment: environment }
42
42
 
43
+ let(:people_query) { Rasti::DB::Query.new collection_class: People, dataset: db[:people], environment: environment }
44
+
43
45
  let(:languages_query) { Rasti::DB::Query.new collection_class: Languages, dataset: custom_db[:languages], environment: environment }
44
46
 
45
47
  it 'Count' do
@@ -87,8 +89,8 @@ describe 'Query' do
87
89
  post = Post.new db[:posts].where(id: 1).first.merge(user: user, categories: categories)
88
90
 
89
91
  selected_attributes = {
90
- user: [:id],
91
- 'user.person' => [:document_number, :user_id],
92
+ user: [:id],
93
+ 'user.person' => [:document_number, :user_id],
92
94
  'user.person.languages' => [:id],
93
95
  categories: [:id]
94
96
  }
@@ -99,7 +101,7 @@ describe 'Query' do
99
101
  .all
100
102
  .must_equal [post]
101
103
  end
102
-
104
+
103
105
  it 'Exclude graph attributes' do
104
106
  language = Language.new custom_db[:languages].where(id: 1).select(:id).first
105
107
 
@@ -112,8 +114,8 @@ describe 'Query' do
112
114
  post = Post.new db[:posts].where(id: 1).first.merge(user: user, categories: categories)
113
115
 
114
116
  excluded_attributes = {
115
- user: [:name],
116
- 'user.person' => [:first_name, :last_name, :birth_date],
117
+ user: [:name],
118
+ 'user.person' => [:first_name, :last_name, :birth_date],
117
119
  'user.person.languages' => [:name],
118
120
  categories: [:name]
119
121
  }
@@ -124,7 +126,7 @@ describe 'Query' do
124
126
  .all
125
127
  .must_equal [post]
126
128
  end
127
-
129
+
128
130
  it 'All graph attributes' do
129
131
  person = Person.new db[:people].where(document_number: 'document_2').first
130
132
 
@@ -140,6 +142,30 @@ describe 'Query' do
140
142
  .must_equal [post]
141
143
  end
142
144
 
145
+ describe 'Select computed attributes' do
146
+ it 'With join' do
147
+ db[:comments].insert post_id: 1, user_id: 5, text: 'Comment 4'
148
+ users_query.select_computed_attributes(:comments_count)
149
+ .where(id: 5)
150
+ .all
151
+ .must_equal [User.new(id: 5, name: 'User 5', comments_count: 2)]
152
+ end
153
+
154
+ it 'Without join' do
155
+ person_expected = Person.new user_id: 1,
156
+ document_number: 'document_1',
157
+ first_name: 'Name 1',
158
+ last_name: 'Last Name 1',
159
+ birth_date: Date.parse('2020-04-24'),
160
+ full_name: 'Name 1 Last Name 1'
161
+
162
+ people_query.select_computed_attributes(:full_name)
163
+ .where(document_number: 'document_1')
164
+ .all
165
+ .must_equal [person_expected]
166
+ end
167
+ end
168
+
143
169
  it 'Map' do
144
170
  users_query.map(&:name).must_equal db[:users].map(:name)
145
171
  end
@@ -148,45 +174,88 @@ describe 'Query' do
148
174
  users_query.detect(id: 3).must_equal User.new(id: 3, name: 'User 3')
149
175
  end
150
176
 
177
+ describe 'Each' do
178
+
179
+ it 'without size' do
180
+ users = []
181
+
182
+ users_query.each do |user|
183
+ users << user
184
+ end
185
+
186
+ users.size.must_equal 10
187
+ users.each_with_index do |user, i|
188
+ user.must_equal User.new(id: i+1, name: "User #{i+1}")
189
+ end
190
+ end
191
+
192
+ it 'with size' do
193
+ users = []
194
+ users_query.each(batch_size: 2) do |user|
195
+ users << user
196
+ end
197
+
198
+ users.size.must_equal 10
199
+ users.each_with_index do |user, i|
200
+ user.must_equal User.new(id: i+1, name: "User #{i+1}")
201
+ end
202
+ end
203
+
204
+ end
205
+
206
+ it 'Each batch' do
207
+ users_batch = []
208
+ users_query.each_batch(size: 2) do |page|
209
+ users_batch << page
210
+ end
211
+
212
+ users_batch.size.must_equal 5
213
+ i = 1
214
+ users_batch.each do |user_page|
215
+ user_page.must_equal [User.new(id: i, name: "User #{i}"), User.new(id: i+1, name: "User #{i+1}")]
216
+ i += 2
217
+ end
218
+ end
219
+
151
220
  it 'Where' do
152
221
  users_query.where(id: 3).all.must_equal [User.new(id: 3, name: 'User 3')]
153
222
  end
154
-
223
+
155
224
  it 'Exclude' do
156
225
  users_query.exclude(id: [1,2,3,4,5,6,7,8,9]).all.must_equal [User.new(id: 10, name: 'User 10')]
157
226
  end
158
-
227
+
159
228
  it 'And' do
160
229
  users_query.where(id: [1,2]).where(name: 'User 2').all.must_equal [User.new(id: 2, name: 'User 2')]
161
230
  end
162
-
231
+
163
232
  it 'Or' do
164
233
  users_query.where(id: 1).or(name: 'User 2').all.must_equal [
165
- User.new(id: 1, name: 'User 1'),
234
+ User.new(id: 1, name: 'User 1'),
166
235
  User.new(id: 2, name: 'User 2')
167
236
  ]
168
237
  end
169
-
238
+
170
239
  it 'Order' do
171
240
  posts_query.order(:title).all.must_equal [
172
- Post.new(id: 2, user_id: 1, title: 'Another post', body: '...', language_id: 1),
173
- Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1),
241
+ Post.new(id: 2, user_id: 1, title: 'Another post', body: '...', language_id: 1),
242
+ Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1),
174
243
  Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...', language_id: 1)
175
244
  ]
176
245
  end
177
-
246
+
178
247
  it 'Reverse order' do
179
248
  posts_query.reverse_order(:title).all.must_equal [
180
249
  Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...', language_id: 1),
181
- Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1),
250
+ Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1),
182
251
  Post.new(id: 2, user_id: 1, title: 'Another post', body: '...', language_id: 1)
183
252
  ]
184
253
  end
185
-
254
+
186
255
  it 'Limit and offset' do
187
256
  users_query.limit(1).offset(1).all.must_equal [User.new(id: 2, name: 'User 2')]
188
257
  end
189
-
258
+
190
259
  it 'First' do
191
260
  users_query.first.must_equal User.new(id: 1, name: 'User 1')
192
261
  end
@@ -203,21 +272,21 @@ describe 'Query' do
203
272
  language = Language.new id: 1, name: 'Spanish'
204
273
 
205
274
  person = Person.new user_id: 2,
206
- document_number: 'document_2',
207
- first_name: 'Name 2',
208
- last_name: 'Last Name 2',
275
+ document_number: 'document_2',
276
+ first_name: 'Name 2',
277
+ last_name: 'Last Name 2',
209
278
  birth_date: Date.parse('2020-04-24'),
210
279
  languages: [language]
211
280
 
212
- user = User.new id: 2,
281
+ user = User.new id: 2,
213
282
  name: 'User 2',
214
283
  person: person
215
284
 
216
- post = Post.new id: 1,
217
- user_id: 2,
285
+ post = Post.new id: 1,
286
+ user_id: 2,
218
287
  user: user,
219
- title: 'Sample post',
220
- body: '...',
288
+ title: 'Sample post',
289
+ body: '...',
221
290
  language_id: 1,
222
291
  language: language
223
292
 
@@ -323,7 +392,7 @@ describe 'Query' do
323
392
  error = proc { posts_query.nql('a + b') }.must_raise Rasti::DB::NQL::InvalidExpressionError
324
393
  error.message.must_equal 'Invalid filter expression: a + b'
325
394
  end
326
-
395
+
327
396
  it 'Filter to self table' do
328
397
  posts_query.nql('user_id > 1')
329
398
  .pluck(:user_id)
@@ -350,6 +419,138 @@ describe 'Query' do
350
419
  .must_equal [2]
351
420
  end
352
421
 
422
+ describe 'Computed Attributes' do
423
+
424
+ it 'Filter relation computed attribute' do
425
+ db[:comments].insert post_id: 1, user_id: 5, text: 'Comment 4'
426
+ users_query.nql('comments_count = 2').all.must_equal [User.new(id: 5, name: 'User 5')]
427
+ end
428
+
429
+ it 'Filter with relation computed attribute with "and" combined' do
430
+ db[:comments].insert post_id: 1, user_id: 5, text: 'Comment 4'
431
+ db[:comments].insert post_id: 1, user_id: 4, text: 'Comment 3'
432
+ users_query.nql('(comments_count > 1) & (id = 5)').all.must_equal [User.new(id: 5, name: 'User 5')]
433
+ end
434
+
435
+ it 'Filter relation computed attribute with "or" combined' do
436
+ db[:comments].insert post_id: 1, user_id: 2, text: 'Comment 3'
437
+ users_query.nql('(comments_count = 2) | (id = 5)')
438
+ .order(:id)
439
+ .all
440
+ .must_equal [ User.new(id: 2, name: 'User 2'), User.new(id: 5, name: 'User 5') ]
441
+ end
442
+
443
+ it 'Filter relation computed attribute with "and" and "or" combined' do
444
+ db[:comments].insert post_id: 1, user_id: 2, text: 'Comment 3'
445
+ users_query.nql('((comments_count = 2) | (id = 5)) & (name: User 5)')
446
+ .order(:id)
447
+ .all
448
+ .must_equal [ User.new(id: 5, name: 'User 5') ]
449
+ end
450
+
451
+ it 'Filter simple computed attribute' do
452
+ person_expected = Person.new user_id: 1,
453
+ document_number: 'document_1',
454
+ first_name: 'Name 1',
455
+ last_name: 'Last Name 1',
456
+ birth_date: Date.parse('2020-04-24')
457
+
458
+ people_query.nql('full_name = Name 1 Last Name 1')
459
+ .all
460
+ .must_equal [person_expected]
461
+ end
462
+
463
+ end
464
+
465
+ describe 'Filter Array' do
466
+
467
+ def filter_condition_must_raise(comparison_symbol, comparison_name)
468
+ error = proc { comments_query.nql("tags #{comparison_symbol} [fake, notice]") }.must_raise Rasti::DB::NQL::FilterConditionStrategies::UnsupportedTypeComparison
469
+ error.argument_type.must_equal Rasti::DB::NQL::FilterConditionStrategies::Types::SQLiteArray
470
+ error.comparison_name.must_equal comparison_name
471
+ error.message.must_equal "Unsupported comparison #{comparison_name} for Rasti::DB::NQL::FilterConditionStrategies::Types::SQLiteArray"
472
+ end
473
+
474
+ it 'Must raise exception from not supported methods' do
475
+ comparisons = {
476
+ greater_than: '>',
477
+ greater_than_or_equal: '>=',
478
+ less_than: '<',
479
+ less_than_or_equal: '<='
480
+ }
481
+
482
+ comparisons.each do |name, symbol|
483
+ filter_condition_must_raise symbol, name
484
+ end
485
+ end
486
+
487
+ it 'Included any of these elements' do
488
+ db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake","notice"]'
489
+ db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice 2', tags: '["notice"]'
490
+ db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice 3', tags: '["fake_notice"]'
491
+ expected_comments = [
492
+ Comment.new(id: 4, text: 'fake notice', tags: ['fake','notice'], user_id: 5, post_id: 1),
493
+ Comment.new(id: 5, text: 'fake notice 2', tags: ['notice'], user_id: 5, post_id: 1)
494
+ ]
495
+
496
+ comments_query.nql('tags: [ fake, notice ]')
497
+ .all
498
+ .must_equal expected_comments
499
+ end
500
+
501
+ it 'Included exactly all these elements' do
502
+ db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake","notice"]'
503
+ db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice 2', tags: '["notice"]'
504
+ comments_query.nql('tags = [fake, notice]')
505
+ .all
506
+ .must_equal [Comment.new(id: 4, text: 'fake notice', tags: ['fake','notice'], user_id: 5, post_id: 1)]
507
+ end
508
+
509
+ it 'Not included anyone of these elements' do
510
+ db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake","notice"]'
511
+ db[:comments].insert post_id: 1, user_id: 5, text: 'Good notice!', tags: '["good"]'
512
+ db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake"]'
513
+ expected_comments = [
514
+ Comment.new(id: 1, text: 'Comment 1', tags: [], user_id: 5, post_id: 1),
515
+ Comment.new(id: 2, text: 'Comment 2', tags: [], user_id: 7, post_id: 1),
516
+ Comment.new(id: 3, text: 'Comment 3', tags: [], user_id: 2, post_id: 2),
517
+ Comment.new(id: 5, text: 'Good notice!', tags: ['good'], user_id: 5, post_id: 1)
518
+ ]
519
+ comments_query.nql('tags !: [fake, notice]')
520
+ .all
521
+ .must_equal expected_comments
522
+ end
523
+
524
+ it 'Not include any of these elements' do
525
+ db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake","notice"]'
526
+ db[:comments].insert post_id: 1, user_id: 5, text: 'Good notice!', tags: '["good"]'
527
+ db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake"]'
528
+ expected_comments = [
529
+ Comment.new(id: 1, text: 'Comment 1', tags: '[]', user_id: 5, post_id: 1),
530
+ Comment.new(id: 2, text: 'Comment 2', tags: '[]', user_id: 7, post_id: 1),
531
+ Comment.new(id: 3, text: 'Comment 3', tags: '[]', user_id: 2, post_id: 2),
532
+ Comment.new(id: 5, text: 'Good notice!', tags: ['good'], user_id: 5, post_id: 1),
533
+ Comment.new(id: 6, text: 'fake notice', tags: ['fake'], user_id: 5, post_id: 1)
534
+ ]
535
+ comments_query.nql('tags != [fake, notice]')
536
+ .all
537
+ .must_equal expected_comments
538
+ end
539
+
540
+ it 'Include any like these elements' do
541
+ db[:comments].insert post_id: 1, user_id: 5, text: 'fake notice', tags: '["fake","notice"]'
542
+ db[:comments].insert post_id: 1, user_id: 5, text: 'this is a fake notice!', tags: '["fake_notice"]'
543
+ expected_comments = [
544
+ Comment.new(id: 4, text: 'fake notice', tags: ['fake','notice'], user_id: 5, post_id: 1),
545
+ Comment.new(id: 5, text: 'this is a fake notice!', tags: ['fake_notice'], user_id: 5, post_id: 1)
546
+ ]
547
+ comments_query.nql('tags ~ [fake]')
548
+ .all
549
+ .must_equal expected_comments
550
+ end
551
+
552
+ end
553
+
353
554
  end
354
555
 
355
556
  end