msfl 0.0.1.pre.qa → 0.0.1.pre.rc1

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: 5192c432f2b0fa92fdc52f791a6d1db94e0e7273
4
- data.tar.gz: 369cf6c5d51a3b2f996b070a70894a6fd952b7f4
3
+ metadata.gz: 1433fb3fe0766b9a5a4913a5c8236bffb00e9c5e
4
+ data.tar.gz: 9307024455e4e75530f334e4c91d2a09f7da7090
5
5
  SHA512:
6
- metadata.gz: dadc0e105e90e00c982424d332a2cada2733a676cf9c26f0d65ab3c5a79e4ffe94c78b87903c493aa070ae0c80f813eb1bf6313cd81531593911fde0f0c3b1bf
7
- data.tar.gz: 86c9aac383c3a267e9344ca3f081b4b1e9fd8c461ca5e86a5962e3811476dad04ac918c521cc9dc0011811e5029caca9ec14858bd9b83ad313a8c0a1c45d6561
6
+ metadata.gz: 1a7ac56dec38d01c8dcec0521e27cb03f361d952d8309d72bfa6494e9b5b49c8e34a89d1f2e98c66742a885110519ecd41ea24d3aa05b2508b1eeb20155244e3
7
+ data.tar.gz: 8a8150eb7c2ded7f183e7f124167a2dd3de92477cdc52731ee6868599625b344308c80bb5707230e51847ba11ad6a0635129a69a77887b112d570ffc3c2df6b5
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ ### Ruby template
2
+ *.gem
3
+ *.rbc
4
+ /coverage/
5
+ /spec/reports/
6
+
7
+ ## Documentation cache and generated files:
8
+ /.yardoc/
9
+ /_yardoc/
10
+ /doc/
11
+ /rdoc/
12
+
13
+ ## Environment normalisation:
14
+ /.bundle/
15
+ /lib/bundler/man/
16
+ .idea/
17
+
18
+ ## Gemfile for development
19
+ #Gemfile
20
+ #Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+ gem 'simplecov', :require => false, :group => :test # MIT https://github.com/colszowka/simplecov/blob/master/MIT-LICENSE
3
+ gem 'yard' # MIT https://github.com/lsegal/yard/blob/master/LICENSE + Ruby license for one file from the Ruby source lib/parser/ruby/legacy/ruby_lex.rb
4
+ gem 'rspec' # MIT https://github.com/rspec/rspec/blob/master/License.txt
5
+ gem 'byebug'
data/Gemfile.lock ADDED
@@ -0,0 +1,40 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ byebug (3.5.1)
5
+ columnize (~> 0.8)
6
+ debugger-linecache (~> 1.2)
7
+ slop (~> 3.6)
8
+ columnize (0.8.9)
9
+ debugger-linecache (1.2.0)
10
+ diff-lcs (1.2.5)
11
+ docile (1.1.5)
12
+ multi_json (1.10.1)
13
+ rspec (3.1.0)
14
+ rspec-core (~> 3.1.0)
15
+ rspec-expectations (~> 3.1.0)
16
+ rspec-mocks (~> 3.1.0)
17
+ rspec-core (3.1.7)
18
+ rspec-support (~> 3.1.0)
19
+ rspec-expectations (3.1.2)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.1.0)
22
+ rspec-mocks (3.1.3)
23
+ rspec-support (~> 3.1.0)
24
+ rspec-support (3.1.2)
25
+ simplecov (0.9.1)
26
+ docile (~> 1.1.0)
27
+ multi_json (~> 1.0)
28
+ simplecov-html (~> 0.8.0)
29
+ simplecov-html (0.8.0)
30
+ slop (3.6.0)
31
+ yard (0.8.7.6)
32
+
33
+ PLATFORMS
34
+ ruby
35
+
36
+ DEPENDENCIES
37
+ byebug
38
+ rspec
39
+ simplecov
40
+ yard
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2015 Mattermark, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,5 @@
1
+ [![Circle CI](https://circleci.com/gh/caldwecr/msfl.svg?style=svg)](https://circleci.com/gh/caldwecr/msfl)
2
+
3
+ # Ruby Gem for the Mattermark Semantic Filter Language
4
+
5
+ Contains serializers and validators (and perhaps other) MSFL goodies
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "rake"
2
+ require 'rspec/core/rake_task'
3
+
4
+ task default: [:spec] do
5
+ ENV['RACK_ENV'] = 'test'
6
+ end
7
+
8
+ task :spec do
9
+ RSpec::Core::RakeTask.new(:spec)
10
+ end
data/circle.yml ADDED
@@ -0,0 +1,9 @@
1
+ machine:
2
+
3
+ timezone:
4
+ America/Los_Angeles # Set the timezone
5
+
6
+ # Version of ruby to use
7
+ ruby:
8
+ version:
9
+ 2.1.3
@@ -6,7 +6,9 @@ module MSFL
6
6
 
7
7
  # The descendant class MUST override this method otherwise all field validations will fail
8
8
  #
9
- # @return [Array] the fields in the dataset
9
+ # The method defines an array of symbols, indicating what fields are supported for the Dataset
10
+ #
11
+ # @return [Array<Symbol>] the fields in the dataset
10
12
  def fields
11
13
  raise NoMethodError, "Descendants of MSFL::Datasets::Base are required to implement the #fields method"
12
14
  end
@@ -14,11 +16,14 @@ module MSFL
14
16
  # The descendant class may override this method to control the operators that are supported for the dataset
15
17
  # - Note that this can only be used to reduce the number of supported operators (you can't add new operators
16
18
  # here, without first adding them to MSFL::Validators::Definitions::HashKey#hash_key_operators)
19
+ #
20
+ # @return [Array<Symbol>] the operators supported in the dataset
17
21
  def operators
18
22
  hash_key_operators
19
23
  end
20
24
 
21
- # Method not implemented at this time
25
+ # This method returns the errors argument. The errors argument is unchanged if type conformity validation passes,
26
+ # otherwise an error is added to errors.
22
27
  #
23
28
  # @param obj [Object] the object that should be type checked based on the field argument
24
29
  # @param field [Symbol] which field should the object be checked for conformity
@@ -30,11 +35,14 @@ module MSFL
30
35
  # # because the type of total_funding must be an integer
31
36
  #
32
37
  def validate_type_conforms(obj, field, errors)
38
+ errors << "Dataset type conformity validation failed for obj: #{obj} against field: #{field}" unless type_conforms?(obj, field)
33
39
  errors
34
40
  end
35
41
 
36
42
  # Method not implemented at this time
37
43
  # Returns true if the object conforms to the types supported by the indicated field
44
+ # While not currently implemented the intent is that the descendant Dataset would specify a hash of supported
45
+ # types for each field and this method would then cross reference that list.
38
46
  #
39
47
  # @param obj [Object] the object that should be type checked based on the field argument
40
48
  # @param field [Symbol] which field should the object be checked for conformity
@@ -42,19 +50,33 @@ module MSFL
42
50
  true
43
51
  end
44
52
 
45
- # Method not implemented at this time
46
- #
53
+ # This method returns the errors argument. The errors argument is unchanged if operator conformity validation
54
+ # passes, otherwise an error is added to errors.
47
55
  #
48
56
  # @param operator [Symbol] the operator that we want to know if the particular field supports it
49
57
  # @param field [Symbol] which field should the operator be checked for conformity
50
58
  # @param errors [Array] an array of validation errors - empty indicates that no errors have been encountered
51
59
  # @return [Array] errors merged with any validation errors encountered in validating the set
52
60
  def validate_operator_conforms(operator, field, errors)
61
+ errors << "Dataset operator conformity validation failed for operator: #{operator} against field: #{field}" unless operator_conforms?(operator, field)
53
62
  errors
54
63
  end
55
64
 
56
65
  # Method not implemented at this time
57
66
  #
67
+ # This method returns true if the operator is supported for the specified field by the dataset. While this
68
+ # is not currently implemented, the intent is that a hash of fields (as keys) would map to
69
+ # Arrays<Symbol> (as values) and then this method would validate that the operator argument meets this contract.
70
+ #
71
+ # @param operator [Symbol] the operator that needs to be checked for conformity
72
+ # @param field [Symbol] which field should the operator be checked against
73
+ # @return [Bool] true if the operator conforms, false otherwise
74
+ def operator_conforms?(operator, field)
75
+ true
76
+ end
77
+
78
+ # This method returns the errors argument. The errors argument is unchanged if value conformity validation
79
+ # passes, otherwise an error is added to errors.
58
80
  #
59
81
  # @param value [Object] the precoerced value (the value must be correctly typed)
60
82
  # that should be checked for validity based on the field, if the value does not conform an
@@ -72,8 +94,28 @@ module MSFL
72
94
  # foo.investors_value_conforms(12345, :total_funding) => # errors is unchanged
73
95
  #
74
96
  def validate_value_conforms(value, field, errors)
97
+ errors << "Dataset value conformity validation failed for value: #{value} against field: #{field}" unless value_conforms?(value, field, errors)
75
98
  errors
76
99
  end
100
+
101
+ # Method not implemented at this time
102
+ #
103
+ # This method returns true if the value is supported for the specified field by the dataset. While this is not
104
+ # currently implemented, the intent is that a hash of fields (as keys) would map to an Array of validation
105
+ # constraints. These constraints would then be executed against the value and if all are successful the value
106
+ # would be considered to have passed.
107
+ #
108
+ # It is likely that the methods invoked from the Array of validation constraints would actually return an Array
109
+ # of errors encountered, this method would then concat that Array into the errors array. If the encountered errors
110
+ # array is empty the method would return true, and false otherwise.
111
+ #
112
+ # @param value [Object] the object to on which to perform validation
113
+ # @param field [Symbol] the field the object should be validated against
114
+ # @param errors [Array] the array of errors from prior validations
115
+ # @return [Bool] true if no new errors are encountered, false otherwise
116
+ def value_conforms?(value, field, errors = [])
117
+ true
118
+ end
77
119
  end
78
120
  end
79
121
  end
@@ -2,12 +2,21 @@ require 'json'
2
2
  module MSFL
3
3
  module Parsers
4
4
  class JSON
5
+
6
+ # Parses json encoded MSFL into Ruby encoded MSFL
7
+ #
8
+ # @param json [String] the string to parse
9
+ # @return [Object] the Ruby encoded MSFL, which may be a Hash, MSFL::Types::Set, or any number of scalar types
5
10
  def self.parse(json)
6
11
  obj = ::JSON.parse(json)
7
12
  obj = arrays_to_sets obj
8
13
  obj
9
14
  end
10
15
 
16
+ # Converts Ruby Arrays is a partially parsed Ruby MSFL filter to MSFL::Types::Set objects
17
+ #
18
+ # @param obj [Object] the object in which to convert Ruby Array objects to MSFL::Types::Set objects
19
+ # @return [Object] the result of converting Ruby Arrays to MSFL::Types::Set objects
11
20
  def self.arrays_to_sets(obj)
12
21
  obj = Types::Set.new obj if obj.is_a?(::Array)
13
22
  if obj.respond_to? :each
@@ -11,8 +11,18 @@ module MSFL
11
11
  BOOLEAN_OPERATORS = [:and, :or]
12
12
  ENUMERATION_OPERATORS = [:in]
13
13
 
14
- def initialize(attributes = nil, opts = {})
15
- @dataset = MSFL.configuration.datasets.first.new unless MSFL.configuration.datasets.empty?
14
+ # Used for creating new semantic validator instances
15
+ #
16
+ # If the dataset argument is specified it will be used as the dataset for the validator. Otherwise
17
+ # the instance's dataset will default to the first value in MSFL.configuration.datasets, unless it is empty,
18
+ # in which case it will revert to MSFL::Datasets::Base, which will deliberately break execution when #validate
19
+ # is called on the validator instance, raising a NoMethodError.
20
+ #
21
+ # @param dataset [MSFL::Dataset::Base] optionally override the dataset instance that should be used by the validator
22
+ # @param opts [Hash] optional; currently not used, included for future additions
23
+ def initialize(dataset = nil, opts = {})
24
+ @dataset = dataset unless dataset.nil?
25
+ @dataset ||= MSFL.configuration.datasets.first.new unless MSFL.configuration.datasets.empty?
16
26
  @dataset ||= Datasets::Base.new
17
27
  @current_field = nil
18
28
  @current_operator = nil
data/msfl.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'msfl'
3
+ s.version = '0.0.1-rc1'
4
+ s.date = '2015-03-05'
5
+ s.summary = "MSFL in Ruby"
6
+ s.description = "Serializers, validators, and other tasty goodness for the Mattermark Semantic Filter Language in Ruby."
7
+ s.authors = ["Courtland Caldwell"]
8
+ s.email = 'courtland@mattermark.com'
9
+ s.files = `git ls-files`.split("\n")
10
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
11
+ s.homepage =
12
+ 'https://github.com/caldwecr/msfl'
13
+ s.add_runtime_dependency "json", "~> 1.7"
14
+ s.add_development_dependency "rake", "~> 10.3"
15
+ s.add_development_dependency "simplecov", "~> 0.9"
16
+ s.add_development_dependency "yard", "~> 0.8"
17
+ s.add_development_dependency "rspec", "~> 3.1"
18
+ s.add_development_dependency "byebug", "~> 3.5"
19
+ s.license = "MIT"
20
+ end
@@ -0,0 +1,5 @@
1
+ require 'simplecov'
2
+ SimpleCov.profiles.define 'msfl' do
3
+ add_filter '/spec'
4
+ add_filter '/test'
5
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe "MSFL::Datasets::Base" do
4
+
5
+ let(:test_instance) { MSFL::Datasets::Movies.new }
6
+
7
+ let(:errors) { [ ] }
8
+
9
+ let(:field) { :title }
10
+
11
+ describe "#fields" do
12
+
13
+ it "raises a NoMethodError" do
14
+ expect { MSFL::Datasets::Base.new.fields }.to raise_error NoMethodError
15
+ end
16
+ end
17
+
18
+ describe "#validate_type_conforms" do
19
+
20
+ subject(:mut) { test_instance.validate_type_conforms obj, field, errors }
21
+
22
+ let(:obj) { "i am a string" }
23
+
24
+ it "is currently a stubbed method that just returns the errors argument" do
25
+ expect(mut).to eq errors
26
+ end
27
+ end
28
+
29
+ describe "#type_conforms?" do
30
+
31
+ context "when MSFL is configured to use Movies as the dataset" do
32
+
33
+ subject(:mut) { test_instance.type_conforms? obj, field }
34
+
35
+ let(:obj) { "i am a string" }
36
+
37
+ it "is true for types that conform to the Dataset" do
38
+ expect(mut).to eq true
39
+ end
40
+
41
+ it "is false for types that do not conform to the Dataset" do
42
+ pending "Dataset specific semantic validation is not yet implemented."
43
+ expect(mut).to eq false
44
+ end
45
+ end
46
+ end
47
+
48
+ describe "#validate_operator_conforms" do
49
+
50
+ subject(:mut) { test_instance.validate_operator_conforms operator, field, errors }
51
+
52
+ let(:operator) { :and }
53
+
54
+ it "is currently a stubbed method that just returns the errors argument" do
55
+ expect(mut).to eq errors
56
+ end
57
+ end
58
+
59
+ describe "#validate_value_conforms" do
60
+
61
+ subject(:mut) { test_instance.validate_value_conforms value, field, errors }
62
+
63
+ let(:value) { 1234 }
64
+
65
+ it "is currently a stubbed method that just returns the errors argument" do
66
+ expect(mut).to eq errors
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,146 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ # Still need to deal with duplicates in array scenarios - is there a nested array variation with a non-obvious deduplication consequence?
5
+ describe "MSFL::Parsers::JSON" do
6
+ describe ".parse" do
7
+
8
+ subject(:mut) { MSFL::Parsers::JSON.parse test_json }
9
+
10
+ let(:test_json) { '{"total_funding": 5000000}' }
11
+
12
+ context "when parsing a json hash" do
13
+
14
+ it "is an equivalent Ruby Hash" do
15
+ expect(mut).to eq({ :total_funding => 5000000 })
16
+ end
17
+ end
18
+
19
+ context "when parsing a json array" do
20
+
21
+ let(:test_json) { '["abc", "def"]' }
22
+
23
+ it { is_expected.to be_a MSFL::Types::Set }
24
+ end
25
+
26
+ end
27
+
28
+ describe ".arrays_to_sets" do
29
+
30
+ subject(:mut) { MSFL::Parsers::JSON.arrays_to_sets arg }
31
+
32
+ let(:arg) { Object.new }
33
+
34
+ [55, "five", :fourty, nil].each do |item|
35
+ context "when the argument is a #{item.class}" do
36
+
37
+ let(:arg) { item }
38
+
39
+ it "is equal to the argument" do
40
+ expect(mut).to eq arg
41
+ end
42
+ end
43
+ end
44
+
45
+ context "when the argument is a Hash" do
46
+
47
+ context "when the hash's values are scalars" do
48
+
49
+ let(:arg) { { foo: "bar", cat: 1337 } }
50
+
51
+ it "is equal to the argument" do
52
+ expect(mut).to eq arg
53
+ end
54
+ end
55
+
56
+ context "when the hash's values include at least one Hash" do
57
+
58
+ let(:arg) do
59
+ { foo: { bar: "bar" }, abc: 123 }
60
+ end
61
+
62
+ it "is equal to the argument" do
63
+ expect(mut).to eq arg
64
+ end
65
+ end
66
+
67
+ context "when the hash's values include at least one Array" do
68
+
69
+ let(:arg) do
70
+ { inner_array: array_in_arg, abc: 123 }
71
+ end
72
+
73
+ let(:expected) do
74
+ { inner_array: MSFL::Types::Set.new(array_in_arg), abc: 123 }
75
+ end
76
+
77
+ let(:array_in_arg) { ["bar", "baz"] }
78
+
79
+ it "is the argument with the Array converted to a MSFL::Types::Set" do
80
+ expect(mut).to eq expected
81
+ end
82
+
83
+ context "when at least one included Array has a duplicate item" do
84
+
85
+ let(:array_in_arg) { ["cat", "cat", 44, 55, "dog", 44, :marco, :polo, nil, :polo, "cat", nil] }
86
+
87
+ it "includes the duplicate item(s) exactly once" do
88
+ expect(mut[:inner_array]).to eq MSFL::Types::Set.new(["cat", 44, 55, "dog", :marco, :polo, nil])
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ context "when the argument is an Array" do
95
+
96
+ let(:arg) { [:foo, "bar", nil, 99, "bar"] }
97
+
98
+ it { is_expected.to be_a MSFL::Types::Set }
99
+
100
+ it "is unordered" do
101
+ expect(mut).to eq MSFL::Types::Set.new(arg.shuffle)
102
+ end
103
+
104
+ it "is deduplicated" do
105
+ expect(mut).to eq MSFL::Types::Set.new([:foo, "bar", nil, 99])
106
+ end
107
+
108
+ context "when the array's values are scalars" do
109
+
110
+ let(:arg) { ["bar", 1337] }
111
+
112
+ it "is equal to MSFL::Types::Set.new(argument)" do
113
+ expect(mut).to eq(MSFL::Types::Set.new arg)
114
+ end
115
+ end
116
+
117
+ context "when the argument includes at least one Hash" do
118
+
119
+ let(:arg) { ["bar", hash_in_arg, 84] }
120
+
121
+ let(:hash_in_arg) { { cat: 1221, dog: "fur" } }
122
+
123
+ it "includes the hash from the argument" do
124
+ expect(mut).to include hash_in_arg
125
+ end
126
+ end
127
+
128
+ context "when the argument includes at least one Array" do
129
+
130
+ let(:arg) { ["bar", array_in_arg, 84] }
131
+
132
+ let(:array_in_arg) { [444.3, "where'swaldo"] }
133
+
134
+ let(:expected_result) { MSFL::Types::Set.new ["bar", MSFL::Types::Set.new(array_in_arg), 84] }
135
+
136
+ it "replaces the outer Array with an equivalent MSFL::Types::Set" do
137
+ expect(mut).to eq expected_result
138
+ end
139
+
140
+ it "replaces the inner Array with an equivalent MSFL::Types::Set" do
141
+ expect(mut).to include MSFL::Types::Set.new(array_in_arg)
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
File without changes
@@ -0,0 +1,124 @@
1
+ require 'spec_helper'
2
+
3
+ describe "MSFL::Validators::Semantic" do
4
+
5
+ describe "#initialize" do
6
+
7
+ subject(:mut) { MSFL::Validators::Semantic.new dataset }
8
+
9
+ let(:dataset) { nil }
10
+
11
+ context "when the dataset argument is specified" do
12
+
13
+ let(:dataset) { Object.new }
14
+
15
+ it "has the dataset argument's value as the dataset" do
16
+ expect(mut.dataset).to be dataset
17
+ end
18
+ end
19
+
20
+ context "when the dataset argument is not specified" do
21
+
22
+ context "when MSFL is configured for one or more datasets" do
23
+
24
+ before { MSFL.configure(reset: true) { |configuration| configuration.datasets = [MSFL::Datasets::Movies] } }
25
+
26
+ it "has an instance of the first item in MSFL.configuration.datasets (an instance of Class) as the dataset" do
27
+ expect(mut.dataset).to be_a MSFL::Datasets::Movies
28
+ end
29
+ end
30
+
31
+ context "when MSFL is not configured for any datasets" do
32
+
33
+ before { MSFL.configure(reset: true) }
34
+
35
+ it "has an instance of MSFL::Datasets::Base as the dataset" do
36
+ expect(mut.dataset).to be_a MSFL::Datasets::Base
37
+ end
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ describe "#validate_set" do
44
+
45
+ subject(:mut) { test_instance.validate_set set, errors, options }
46
+
47
+ let(:test_instance) { MSFL::Validators::Semantic.new }
48
+
49
+ let(:set) { MSFL::Types::Set.new([ ]) }
50
+
51
+ let(:errors) { [ ] }
52
+
53
+ let(:options) { { } }
54
+
55
+ context "when the errors argument has items" do
56
+
57
+ let(:errors) { [error_message] }
58
+
59
+ let(:error_message) { "This is an error message" }
60
+
61
+ it "is an array containing at least all of the error messages from the original errors argument" do
62
+ expect(mut).to include error_message
63
+ end
64
+ end
65
+
66
+ context "when opts does not have the key :parent_operator" do
67
+
68
+ let(:error_message) do
69
+ "Validate set requires the :parent_operator option be set and represented in either the BOOLEAN_OPERATORS
70
+ or ENUMERATION_OPERATORS constant"
71
+ end
72
+
73
+ it "appends an error to errors" do
74
+ expect(mut).to include error_message
75
+ end
76
+ end
77
+
78
+ context "when opts[:parent_operator] is in BOOLEAN_OPERATORS" do
79
+
80
+ let(:options) { { parent_operator: :and } }
81
+
82
+ let(:test_instance) do
83
+ t_i = MSFL::Validators::Semantic.new
84
+ allow(t_i).to receive(:validate_boolean_set) { errors }
85
+ expect(t_i).to receive(:validate_boolean_set).once.with(set, errors, options)
86
+ t_i
87
+ end
88
+
89
+ it "invokes #validate_boolean_set once with the same arguments" do
90
+ mut
91
+ end
92
+ end
93
+
94
+ context "when opts[:parent_operator] is in ENUMERATION_OPERATORS" do
95
+
96
+ let(:options) { { parent_operator: :in } }
97
+
98
+ let(:test_instance) do
99
+ t_i = MSFL::Validators::Semantic.new
100
+ allow(t_i).to receive(:validate_enumeration_set) { errors }
101
+ expect(t_i).to receive(:validate_enumeration_set).once.with(set, errors, options)
102
+ t_i
103
+ end
104
+
105
+ it "invokes #validate_enumeration_set once with the same arguments" do
106
+ mut
107
+ end
108
+ end
109
+
110
+ context "when opts[:parent_operator] is not in neither BOOLEAN_OPERATORS nor ENUMERATION_OPERATORS" do
111
+
112
+ let(:options) { { parent_operator: :not_in_either } }
113
+
114
+ let(:error_message) do
115
+ "Validate set requires the :parent_operator option be set and represented in either the BOOLEAN_OPERATORS
116
+ or ENUMERATION_OPERATORS constant"
117
+ end
118
+
119
+ it "appends an error to errors" do
120
+ expect(mut).to include error_message
121
+ end
122
+ end
123
+ end
124
+ end
data/spec/msfl_spec.rb ADDED
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+ require 'msfl/datasets/movies'
3
+ describe "MSFL" do
4
+
5
+ let(:json_encoded_msfl) do
6
+ '{
7
+ "or": [
8
+ {
9
+ "and": [
10
+ {
11
+ "title": {
12
+ "in": [
13
+ "Frozen",
14
+ "Big Hero 6",
15
+ "Apollo 13"
16
+ ]
17
+ }
18
+ },
19
+ {
20
+ "rating": {
21
+ "gte": "PG"
22
+ }
23
+ }
24
+ ]
25
+ },
26
+ {
27
+ "earnings": {
28
+ "lt": 5000000
29
+ }
30
+ }
31
+ ]
32
+ }'
33
+ end
34
+
35
+ let(:invalid_ruby_encoded_msfl) do
36
+ { not_a_field_in_dataset: "foobar" }
37
+ end
38
+
39
+ let(:ruby_encoded_msfl) do
40
+ {
41
+ or: MSFL::Types::Set.new([
42
+ {
43
+ and: MSFL::Types::Set.new([
44
+ {
45
+ title: {
46
+ in: MSFL::Types::Set.new([
47
+ "Frozen",
48
+ "Big Hero 6",
49
+ "Apollo 13"
50
+ ])
51
+ }
52
+ },
53
+ {
54
+ rating: {
55
+ gte: "PG"
56
+ }
57
+ }
58
+ ])
59
+ },
60
+ {
61
+ earnings: {
62
+ lt: 5000000
63
+ }
64
+ }
65
+ ])
66
+ }
67
+ end
68
+
69
+ let(:parser) { MSFL::Parsers::JSON }
70
+
71
+ let(:validator) { MSFL::Validators::Semantic.new }
72
+
73
+ it "is configured using a block" do
74
+ MSFL.configure(reset: true) { |configuration| configuration.datasets = [MSFL::Datasets::Movies] }
75
+ expect(MSFL.configuration.datasets).to eq [MSFL::Datasets::Movies]
76
+ end
77
+
78
+ it "parses json encoded MSFL" do
79
+ expect(parser.parse json_encoded_msfl).to eq ruby_encoded_msfl
80
+ end
81
+
82
+ it "rejects invalid MSFL filters" do
83
+ MSFL.configure(reset: true) { |conf| conf.datasets = [MSFL::Datasets::Movies] }
84
+ expect(validator.validate invalid_ruby_encoded_msfl).to be false
85
+ end
86
+
87
+ it "accepts valid MSFL filters" do
88
+ MSFL.configure(reset: true) { |conf| conf.datasets = [MSFL::Datasets::Movies] }
89
+ expect(validator.validate ruby_encoded_msfl).to be true
90
+ end
91
+ end
@@ -0,0 +1,6 @@
1
+ require_relative '../simplecov_custom_profiles'
2
+ SimpleCov.start 'msfl'
3
+ require 'rspec/support/spec'
4
+ require 'byebug'
5
+ require_relative '../lib/msfl'
6
+ require_relative 'msfl/shared_examples'
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: 0.0.1.pre.qa
4
+ version: 0.0.1.pre.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Courtland Caldwell
@@ -101,6 +101,13 @@ executables: []
101
101
  extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
+ - .gitignore
105
+ - Gemfile
106
+ - Gemfile.lock
107
+ - LICENSE
108
+ - README.md
109
+ - Rakefile
110
+ - circle.yml
104
111
  - lib/msfl.rb
105
112
  - lib/msfl/configuration.rb
106
113
  - lib/msfl/datasets.rb
@@ -114,6 +121,14 @@ files:
114
121
  - lib/msfl/validators/definitions.rb
115
122
  - lib/msfl/validators/definitions/hash_key.rb
116
123
  - lib/msfl/validators/semantic.rb
124
+ - msfl.gemspec
125
+ - simplecov_custom_profiles.rb
126
+ - spec/msfl/datasets/base_spec.rb
127
+ - spec/msfl/parsers/json_spec.rb
128
+ - spec/msfl/shared_examples.rb
129
+ - spec/msfl/validators/semantic_spec.rb
130
+ - spec/msfl_spec.rb
131
+ - spec/spec_helper.rb
117
132
  homepage: https://github.com/caldwecr/msfl
118
133
  licenses:
119
134
  - MIT
@@ -138,5 +153,11 @@ rubygems_version: 2.4.2
138
153
  signing_key:
139
154
  specification_version: 4
140
155
  summary: MSFL in Ruby
141
- test_files: []
156
+ test_files:
157
+ - spec/msfl/datasets/base_spec.rb
158
+ - spec/msfl/parsers/json_spec.rb
159
+ - spec/msfl/shared_examples.rb
160
+ - spec/msfl/validators/semantic_spec.rb
161
+ - spec/msfl_spec.rb
162
+ - spec/spec_helper.rb
142
163
  has_rdoc: