set_builder 2.0.0.beta3 → 2.0.0.beta4
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.
- data/lib/assets/javascripts/set_builder.js +19 -13
- data/lib/set_builder/constraint.rb +11 -8
- data/lib/set_builder/modifier/arguments.rb +50 -0
- data/lib/set_builder/modifier/base.rb +18 -16
- data/lib/set_builder/modifiers/date_preposition.rb +8 -8
- data/lib/set_builder/modifiers/number_preposition.rb +4 -4
- data/lib/set_builder/modifiers/string_preposition.rb +8 -8
- data/lib/set_builder/parser.rb +36 -0
- data/lib/set_builder/trait.rb +2 -33
- data/lib/set_builder/version.rb +1 -1
- data/spec/unit/set_builder.spec.js +31 -6
- data/test/constraint_test.rb +36 -12
- data/test/modifier_test.rb +28 -28
- metadata +52 -27
- checksums.yaml +0 -7
| @@ -30,12 +30,14 @@ var SetBuilder = (function() { | |
| 30 30 | 
             
                  return _modifiers;
         | 
| 31 31 | 
             
                },
         | 
| 32 32 | 
             
                getValueMap: function(key) {
         | 
| 33 | 
            -
                   | 
| 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 | 
            -
                 | 
| 179 | 
            -
             | 
| 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 !=  | 
| 256 | 
            -
                  throw ('The operator "' + operator.toString() + '" expects ' +  | 
| 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 | 
            -
             | 
| 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 | 
            -
                       | 
| 47 | 
            -
                      if values.length !=  | 
| 48 | 
            -
                        errors.push "wrong number of arguments; expected #{ | 
| 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 | 
| 82 | 
            -
                     | 
| 83 | 
            -
                     | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 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 | 
            -
                     | 
| 100 | 
            -
             | 
| 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 =>  | 
| 12 | 
            -
                      :after =>  | 
| 13 | 
            -
                      :on =>  | 
| 14 | 
            -
                      :during_month =>  | 
| 15 | 
            -
                      :during_year =>  | 
| 16 | 
            -
                      :in_the_last =>  | 
| 17 | 
            -
                      :between =>  | 
| 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 =>  | 
| 11 | 
            -
                      :is_less_than =>  | 
| 12 | 
            -
                      :is_greater_than =>  | 
| 13 | 
            -
                      :is_between =>  | 
| 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 =>  | 
| 11 | 
            -
                      :does_not_contain =>  | 
| 12 | 
            -
                      :begins_with =>  | 
| 13 | 
            -
                      :does_not_begin_with =>  | 
| 14 | 
            -
                      :ends_with =>  | 
| 15 | 
            -
                      :does_not_end_with =>  | 
| 16 | 
            -
                      :is =>  | 
| 17 | 
            -
                      :is_not =>  | 
| 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
         | 
    
        data/lib/set_builder/trait.rb
    CHANGED
    
    | @@ -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
         | 
    
        data/lib/set_builder/version.rb
    CHANGED
    
    
| @@ -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 | 
            -
             | 
| 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
         | 
    
        data/test/constraint_test.rb
    CHANGED
    
    | @@ -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"] }])
         | 
    
        data/test/modifier_test.rb
    CHANGED
    
    | @@ -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 | 
            -
                    " | 
| 75 | 
            -
                    " | 
| 76 | 
            -
                    "on"          => ["date"],
         | 
| 77 | 
            -
                    " | 
| 78 | 
            -
                    " | 
| 79 | 
            -
                    " | 
| 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. | 
| 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- | 
| 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 | 
            -
            -  | 
| 147 | 
            -
            -  | 
| 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:  | 
| 254 | 
            +
            rubygems_version: 1.8.23.2
         | 
| 230 255 | 
             
            signing_key: 
         | 
| 231 | 
            -
            specification_version:  | 
| 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
         |