msfl 1.1.5 → 1.1.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 177a30d02e7d96f90d3a86fd31804f7dcfacae54
4
- data.tar.gz: 5e6ddff54fcc8f8380e51967a81b6a8b48931ec8
3
+ metadata.gz: 9034a3e616954189429dc66d76be624f065b5f9b
4
+ data.tar.gz: 8ef828b22da3158dc126e3d8ae8a148bdf82f9b9
5
5
  SHA512:
6
- metadata.gz: 69c76fe997453a7ad780a7ebeb6f91558777075b5f2085c6aa2c2b0a4282d10c91eec1e18fa7267c0c058ddb9eeb6f129b446352bacaf55565aa60ea4e46af76
7
- data.tar.gz: 1329571a071f77f574acd92223f79d7fad3dfbf94a63a4d88eca1acc782a354a336ae20120f73a8dc68b92a54721aa4529d180e9e0ce51d63583e9fb9083d79a
6
+ metadata.gz: fe03bb90fc8cd612c5914217600a02dfb3a8fd4a5e08e6f701b5e80cdb704f8128e8335c245300d7a2ed6ad2d45b051ac804b496b7386f7350f3484aecf0975d
7
+ data.tar.gz: 920a0e38dbf3256d45695c60dced75252ddff4d8cf7babaa63825da13b72fb36c220dc13f08ccf364474b0478eb888c7854d01479b39c5e5562865b71ec24fc5
data/README.md CHANGED
@@ -1,5 +1,83 @@
1
- [![Circle CI](https://circleci.com/gh/caldwecr/msfl.svg?style=svg)](https://circleci.com/gh/caldwecr/msfl)
1
+ [![Circle CI](https://circleci.com/gh/Referly/msfl.svg?style=svg)](https://circleci.com/gh/Referly/msfl)
2
2
 
3
3
  # Ruby Gem for the Mattermark Semantic Filter Language
4
4
 
5
- Contains serializers and validators (and perhaps other) MSFL goodies
5
+ Contains serializers and validators (and perhaps other) MSFL goodies
6
+
7
+ ## EBNF
8
+
9
+ MSFL is a context-free language. The context-free grammar is defined below.
10
+
11
+ I'm not actually sure this is correct, it is definitely not comprehensive as it skips over the shortcut functionality.
12
+
13
+ ```
14
+ filter = range_op | binary_op | set_op
15
+ set_op = and | or
16
+ and = "{" "\"and\"" ":" list "}"
17
+ or = "{" "\"or\"" ":" list "}"
18
+ list = "[" filter? | (filter ("," filter)*) "]";
19
+ range_op = between;
20
+ between = "{" field ":" between_body | "{" "\"between\"" ":" between_body "}";
21
+ between_body = "{" "\"start\"" ":" between_start "," "\"end\"" ":" between_end "}";
22
+ between_start = integer | double | date | datetime | time;
23
+ between_end = integer | double | date | datetime | time;
24
+ binary_op = comparison | containment;
25
+ comparison = "{" field ":" "{" comparison_op ":" atom "}" "}";
26
+ field = "\"" ALPHANUMERIC+ "\"";
27
+ comparison_op = "lt" | "gt" | "lte" | "gte" | "eq";
28
+ containment = "{" field ":" "{" "\"in\"" ":" atom_list "}" "}";
29
+ atom = string | integer | double | boolean | date | datetime | time;
30
+ atom_list = "[" atom? | (atom ("," atom)*) "]";
31
+ ```
32
+
33
+ ## Configuration
34
+
35
+ All configuration options should be set in a block passed to `MSFL.configure { |c| c.datasets = [] }`
36
+
37
+ Naturally you should provide an appropriate array of the datasets you are supporting.
38
+
39
+ As additional configuration settings are added they will be set similarly.
40
+
41
+ ## Converters
42
+
43
+ The MSFL converters provide convenience methods for transforming a parsed MSFL tree to a different structure that is
44
+ logically equivalent. The intent is to enable consumers of MSFL to easily manipulate parsed MSFL filters into the form
45
+ that most easily or efficiently allows adaptation to the storage mechanism upon which the filtering is being effected.
46
+
47
+ Note that the order in which converters are run is controlled by the constant MSFL::Converters::CONVERSIONS and cannot
48
+ be manipulated through configuration. This behavior is currently necessary for ease of implementation but is unlikely
49
+ to continue to be status quo.
50
+
51
+ ## Datasets
52
+
53
+ The consumer of the MSFL gem defines one or more datasets. The dataset definition enumerates the supported fields and
54
+ their types.
55
+
56
+ ## Parsers
57
+
58
+ Currently there is only a parser for the JSON encoding of MSFL filters. Any additional parsers will also be placed
59
+ under this directory.
60
+
61
+ ## Types
62
+
63
+ Because of the behavioral limitations imposed on certain types (currently Sets are the only example) there is a folder
64
+ for types to be defined.
65
+
66
+ ## Validators
67
+
68
+ After parsing a MSFL filter it can be validated. Currently the validation is primitive. The intent is to enable
69
+ semantic validation on a per dataset basis. This will allow per attribute validations to be setup by the consumer
70
+ of this gem, which will be run automatically during validation.
71
+
72
+ ## Frameworks
73
+
74
+ ### Sinatra
75
+
76
+ There are several helper methods for using this gem with Sinatra. You can register the helpers in your Sinatra app
77
+ by adding the following inside of your application's class.
78
+
79
+ ```
80
+ # This should actually be Sinatra::MSFL but there are some namespacing issues with MSFL currently that prevented
81
+ # this from being the v0 implementation. This will change in the near future.
82
+ register MSFL::Sinatra
83
+ ```
@@ -116,8 +116,9 @@ module MSFL
116
116
  if obj[first_key].is_a?(Hash)
117
117
  result = implicit_and_to_explicit_recursively obj[first_key], first_key
118
118
  elsif obj[first_key].is_a? MSFL::Types::Set
119
- # This situation occurs when there are nested logical operators
120
- # obj is a hash, with one key that is not a binary operator which has a value that is a MSFL::Types::Set
119
+ # When an implicit and occurs under an MSFL::Types::Set when the key for the value which is the set
120
+ # is not a binary or logical operator. This doesn't happen in known current cases.
121
+ # ex. => { foo: [ { bar: { gte: 1, lte: 5 } } ] }
121
122
  result = Hash.new
122
123
  result[first_key] = recurse_through_set :implicit_and_to_explicit_recursively, obj[first_key]
123
124
  elsif obj[first_key].is_a? Array
data/msfl.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'msfl'
3
- s.version = '1.1.5'
3
+ s.version = '1.1.6'
4
4
  s.date = '2015-04-01'
5
5
  s.summary = "MSFL in Ruby"
6
6
  s.description = "Serializers, validators, and other tasty goodness for the Mattermark Semantic Filter Language in Ruby."
@@ -140,6 +140,24 @@ describe "MSFL::Converters::Operator" do
140
140
 
141
141
  let(:expected) { raise ArgumentError, "You are expected to define the expected value" }
142
142
 
143
+ context "when the argument is an Array" do
144
+
145
+ let(:arg) { ["foo", "bar"] }
146
+
147
+ it "raises an ArgumentError" do
148
+ expect { subject }.to raise_error ArgumentError
149
+ end
150
+ end
151
+
152
+ context "when the argument is a Hash containing an Array" do
153
+
154
+ let(:arg) { { and: [ { foo: 1 }, { bar: 2 } ] } }
155
+
156
+ it "raises an ArgumentError" do
157
+ expect { subject }.to raise_error ArgumentError
158
+ end
159
+ end
160
+
143
161
  context "when there is not an implicit BETWEEN" do
144
162
 
145
163
  ["foo", { foo: "bar" }, 123, 56.12, :aaaah].each do |arg|
@@ -255,9 +273,9 @@ describe "MSFL::Converters::Operator" do
255
273
  end
256
274
  end
257
275
 
258
- describe "#implicit_and_to_explicit" do
276
+ describe "#implicit_and_to_explicit_recursively" do
259
277
 
260
- subject(:mut) { test_instance.implicit_and_to_explicit_recursively arg }
278
+ subject { test_instance.implicit_and_to_explicit_recursively arg }
261
279
 
262
280
  let(:test_instance) { MSFL::Converters::Operator.new }
263
281
 
@@ -274,7 +292,7 @@ describe "MSFL::Converters::Operator" do
274
292
  let(:arg) { 50 }
275
293
 
276
294
  it "is the arg unchanged" do
277
- expect(mut).to eq expected
295
+ expect(subject).to eq expected
278
296
  end
279
297
  end
280
298
 
@@ -283,7 +301,7 @@ describe "MSFL::Converters::Operator" do
283
301
  let(:arg) { { gte: 1000 } }
284
302
 
285
303
  it "is the arg unchanged" do
286
- expect(mut).to eq expected
304
+ expect(subject).to eq expected
287
305
  end
288
306
  end
289
307
 
@@ -292,7 +310,7 @@ describe "MSFL::Converters::Operator" do
292
310
  let(:arg) { { value: { gte: 1000 } } }
293
311
 
294
312
  it "is the arg unchanged" do
295
- expect(mut).to eq expected
313
+ expect(subject).to eq expected
296
314
  end
297
315
  end
298
316
 
@@ -310,7 +328,7 @@ describe "MSFL::Converters::Operator" do
310
328
  ])}}
