set_builder 2.0.0.beta3 → 2.0.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
@@ -30,12 +30,14 @@ var SetBuilder = (function() {
30
30
  return _modifiers;
31
31
  },
32
32
  getValueMap: function(key) {
33
- return _value_maps[key];
33
+ var valueMap = _value_maps[key];
34
+ return typeof valueMap == 'function' ? valueMap() : valueMap;
34
35
  },
35
- getValue: function(key, value) {
36
+ getValue: function(key, value, valueMap) {
37
+ var map = valueMap || SetBuilder.getValueMap(key);
36
38
  if(Object.prototype.toString.call(value) == '[object Array]') {
37
39
  var getValue = arguments.callee;
38
- var values = value.__collect(function(value) { return getValue(key, value) });
40
+ var values = value.__collect(function(value) { return getValue(key, value, map) });
39
41
  switch(values.length) {
40
42
  case 0: return '';
41
43
  case 1: return values[0];
@@ -43,9 +45,7 @@ var SetBuilder = (function() {
43
45
  default: return values.slice(0, -1).join(', ') + ', or ' + values[values.length - 1];
44
46
  }
45
47
  }
46
-
47
- var match = value.toString(),
48
- map = SetBuilder.getValueMap(key);
48
+ var match = value.toString();
49
49
  if(map) {
50
50
  var pair = map.__find(function(i) { return (i[0] == match) });
51
51
  return pair ? pair[1] : '(unknown)';
@@ -174,11 +174,16 @@ SetBuilder.Modifier = function(_name, _operator, _values, _params) {
174
174
  }
175
175
 
176
176
  this.toString = function() {
177
- var words = [_operator.replace(/_/, ' ')];
178
- for(var i=0; i<_values.length; i++) {
179
- words.push(SetBuilder.getValue(_params[i], _values[i]));
177
+ var words = [_operator.replace(/_/, ' '), ' '];
178
+ var __values = _values.dup();
179
+ for(var i=0; i<_params.length; i++) {
180
+ if(_params[i][0] == 'arg') {
181
+ words.push(SetBuilder.getValue(_params[i][1], __values.shift()));
182
+ } else {
183
+ words.push(_params[i][1])
184
+ }
180
185
  }
181
- return words.join(' ');
186
+ return words.join('');
182
187
  }
183
188
 
184
189
  };
@@ -247,13 +252,14 @@ SetBuilder.Modifiers = function(_modifiers) {
247
252
  var operator = args.operator;
248
253
  if(!operator) throw 'An operator name was not supplied.'
249
254
 
250
- var params = this.params_for_operator(modifier_type, operator);
255
+ var params = this.params_for_operator(modifier_type, operator)
256
+ var paramsLength = params.__select(function(token) { return token[0] == 'arg' }).length;
251
257
  var values = args.values;
252
258
 
253
259
  if(!values) values = [];
254
260
  if(!(values instanceof Array)) values = [values];
255
- if(values.length != params.length) {
256
- throw ('The operator "' + operator.toString() + '" expects ' + params.length + ' arguments but received ' + values.length + '.');
261
+ if(values.length != paramsLength) {
262
+ throw ('The operator "' + operator.toString() + '" expects ' + paramsLength + ' arguments but received ' + values.length + '.');
257
263
  }
258
264
 
259
265
  return new SetBuilder.Modifier(name, operator, values, params);
@@ -23,7 +23,17 @@ module SetBuilder
23
23
  @params = params
24
24
 
25
25
  @direct_object = params[direct_object_type] if trait.requires_direct_object?
26
- @enums = params[:enums] || []
26
+
27
+ # Map supplied enum values to what the Trait has defined.
28
+ # If there are any discrepancies or missing values, fill them
29
+ # in with values that will work.
30
+ enum_values = params[:enums] || []
31
+ @enums = trait.enums.each_with_index.map do |expected_values, i|
32
+ value = enum_values[i]
33
+ value = expected_values[0] unless expected_values.include?(value)
34
+ value
35
+ end
36
+
27
37
  modifiers = params.fetch(:modifiers, [])
28
38
  @modifiers = trait.modifiers.each_with_index.map { |modifier, i|
29
39
  modifier.new(modifiers[i] || {}) }
@@ -38,13 +48,6 @@ module SetBuilder
38
48
  def errors
39
49
  [].tap do |errors|
40
50
  errors.push "#{direct_object_type} is blank" if direct_object_required? && direct_object.nil?
41
- if enums.length != trait.enums.length
42
- errors.push "should have values for #{trait.enums.length} enums"
43
- else
44
- trait.enums.each_with_index do |expected_values, i|
45
- errors.push "enum ##{i + 1} should be #{expected_values.map { |value| "'#{value}'" }.to_sentence(two_words_connector: " or ", last_word_connector: ", or ")}" unless expected_values.member?(enums[i])
46
- end
47
- end
48
51
  errors.concat modifiers.flat_map(&:errors)
49
52
  end
50
53
  end
@@ -0,0 +1,50 @@
1
+ require "set_builder/parser"
2
+
3
+ module SetBuilder
4
+ module Modifier
5
+ class Arguments
6
+ attr_reader :arguments, :expression, :tokens
7
+
8
+ include Parser
9
+
10
+ def initialize(expression)
11
+ @expression = expression.respond_to?(:each) ? map_legacy_arguments(expression) : expression
12
+ @tokens = parse(@expression)
13
+ end
14
+
15
+ def arity
16
+ types.count
17
+ end
18
+
19
+ def types
20
+ @types ||= @tokens
21
+ .select { |token, _| token == :arg }
22
+ .map { |_, type| type }
23
+ end
24
+
25
+ def as_json(*)
26
+ tokens.map { |(token, value)| [token.to_s, value] }
27
+ end
28
+
29
+ def to_s(values)
30
+ _values = values.dup
31
+ tokens.map do |token, token_value|
32
+ if token == :arg
33
+ ValueMap.to_s(token_value, _values.shift)
34
+ else
35
+ token_value
36
+ end
37
+ end.join
38
+ end
39
+
40
+ private
41
+
42
+ def map_legacy_arguments(arguments)
43
+ _expression = arguments.map { |arg| "{#{arg}}" }.join(" ")
44
+ puts "DEPRECATED: SetBuilder::Modifier should use expression style argumenents now e.g.-> \"#{_expression}\""
45
+ _expression
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -1,3 +1,5 @@
1
+ require "set_builder/modifier/arguments"
2
+
1
3
  module SetBuilder
2
4
  module Modifier
3
5
  class Base
@@ -43,11 +45,11 @@ module SetBuilder
43
45
 
44
46
  def errors_with_values
45
47
  [].tap do |errors|
46
- types = self.class.operators[operator] || []
47
- if values.length != types.length
48
- errors.push "wrong number of arguments; expected #{types.length} (#{types.join(", ")})"
48
+ arguments = self.class.parsed_operators[operator] || Arguments.new("")
49
+ if values.length != arguments.arity
50
+ errors.push "wrong number of arguments; expected #{arguments.arity} (#{arguments.types.join(", ")})"
49
51
  else
50
- errors.concat values.each_with_index.flat_map { |value, i| errors_with_value_type(value, types[i]) }
52
+ errors.concat values.each_with_index.flat_map { |value, i| errors_with_value_type(value, arguments.types[i]) }
51
53
  end
52
54
  end
53
55
  end
@@ -78,13 +80,16 @@ module SetBuilder
78
80
 
79
81
 
80
82
 
81
- def to_s(negative=false)
82
- words = negative ? [self.class.negate(operator).to_s.gsub(/_/, " ")] : [operator.to_s.gsub(/_/, " ")]
83
- arguments = self.class.operators[operator] || []
84
- (0...arguments.length).each do |i|
85
- words << ValueMap.to_s(arguments[i], values[i])
86
- end
87
- words.join(" ")
83
+ def to_s
84
+ arguments = self.class.parsed_operators[operator] || Arguments.new("")
85
+ operator.to_s.gsub(/_/, " ") + " " + arguments.to_s(values)
86
+ end
87
+
88
+
89
+
90
+ def self.parsed_operators
91
+ @parsed_operators ||= Hash[operators.map { |operator, arguments|
92
+ [operator, Arguments.new(arguments)] }]
88
93
  end
89
94
 
90
95
 
@@ -96,11 +101,8 @@ module SetBuilder
96
101
 
97
102
 
98
103
  def self.to_hash
99
- hash = {}
100
- operators.each do |operator, array|
101
- hash[operator.to_s] = array.map {|type| type.to_s }
102
- end
103
- hash
104
+ Hash[parsed_operators.map { |operator, arguments|
105
+ [operator.to_s, arguments.as_json] }]
104
106
  end
105
107
 
106
108
 
@@ -7,14 +7,14 @@ module SetBuilder
7
7
 
8
8
  def self.operators
9
9
  {
10
- :ever => [],
11
- :before => [:date],
12
- :after => [:date],
13
- :on => [:date],
14
- :during_month => [:month],
15
- :during_year => [:year],
16
- :in_the_last => [:number, :period],
17
- :between => [:date, :date]
10
+ :ever => "",
11
+ :before => "{date}",
12
+ :after => "{date}",
13
+ :on => "{date}",
14
+ :during_month => "{month}",
15
+ :during_year => "{year}",
16
+ :in_the_last => "{number} {period}",
17
+ :between => "{date} and {date}"
18
18
  }
19
19
  end
20
20
 
@@ -7,10 +7,10 @@ module SetBuilder
7
7
 
8
8
  def self.operators
9
9
  {
10
- :is => [:number],
11
- :is_less_than => [:number],
12
- :is_greater_than => [:number],
13
- :is_between => [:number, :number]
10
+ :is => "{number}",
11
+ :is_less_than => "{number}",
12
+ :is_greater_than => "{number}",
13
+ :is_between => "{number} and {number}"
14
14
  }
15
15
  end
16
16
 
@@ -7,14 +7,14 @@ module SetBuilder
7
7
 
8
8
  def self.operators
9
9
  {
10
- :contains => [:string],
11
- :does_not_contain => [:string],
12
- :begins_with => [:string],
13
- :does_not_begin_with => [:string],
14
- :ends_with => [:string],
15
- :does_not_end_with => [:string],
16
- :is => [:string],
17
- :is_not => [:string]
10
+ :contains => "{string}",
11
+ :does_not_contain => "{string}",
12
+ :begins_with => "{string}",
13
+ :does_not_begin_with => "{string}",
14
+ :ends_with => "{string}",
15
+ :does_not_end_with => "{string}",
16
+ :is => "{string}",
17
+ :is_not => "{string}"
18
18
  }
19
19
  end
20
20
 
@@ -0,0 +1,36 @@
1
+ module SetBuilder
2
+ module Parser
3
+
4
+ def parse(expression)
5
+ tokenizer = Regexp.union(LEXER.values)
6
+ expression.split(tokenizer).each_with_object([]) do |lexeme, output|
7
+ next if lexeme.empty?
8
+ token = token_for(lexeme)
9
+ output.push [token, value_for(token, lexeme)]
10
+ end
11
+ end
12
+
13
+ def token_for(lexeme)
14
+ LEXER.each { |token, pattern| return token if pattern.match(lexeme) }
15
+ :string
16
+ end
17
+
18
+ def value_for(token, lexeme)
19
+ case token
20
+ when :name, :modifier, :arg then lexeme[1...-1]
21
+ when :enum then lexeme[1...-1].split("|")
22
+ when :direct_object_type then lexeme[1..-1]
23
+ else lexeme
24
+ end
25
+ end
26
+
27
+ LEXER = {
28
+ name: /("[^"]+")/,
29
+ direct_object_type: /(:[\w\-\.]+)/,
30
+ enum: /(\[[^\]]+\])/,
31
+ modifier: /(<\w+>)/,
32
+ arg: /(\{[^\}]+\})/
33
+ }.freeze
34
+
35
+ end
36
+ end
@@ -1,11 +1,13 @@
1
1
  require "set_builder/constraint"
2
2
  require "set_builder/modifier"
3
+ require "set_builder/parser"
3
4
 
4
5
 
5
6
  module SetBuilder
6
7
  class Trait
7
8
  attr_reader :expression, :tokens, :name, :modifiers, :direct_object_type, :enums
8
9
 
10
+ include Parser
9
11
 
10
12
 
11
13
  def initialize(expression, &block)
@@ -65,38 +67,5 @@ module SetBuilder
65
67
 
66
68
 
67
69
 
68
- def parse(expression)
69
- tokenizer = Regexp.union(LEXER.values)
70
- expression.split(tokenizer).each_with_object([]) do |lexeme, output|
71
- next if lexeme.empty?
72
- token = token_for(lexeme)
73
- output.push [token, value_for(token, lexeme)]
74
- end
75
- end
76
-
77
- def token_for(lexeme)
78
- LEXER.each { |token, pattern| return token if pattern.match(lexeme) }
79
- :string
80
- end
81
-
82
- def value_for(token, lexeme)
83
- case token
84
- when :name then lexeme[1...-1]
85
- when :enum then lexeme[1...-1].split("|")
86
- when :modifier then lexeme[1...-1]
87
- when :direct_object_type then lexeme[1..-1]
88
- else lexeme
89
- end
90
- end
91
-
92
- LEXER = {
93
- name: /("[^"]+")/,
94
- direct_object_type: /(:[\w\-\.]+)/,
95
- enum: /(\[[^\]]+\])/,
96
- modifier: /(<\w+>)/
97
- }.freeze
98
-
99
-
100
-
101
70
  end
102
71
  end
@@ -1,3 +1,3 @@
1
1
  module SetBuilder
2
- VERSION = "2.0.0.beta3"
2
+ VERSION = "2.0.0.beta4"
3
3
  end
@@ -32,10 +32,13 @@ describe 'SetBuilder'
32
32
 
33
33
  SetBuilder.registerModifiers({
34
34
  string: {
35
- contains: ['string'],
36
- begins_with: ['string'],
37
- ends_with: ['string'],
38
- is: ['string']
35
+ contains: [['arg', 'string']],
36
+ begins_with: [['arg', 'string']],
37
+ ends_with: [['arg', 'string']],
38
+ is: [['arg', 'string']]
39
+ },
40
+ date: {
41
+ between: [['arg', 'date'], ['string', ' and '], ['arg', 'date']]
39
42
  }
40
43
  });
41
44
 
@@ -60,6 +63,20 @@ describe 'SetBuilder'
60
63
 
61
64
 
62
65
 
66
+ describe '.registerValueMap'
67
+ it 'should accept an array of arrays as a valueMap'
68
+ SetBuilder.registerValueMap('name', [['1', 'John'], ['2', 'Susan']]);
69
+ expect(SetBuilder.getValueMap('name')).to(eql, [['1', 'John'], ['2', 'Susan']]);
70
+ end
71
+
72
+ it 'should accept and call a function as a valueMap'
73
+ var events = [['1', 'Band Rehearsal']];
74
+ SetBuilder.registerValueMap('event', function () { return events });
75
+ expect(SetBuilder.getValueMap('event')).to(eql, events);
76
+ events.push(['2', 'Basketball Practice']);
77
+ expect(SetBuilder.getValueMap('event')).to(eql, events);
78
+ end
79
+ end
63
80
 
64
81
  describe '.getValueMap'
65
82
  it 'should return an array of arrays'
@@ -80,7 +97,7 @@ describe 'SetBuilder'
80
97
 
81
98
  describe '.getValueMaps'
82
99
  it 'should return the names of the value maps registered'
83
- expect(SetBuilder.getValueMaps()).to(eql, ['school']);
100
+ expect(SetBuilder.getValueMaps()).to(eql, ['school', 'name', 'event']);
84
101
  end
85
102
  end
86
103
 
@@ -139,7 +156,7 @@ describe 'SetBuilder'
139
156
 
140
157
  describe '.length'
141
158
  it 'should have parsed the data structure correctly'
142
- expect(modifiers.length()).to(be, 1);
159
+ expect(modifiers.length()).to(be, 2);
143
160
  end
144
161
  end
145
162
 
@@ -195,6 +212,14 @@ describe 'SetBuilder'
195
212
  var expected_string = 'who are not awesome, who have not attended Concordia, who have not died, and whose name is Jerome'
196
213
  expect(set.toString()).to(eql, expected_string);
197
214
  end
215
+
216
+ it 'should generate the natural language description of a set with extra text in modifier arguments'
217
+ var set = new SetBuilder.Set([
218
+ { trait: 'born', modifiers: [{ operator: 'between', values: ['Jan 1, 2016', 'Jan 2, 2016'] }]}
219
+ ])
220
+ var expected_string = 'who were born between Jan 1, 2016 and Jan 2, 2016';
221
+ expect(set.toString()).to(eql, expected_string);
222
+ end
198
223
  end
199
224
 
200
225
  end
@@ -3,6 +3,8 @@ require "test_helper"
3
3
  class ConstraintTest < ActiveSupport::TestCase
4
4
  include SetBuilder
5
5
 
6
+ attr_reader :trait, :constraint
7
+
6
8
 
7
9
  test "constraints find correct modifiers" do
8
10
  trait = $friend_traits[:name]
@@ -29,6 +31,40 @@ class ConstraintTest < ActiveSupport::TestCase
29
31
 
30
32
 
31
33
 
34
+ context "When a Constraint has fewer enum values than the Trait expects, it" do
35
+ setup do
36
+ @trait = Trait.new('who [is|is not] "awesome" at [basketball|golf|hockey]')
37
+ @constraint = trait.apply({enums: ["is not"]})
38
+ end
39
+
40
+ should "be valid" do
41
+ assert constraint.valid?, "The constraint was not valid: #{constraint.errors.join(";")}"
42
+ end
43
+
44
+ should "fill in the missing values with the first option the Trait defines" do
45
+ assert_equal "who is not awesome at basketball", constraint.to_s
46
+ end
47
+ end
48
+
49
+
50
+
51
+ context "When a Constraint is given an enum value that the Trait doesn't expect, it" do
52
+ setup do
53
+ @trait = Trait.new('who [is|is not] "awesome" at [basketball|golf|hockey]')
54
+ @constraint = trait.apply({enums: ["are not", "soccer"]})
55
+ end
56
+
57
+ should "be valid" do
58
+ assert constraint.valid?, "The constraint was not valid: #{constraint.errors.join(";")}"
59
+ end
60
+
61
+ should "replace the value with the first option the Trait defines" do
62
+ assert_equal "who is awesome at basketball", constraint.to_s
63
+ end
64
+ end
65
+
66
+
67
+
32
68
  context "A constraint" do
33
69
  should "be invalid if it is missing a direct object" do
34
70
  trait = Trait.new('who "attended" :school')
@@ -36,18 +72,6 @@ class ConstraintTest < ActiveSupport::TestCase
36
72
  assert_match /school is blank/, constraint.errors.join
37
73
  end
38
74
 
39
- should "be invalid if it is missing an enumeration" do
40
- trait = Trait.new('who [is|is not] "awesome"')
41
- constraint = trait.apply({})
42
- assert_match /should have values for 1 enums/, constraint.errors.join
43
- end
44
-
45
- should "be invalid if it supplies an unexpected value for an enumeration" do
46
- trait = Trait.new('who [is|is not] "awesome"')
47
- constraint = trait.apply(enums: ["is totally"])
48
- assert_match /should be 'is' or 'is not'/, constraint.errors.join
49
- end
50
-
51
75
  should "be invalid if it supplies an unexpected value for a modifier's operator" do
52
76
  trait = Trait.new('whose "name" <string>')
53
77
  constraint = trait.apply(modifiers: [{ operator: "starts_with", values: ["Jer"] }])
@@ -55,14 +55,14 @@ class ModifierTest < ActiveSupport::TestCase
55
55
 
56
56
  test "converting modifier to json" do
57
57
  expected_results = {
58
- "contains" => ["string"],
59
- "does_not_contain" => ["string"],
60
- "begins_with" => ["string"],
61
- "does_not_begin_with" => ["string"],
62
- "ends_with" => ["string"],
63
- "does_not_end_with" => ["string"],
64
- "is" => ["string"],
65
- "is_not" => ["string"]
58
+ "contains" => [["arg", "string"]],
59
+ "does_not_contain" => [["arg", "string"]],
60
+ "begins_with" => [["arg", "string"]],
61
+ "does_not_begin_with" => [["arg", "string"]],
62
+ "ends_with" => [["arg", "string"]],
63
+ "does_not_end_with" => [["arg", "string"]],
64
+ "is" => [["arg", "string"]],
65
+ "is_not" => [["arg", "string"]]
66
66
  }.to_json
67
67
  assert_equal expected_results, SetBuilder::Modifier.for(:string).to_json
68
68
  end
@@ -71,29 +71,29 @@ class ModifierTest < ActiveSupport::TestCase
71
71
  expected_results = {
72
72
  "date" => {
73
73
  "ever" => [],
74
- "after" => ["date"],
75
- "before" => ["date"],
76
- "on" => ["date"],
77
- "in_the_last" => ["number", "period"],
78
- "during_month"=> ["month"],
79
- "during_year" => ["year"],
80
- "between" => ["date", "date"]
74
+ "before" => [["arg", "date"]],
75
+ "after" => [["arg", "date"]],
76
+ "on" => [["arg", "date"]],
77
+ "during_month"=> [["arg", "month"]],
78
+ "during_year" => [["arg", "year"]],
79
+ "in_the_last" => [["arg", "number"], ["string", " "], ["arg", "period"]],
80
+ "between" => [["arg", "date"], ["string", " and "], ["arg", "date"]]
81
81
  },
82
- "number"=> {
83
- "is"=>["number"],
84
- "is_less_than"=>["number"],
85
- "is_greater_than"=>["number"],
86
- "is_between"=>["number", "number"]
82
+ "number" => {
83
+ "is"=>[["arg", "number"]],
84
+ "is_less_than"=>[["arg", "number"]],
85
+ "is_greater_than"=>[["arg", "number"]],
86
+ "is_between"=>[["arg", "number"], ["string", " and "], ["arg", "number"]]
87
87
  },
88
88
  "string" => {
89
- "contains" => ["string"],
90
- "does_not_contain" => ["string"],
91
- "begins_with" => ["string"],
92
- "does_not_begin_with" => ["string"],
93
- "ends_with" => ["string"],
94
- "does_not_end_with" => ["string"],
95
- "is" => ["string"],
96
- "is_not" => ["string"]
89
+ "contains" => [["arg", "string"]],
90
+ "does_not_contain" => [["arg", "string"]],
91
+ "begins_with" => [["arg", "string"]],
92
+ "does_not_begin_with" => [["arg", "string"]],
93
+ "ends_with" => [["arg", "string"]],
94
+ "does_not_end_with" => [["arg", "string"]],
95
+ "is" => [["arg", "string"]],
96
+ "is_not" => [["arg", "string"]]
97
97
  }
98
98
  }
99
99
  assert_equal expected_results, $friend_traits.modifiers.to_hash
metadata CHANGED
@@ -1,139 +1,158 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: set_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.beta3
4
+ version: 2.0.0.beta4
5
+ prerelease: 6
5
6
  platform: ruby
6
7
  authors:
7
8
  - Bob Lail
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2016-01-27 00:00:00.000000000 Z
12
+ date: 2016-03-07 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rails
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
- - - "~>"
19
+ - - ~>
18
20
  - !ruby/object:Gem::Version
19
21
  version: 4.2.0
20
22
  type: :runtime
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
- - - "~>"
27
+ - - ~>
25
28
  - !ruby/object:Gem::Version
26
29
  version: 4.2.0
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: arel
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
- - - ">="
35
+ - - ! '>='
32
36
  - !ruby/object:Gem::Version
33
37
  version: '0'
34
38
  type: :runtime
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
- - - ">="
43
+ - - ! '>='
39
44
  - !ruby/object:Gem::Version
40
45
  version: '0'
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: bundler
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
- - - "~>"
51
+ - - ~>
46
52
  - !ruby/object:Gem::Version
47
53
  version: '1.3'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
- - - "~>"
59
+ - - ~>
53
60
  - !ruby/object:Gem::Version
54
61
  version: '1.3'
55
62
  - !ruby/object:Gem::Dependency
56
63
  name: rake
57
64
  requirement: !ruby/object:Gem::Requirement
65
+ none: false
58
66
  requirements:
59
- - - ">="
67
+ - - ! '>='
60
68
  - !ruby/object:Gem::Version
61
69
  version: '0'
62
70
  type: :development
63
71
  prerelease: false
64
72
  version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
65
74
  requirements:
66
- - - ">="
75
+ - - ! '>='
67
76
  - !ruby/object:Gem::Version
68
77
  version: '0'
69
78
  - !ruby/object:Gem::Dependency
70
79
  name: jspec
71
80
  requirement: !ruby/object:Gem::Requirement
81
+ none: false
72
82
  requirements:
73
- - - ">="
83
+ - - ! '>='
74
84
  - !ruby/object:Gem::Version
75
85
  version: '0'
76
86
  type: :development
77
87
  prerelease: false
78
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
79
90
  requirements:
80
- - - ">="
91
+ - - ! '>='
81
92
  - !ruby/object:Gem::Version
82
93
  version: '0'
83
94
  - !ruby/object:Gem::Dependency
84
95
  name: pry
85
96
  requirement: !ruby/object:Gem::Requirement
97
+ none: false
86
98
  requirements:
87
- - - ">="
99
+ - - ! '>='
88
100
  - !ruby/object:Gem::Version
89
101
  version: '0'
90
102
  type: :development
91
103
  prerelease: false
92
104
  version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
93
106
  requirements:
94
- - - ">="
107
+ - - ! '>='
95
108
  - !ruby/object:Gem::Version
96
109
  version: '0'
97
110
  - !ruby/object:Gem::Dependency
98
111
  name: shoulda-context
99
112
  requirement: !ruby/object:Gem::Requirement
113
+ none: false
100
114
  requirements:
101
- - - ">="
115
+ - - ! '>='
102
116
  - !ruby/object:Gem::Version
103
117
  version: '0'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
107
122
  requirements:
108
- - - ">="
123
+ - - ! '>='
109
124
  - !ruby/object:Gem::Version
110
125
  version: '0'
111
126
  - !ruby/object:Gem::Dependency
112
127
  name: minitest-reporters
113
128
  requirement: !ruby/object:Gem::Requirement
129
+ none: false
114
130
  requirements:
115
- - - ">="
131
+ - - ! '>='
116
132
  - !ruby/object:Gem::Version
117
133
  version: '0'
118
134
  type: :development
119
135
  prerelease: false
120
136
  version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
121
138
  requirements:
122
- - - ">="
139
+ - - ! '>='
123
140
  - !ruby/object:Gem::Version
124
141
  version: '0'
125
142
  - !ruby/object:Gem::Dependency
126
143
  name: timecop
127
144
  requirement: !ruby/object:Gem::Requirement
145
+ none: false
128
146
  requirements:
129
- - - ">="
147
+ - - ! '>='
130
148
  - !ruby/object:Gem::Version
131
149
  version: '0'
132
150
  type: :development
133
151
  prerelease: false
134
152
  version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
135
154
  requirements:
136
- - - ">="
155
+ - - ! '>='
137
156
  - !ruby/object:Gem::Version
138
157
  version: '0'
139
158
  description: A gem for describing constraints on data sets
@@ -143,8 +162,8 @@ executables: []
143
162
  extensions: []
144
163
  extra_rdoc_files: []
145
164
  files:
146
- - ".gitignore"
147
- - ".travis.yml"
165
+ - .gitignore
166
+ - .travis.yml
148
167
  - Gemfile
149
168
  - MIT-LICENSE
150
169
  - README.md
@@ -158,6 +177,7 @@ files:
158
177
  - lib/set_builder/errors/trait_not_found.rb
159
178
  - lib/set_builder/modifier.rb
160
179
  - lib/set_builder/modifier/adverb.rb
180
+ - lib/set_builder/modifier/arguments.rb
161
181
  - lib/set_builder/modifier/base.rb
162
182
  - lib/set_builder/modifier/verb.rb
163
183
  - lib/set_builder/modifier_collection.rb
@@ -165,6 +185,7 @@ files:
165
185
  - lib/set_builder/modifiers/date_preposition.rb
166
186
  - lib/set_builder/modifiers/number_preposition.rb
167
187
  - lib/set_builder/modifiers/string_preposition.rb
188
+ - lib/set_builder/parser.rb
168
189
  - lib/set_builder/set.rb
169
190
  - lib/set_builder/trait.rb
170
191
  - lib/set_builder/trait_builder.rb
@@ -209,26 +230,30 @@ files:
209
230
  homepage: ''
210
231
  licenses:
211
232
  - MIT
212
- metadata: {}
213
233
  post_install_message:
214
234
  rdoc_options: []
215
235
  require_paths:
216
236
  - lib
217
237
  required_ruby_version: !ruby/object:Gem::Requirement
238
+ none: false
218
239
  requirements:
219
- - - ">="
240
+ - - ! '>='
220
241
  - !ruby/object:Gem::Version
221
242
  version: '0'
243
+ segments:
244
+ - 0
245
+ hash: -2909033226206724461
222
246
  required_rubygems_version: !ruby/object:Gem::Requirement
247
+ none: false
223
248
  requirements:
224
- - - ">"
249
+ - - ! '>'
225
250
  - !ruby/object:Gem::Version
226
251
  version: 1.3.1
227
252
  requirements: []
228
253
  rubyforge_project:
229
- rubygems_version: 2.2.2
254
+ rubygems_version: 1.8.23.2
230
255
  signing_key:
231
- specification_version: 4
256
+ specification_version: 3
232
257
  summary: Define traits on a model, create sets that constrain those traits, and generate
233
258
  both natural-language descriptions of the sets and queries to select them
234
259
  test_files:
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: acd34d467c6aca8cc3c42db795261de035c72c58
4
- data.tar.gz: 2c08cc3a703c5cc84230cbaa0e047004d4e7f430
5
- SHA512:
6
- metadata.gz: d79aec9ff59f398bc844de87cbc9a7946fb43166017d1231c36fc8a1ff267a296a98e88e524d3b01b2c726bd91ed75d4e63833246e32cc6fa25114e038809cb1
7
- data.tar.gz: d4ba5f0e2dfff5ad5245abd758adcac891c93fe2e0bba30c830e52b7dd63e7749962ed6843dc4f3c4b33b1e7b3a3b33dcb58ceef97312a417cce6abbf8be8962