311
329
 
312
330
  it "converts the implicit AND to an explicit AND" do
313
- expect(mut).to eq expected
331
+ expect(subject).to eq expected
314
332
  end
315
333
  end
316
334
 
@@ -325,7 +343,7 @@ describe "MSFL::Converters::Operator" do
325
343
  ])}}
326
344
 
327
345
  it "converts the implicit AND to an explicit AND" do
328
- expect(mut).to eq expected
346
+ expect(subject).to eq expected
329
347
  end
330
348
  end
331
349
 
@@ -347,7 +365,7 @@ describe "MSFL::Converters::Operator" do
347
365
  end
348
366
 
349
367
  it "converts both of the implicit ANDs to explicit ANDs" do
350
- expect(mut).to eq expected
368
+ expect(subject).to eq expected
351
369
  end
352
370
  end
353
371
  end
@@ -375,14 +393,65 @@ describe "MSFL::Converters::Operator" do
375
393
  end
376
394
 
377
395
  it "converts all of the implicit ANDs" do
378
- expect(mut).to eq expected
396
+ expect(subject).to eq expected
397
+ end
398
+ end
399
+
400
+ context "when the implicit AND is under an MSFL::Types::Set" do
401
+
402
+ let(:arg) do
403
+ {
404
+ foo: MSFL::Types::Set.new([
405
+ { bar: { gte: 1, lte: 5 } }
406
+ ])
407
+ }
408
+ end
409
+
410
+ let(:expected) do
411
+ {
412
+ foo: MSFL::Types::Set.new([
413
+ { and: MSFL::Types::Set.new([
414
+ { bar: { gte: 1 } },
415
+ { bar: { lte: 5 } }
416
+ ])}
417
+ ])
418
+ }
419
+ end
420
+
421
+ it "converts the implicit AND" do
422
+ expect(subject).to eq expected
423
+ end
424
+ end
425
+
426
+ context "when the implict AND is inside of an Array" do
427
+
428
+ let(:arg) do
429
+ { and: [ { foo: 1 }, { bar: 2 } ] }
430
+ end
431
+
432
+ it "raises an ArgumentError" do
433
+ expect { subject }.to raise_error ArgumentError
434
+ end
435
+ end
436
+
437
+ context "when the implict AND is inside of an Array that is inside of an MSFL::Types::Set" do
438
+
439
+ let(:arg) do
440
+ { foo: MSFL::Types::Set.new([
441
+ { bar: [{ score: { gte: 1, lte: 5 } }, "efg"] }
442
+ ])
443
+ }
444
+ end
445
+
446
+ it "raises an ArgumentError" do
447
+ expect { subject }.to raise_error ArgumentError
379
448
  end
380
449
  end
381
450
  end
382
451
 
383
452
  describe "#between_to_gte_lte_recursively" do
384
453
 
385
- subject(:mut) { test_instance.between_to_gte_lte_recursively arg }
454
+ subject { test_instance.between_to_gte_lte_recursively arg }
386
455
 
387
456
  let(:test_instance) { MSFL::Converters::Operator.new }
388
457
 
@@ -404,7 +473,7 @@ describe "MSFL::Converters::Operator" do
404
473
  let(:arg) { item }
405
474
 
406
475
  it "is equal to the argument" do
407
- expect(mut).to eq arg
476
+ expect(subject).to eq arg
408
477
  end
409
478
  end
410
479
  end
@@ -417,7 +486,7 @@ describe "MSFL::Converters::Operator" do
417
486
  let(:expected) { { foo: { gte: "2015-01-01", lte: "2015-04-01" } } }
418
487
 
419
488
  it "converts between clauses into anded gte / lte clauses" do
420
- expect(mut).to eq expected
489
+ expect(subject).to eq expected
421
490
  end
422
491
 
423
492
  context "when the between clause is below the second level" do
@@ -441,7 +510,7 @@ describe "MSFL::Converters::Operator" do
441
510
  end
442
511
 
443
512
  it "recursively converts between clauses into anded gte / lte clauses" do
444
- expect(mut).to eq expected
513
+ expect(subject).to eq expected
445
514
  end
446
515
  end
447
516
  end
@@ -453,7 +522,7 @@ describe "MSFL::Converters::Operator" do
453
522
  let(:expected) { MSFL::Types::Set.new([ { foo: { gte: 1, lte: 5 } } ]) }
454
523
 
455
524
  it "recursively converts between clauses into anded gte / lte clauses" do
456
- expect(mut).to eq expected
525
+ expect(subject).to eq expected
457
526
  end
458
527
 
459
528
  context "when the between clause is below the second level" do
@@ -463,7 +532,7 @@ describe "MSFL::Converters::Operator" do
463
532
  let(:expected) { MSFL::Types::Set.new([ { and: MSFL::Types::Set.new([{ foo: { gte: 1, lte: 5} }, { bar: 123} ]) }]) }
464
533
 
465
534
  it "recursively converts between clauses into anded gte / lte clauses" do
466
- expect(mut).to eq expected
535
+ expect(subject).to eq expected
467
536
  end
468
537
  end
469
538
  end
@@ -473,7 +542,7 @@ describe "MSFL::Converters::Operator" do
473
542
  let(:arg) { [ { foo: { between: { start: 1, end: 5 } } } ] }
474
543
 
475
544
  it "raises an ArgumentError" do
476
- expect { mut }.to raise_error ArgumentError
545
+ expect { subject }.to raise_error ArgumentError
477
546
  end
478
547
  end
479
548
 
@@ -500,7 +569,7 @@ describe "MSFL::Converters::Operator" do
500
569
  end
501
570
 
502
571
  it "recursively converts between clauses into anded gte / lte clauses" do
503
- expect(mut).to eq expected
572
+ expect(subject).to eq expected
504
573
  end
505
574
  end
506
575
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msfl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
4
+ version: 1.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Courtland Caldwell