set_builder 1.2.0.beta3 → 2.0.0.beta1
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 +4 -4
- data/README.md +7 -1
- data/lib/assets/javascripts/set_builder.js +80 -62
- data/lib/set_builder/constraint.rb +2 -2
- data/lib/set_builder/modifier.rb +12 -6
- data/lib/set_builder/modifiers/{date_modifier.rb → date_preposition.rb} +1 -1
- data/lib/set_builder/modifiers/{number_modifier.rb → number_preposition.rb} +2 -2
- data/lib/set_builder/modifiers/{string_modifier.rb → string_preposition.rb} +1 -1
- data/lib/set_builder/modifiers.rb +3 -3
- data/lib/set_builder/trait.rb +49 -47
- data/lib/set_builder/value_map.rb +8 -7
- data/lib/set_builder/version.rb +1 -1
- data/lib/set_builder.rb +6 -32
- data/set_builder.gemspec +3 -2
- data/spec/dom.html +2 -3
- data/spec/unit/array.spec.js +9 -1
- data/spec/unit/set_builder.spec.js +31 -21
- data/test/{date_modifier_test.rb → date_preposition_test.rb} +3 -3
- data/test/inflector_test.rb +6 -6
- data/test/modifier_test.rb +3 -3
- data/test/{string_modifier_test.rb → string_preposition_test.rb} +2 -2
- data/test/test_helper.rb +6 -13
- data/test/trait_test.rb +1 -1
- data/test/traits_test.rb +20 -7
- metadata +29 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33054edba058a15627aaf11cbdd32f2a3bdb5c7e
|
4
|
+
data.tar.gz: 2ab79d3204faa01c6acd43515f453d8c3a883990
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5af7ed922c28414483e4cf8c14704a94d527733a27ce8d07b95a3c687df7533594661c0d1099085d6326308602dd619dae2a143c09960aa69bdebdc41417b7e
|
7
|
+
data.tar.gz: 47f857f3f679dec0cb5f0c701bd45a890a8cdd968d9eb8a544d76c8e866bc8ddfb9c2747c7437b7dba845dd17c32ebed93f9f0ff759b8e0324564f00d16e4b45
|
data/README.md
CHANGED
@@ -27,5 +27,11 @@ SetBuilder can render this Set in plain English:
|
|
27
27
|
It can also generate a NamedScope on an ActiveRecord model to fetch the people who fit in this set.
|
28
28
|
|
29
29
|
|
30
|
+
### Running the tests
|
30
31
|
|
31
|
-
|
32
|
+
*Ruby* `bundle exec rake test`
|
33
|
+
|
34
|
+
*Javascript* `jspec run --browsers ff`
|
35
|
+
|
36
|
+
|
37
|
+
Copyright (c) 2010, 2015 Bob Lail, released under the MIT license
|
@@ -77,7 +77,7 @@ SetBuilder.Constraint = function(_trait, args) {
|
|
77
77
|
}
|
78
78
|
|
79
79
|
args = args.dup();
|
80
|
-
if(_trait.
|
80
|
+
if(_trait.requiresDirectObject()) _direct_object = args.shift();
|
81
81
|
var _modifiers = _trait.modifiers().collect(function(modifier_type) {
|
82
82
|
return SetBuilder.modifiers().apply(modifier_type, args.shift());
|
83
83
|
});
|
@@ -109,7 +109,7 @@ SetBuilder.Constraint = function(_trait, args) {
|
|
109
109
|
|
110
110
|
this.negate = function(value) {
|
111
111
|
_negative = value;
|
112
|
-
if(_trait.
|
112
|
+
if(!_trait.hasNegative()) _negative = false;
|
113
113
|
return this;
|
114
114
|
}
|
115
115
|
|
@@ -121,19 +121,26 @@ SetBuilder.Constraint = function(_trait, args) {
|
|
121
121
|
return _trait.requires_direct_object();
|
122
122
|
}
|
123
123
|
|
124
|
-
this.
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
124
|
+
this.toString = function() {
|
125
|
+
var type, text, i = 0;
|
126
|
+
return _trait.tokens().collect(function(token) {
|
127
|
+
type = token[0], text = token[1];
|
128
|
+
switch(type) {
|
129
|
+
case 'string':
|
130
|
+
return text;
|
131
|
+
case 'name':
|
132
|
+
return _trait.name();
|
133
|
+
case 'negative':
|
134
|
+
return _negative && text;
|
135
|
+
case 'direct_object_type':
|
136
|
+
return SetBuilder.getValue(text, _direct_object);
|
137
|
+
case 'modifier':
|
138
|
+
return _modifiers[i++].toString();
|
139
|
+
default:
|
140
|
+
if(console && console.log) console.log('[SetBuilder.Constraint] unknown type: "' + type + '" (text: "' + text + '")');
|
141
|
+
return false;
|
142
|
+
}
|
143
|
+
}).compact().join(' ');
|
137
144
|
}
|
138
145
|
|
139
146
|
};
|
@@ -165,7 +172,7 @@ SetBuilder.Modifier = function(_name, _operator, _values, _params) {
|
|
165
172
|
return _values;
|
166
173
|
}
|
167
174
|
|
168
|
-
this.toString = function(
|
175
|
+
this.toString = function() {
|
169
176
|
var words = [_operator.replace(/_/, ' ')];
|
170
177
|
for(var i=0; i<_values.length; i++) {
|
171
178
|
words.push(SetBuilder.getValue(_params[i], _values[i]));
|
@@ -265,7 +272,6 @@ SetBuilder.Modifiers = function(_modifiers) {
|
|
265
272
|
*/
|
266
273
|
|
267
274
|
SetBuilder.Set = function(_raw_data) {
|
268
|
-
|
269
275
|
if(!_raw_data) _raw_data = [];
|
270
276
|
|
271
277
|
var _constraints = [];
|
@@ -314,27 +320,32 @@ SetBuilder.Set = function(_raw_data) {
|
|
314
320
|
an individual trait that can be constrained
|
315
321
|
*/
|
316
322
|
|
317
|
-
SetBuilder.Trait = function(
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
323
|
+
SetBuilder.Trait = function(_tokens) {
|
324
|
+
|
325
|
+
var type, text;
|
326
|
+
var _name, _modifiers = [], _direct_object_type, _negative;
|
327
|
+
_tokens.each(function(token) {
|
328
|
+
type = token[0], text = token[1];
|
329
|
+
switch(type) {
|
330
|
+
case 'name':
|
331
|
+
_name = text;
|
332
|
+
break;
|
333
|
+
case 'modifier':
|
334
|
+
_modifiers.push(text);
|
335
|
+
break;
|
336
|
+
case 'direct_object_type':
|
337
|
+
_direct_object_type = text;
|
338
|
+
break;
|
339
|
+
case 'negative':
|
340
|
+
_negative = text;
|
341
|
+
break;
|
342
|
+
}
|
343
|
+
});
|
333
344
|
|
334
345
|
|
335
346
|
// Public methods
|
336
347
|
|
337
|
-
this.
|
348
|
+
this.requiresDirectObject = function() {
|
338
349
|
return !!_direct_object_type;
|
339
350
|
}
|
340
351
|
|
@@ -346,39 +357,16 @@ SetBuilder.Trait = function(_raw_data) {
|
|
346
357
|
return _name;
|
347
358
|
}
|
348
359
|
|
349
|
-
this.
|
350
|
-
return
|
360
|
+
this.hasNegative = function() {
|
361
|
+
return !!_negative;
|
351
362
|
}
|
352
363
|
|
353
364
|
this.modifiers = function() {
|
354
365
|
return _modifiers;
|
355
366
|
}
|
356
367
|
|
357
|
-
this.
|
358
|
-
|
359
|
-
switch(_part_of_speech) {
|
360
|
-
case 'active':
|
361
|
-
return negative ? 'who have not' : 'who';
|
362
|
-
case 'perfect':
|
363
|
-
return negative ? 'who have not' : 'who have';
|
364
|
-
case 'passive':
|
365
|
-
return negative ? 'who were not' : 'who were';
|
366
|
-
case 'reflexive':
|
367
|
-
return negative ? 'who are not' : 'who are';
|
368
|
-
case 'noun':
|
369
|
-
return 'whose';
|
370
|
-
default:
|
371
|
-
return undefined;
|
372
|
-
}
|
373
|
-
}
|
374
|
-
|
375
|
-
this.toString = function(include_prefix, negative) {
|
376
|
-
var prefix = this.prefix(negative);
|
377
|
-
if(prefix) { // return an empty string if the prefix is invalid
|
378
|
-
return (include_prefix==false) ? this.name() : (prefix + ' ' + this.name());
|
379
|
-
} else {
|
380
|
-
return '';
|
381
|
-
}
|
368
|
+
this.tokens = function() {
|
369
|
+
return _tokens;
|
382
370
|
}
|
383
371
|
|
384
372
|
this.apply = function(args) {
|
@@ -397,7 +385,7 @@ SetBuilder.Trait = function(_raw_data) {
|
|
397
385
|
*/
|
398
386
|
|
399
387
|
SetBuilder.Traits = function(_raw_data) {
|
400
|
-
|
388
|
+
|
401
389
|
var _traits = _raw_data.collect(function(line) {
|
402
390
|
return new SetBuilder.Trait(line);
|
403
391
|
});
|
@@ -515,6 +503,22 @@ if(!Array.prototype.inject) Array.prototype.inject = Array.prototype.__inject;
|
|
515
503
|
|
516
504
|
|
517
505
|
|
506
|
+
//
|
507
|
+
// .compact
|
508
|
+
//
|
509
|
+
Array.prototype.__compact = function() {
|
510
|
+
var new_array = [];
|
511
|
+
for(var i=0; i<this.length; i++) {
|
512
|
+
if(this[i]) {
|
513
|
+
new_array.push(this[i]);
|
514
|
+
}
|
515
|
+
}
|
516
|
+
return new_array;
|
517
|
+
}
|
518
|
+
if(!Array.prototype.compact) Array.prototype.compact = Array.prototype.__compact;
|
519
|
+
|
520
|
+
|
521
|
+
|
518
522
|
//
|
519
523
|
// .find
|
520
524
|
//
|
@@ -527,3 +531,17 @@ Array.prototype.__find = function(fn) {
|
|
527
531
|
return null;
|
528
532
|
}
|
529
533
|
if(!Array.prototype.find) Array.prototype.find = Array.prototype.__find;
|
534
|
+
|
535
|
+
//
|
536
|
+
// .select
|
537
|
+
//
|
538
|
+
Array.prototype.__select = function(fn) {
|
539
|
+
var results = [];
|
540
|
+
for(var i=0; i<this.length; i++) {
|
541
|
+
if(fn(this[i])) {
|
542
|
+
results.push(this[i]);
|
543
|
+
}
|
544
|
+
}
|
545
|
+
return results;
|
546
|
+
}
|
547
|
+
if(!Array.prototype.select) Array.prototype.select = Array.prototype.__select;
|
data/lib/set_builder/modifier.rb
CHANGED
@@ -33,8 +33,14 @@ module SetBuilder
|
|
33
33
|
|
34
34
|
|
35
35
|
|
36
|
-
def self.[](
|
37
|
-
|
36
|
+
def self.[](klassname_or_symbol)
|
37
|
+
is_classname = /^[A-Z]/.match(klassname_or_symbol)
|
38
|
+
if is_classname
|
39
|
+
klass = SetBuilder::Modifiers.const_get("#{klassname_or_symbol}")
|
40
|
+
SetBuilder::Modifier.valid_modifier!(klass)
|
41
|
+
else
|
42
|
+
SetBuilder::Modifier.for(klassname_or_symbol.to_sym)
|
43
|
+
end
|
38
44
|
end
|
39
45
|
|
40
46
|
|
@@ -98,9 +104,9 @@ module SetBuilder
|
|
98
104
|
# Force predefined modifiers to pass `valid_modifier?`
|
99
105
|
#
|
100
106
|
Modifier.register(
|
101
|
-
[:date, Modifiers::
|
102
|
-
[:number, Modifiers::
|
103
|
-
[:string, Modifiers::
|
107
|
+
[:date, Modifiers::DatePreposition],
|
108
|
+
[:number, Modifiers::NumberPreposition],
|
109
|
+
[:string, Modifiers::StringPreposition]
|
104
110
|
)
|
105
111
|
|
106
112
|
|
@@ -131,4 +137,4 @@ end
|
|
131
137
|
#
|
132
138
|
#
|
133
139
|
#
|
134
|
-
# end
|
140
|
+
# end
|
@@ -3,7 +3,7 @@ require 'set_builder/modifier/verb'
|
|
3
3
|
|
4
4
|
module SetBuilder
|
5
5
|
module Modifiers
|
6
|
-
class
|
6
|
+
class NumberPreposition < Modifier::Verb
|
7
7
|
|
8
8
|
|
9
9
|
|
@@ -42,7 +42,7 @@ module SetBuilder
|
|
42
42
|
when :is_greater_than
|
43
43
|
selector.gt(value)
|
44
44
|
when :is_between
|
45
|
-
selector.gteq(
|
45
|
+
selector.gteq(values[0]).and(selector.lteq(values[1]))
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -1,3 +1,3 @@
|
|
1
|
-
require 'set_builder/modifiers/
|
2
|
-
require 'set_builder/modifiers/
|
3
|
-
require 'set_builder/modifiers/
|
1
|
+
require 'set_builder/modifiers/string_preposition'
|
2
|
+
require 'set_builder/modifiers/date_preposition'
|
3
|
+
require 'set_builder/modifiers/number_preposition'
|
data/lib/set_builder/trait.rb
CHANGED
@@ -5,70 +5,72 @@ require 'set_builder/modifier'
|
|
5
5
|
module SetBuilder
|
6
6
|
class Trait
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@
|
8
|
+
attr_reader :name, :parsed_expression, :part_of_speech, :modifiers, :direct_object_type
|
9
|
+
|
10
|
+
LEXER = {
|
11
|
+
name: /("[^"]+")/,
|
12
|
+
direct_object_type: /(:\w+)/,
|
13
|
+
negative: /(\[[^\]]+\])/,
|
14
|
+
modifier: /(<\w+>)/
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
def initialize(trait_expression, &block)
|
18
|
+
@parsed_expression = parse(trait_expression)
|
19
|
+
@name, @direct_object_type = find(:name), find(:direct_object_type)
|
20
|
+
@block = block
|
21
|
+
@modifiers = find_all(:modifier).map { |modifier| Modifier[modifier] }
|
19
22
|
end
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
attr_reader :name, :part_of_speech, :modifiers, :direct_object_type
|
24
|
-
|
25
|
-
|
26
|
-
|
27
24
|
def requires_direct_object?
|
28
25
|
!@direct_object_type.nil?
|
29
26
|
end
|
30
27
|
alias :direct_object_required? :requires_direct_object?
|
31
28
|
|
32
|
-
|
33
|
-
|
34
|
-
def noun?
|
35
|
-
(self.part_of_speech == :noun)
|
29
|
+
def negative?
|
30
|
+
find(:negative)
|
36
31
|
end
|
37
|
-
|
38
|
-
|
39
|
-
|
32
|
+
|
40
33
|
def to_s(negative=false)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
when :passive
|
47
|
-
negative ? "who were not #{name}" : "who were #{name}"
|
48
|
-
when :reflexive
|
49
|
-
negative ? "who are not #{name}" : "who are #{name}"
|
50
|
-
when :noun
|
51
|
-
"whose #{name}"
|
52
|
-
end
|
34
|
+
parsed_expression.reject do |token, _|
|
35
|
+
[:modifier, :direct_object_type].include?(token) || (!negative && token == :negative)
|
36
|
+
end.map do |token, value|
|
37
|
+
token == :name ? name : value
|
38
|
+
end.join(" ")
|
53
39
|
end
|
54
40
|
|
55
|
-
|
56
|
-
|
57
|
-
def to_json
|
58
|
-
array = []
|
59
|
-
array << (requires_direct_object? ? [name, @direct_object_type] : name)
|
60
|
-
array << part_of_speech
|
61
|
-
array << modifiers.collect{|klass| Modifier.name(klass)} unless modifiers.empty?
|
62
|
-
array.to_json
|
41
|
+
def find_all(token)
|
42
|
+
parsed_expression.select { |(_token, _)| _token == token }.map { |(_, value)| value }
|
63
43
|
end
|
64
44
|
|
45
|
+
def find(token)
|
46
|
+
find_all(token).first
|
47
|
+
end
|
65
48
|
|
66
|
-
|
49
|
+
def as_json(*)
|
50
|
+
parsed_expression.map { |(token, value)| [token.to_s, value] }
|
51
|
+
end
|
52
|
+
|
67
53
|
def apply(*args)
|
68
54
|
SetBuilder::Constraint.new(self, *args, &@block)
|
69
55
|
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def parse(trait_definition)
|
60
|
+
regex = Regexp.union(LEXER.values)
|
61
|
+
trait_definition.split(regex).map do |lexeme|
|
62
|
+
[token_for(lexeme), value_for(lexeme)] unless lexeme.strip.empty?
|
63
|
+
end.compact
|
64
|
+
end
|
70
65
|
|
66
|
+
def token_for(lexeme)
|
67
|
+
LEXER.each { |token, pattern| return token if pattern.match(lexeme) }
|
68
|
+
return :string
|
69
|
+
end
|
71
70
|
|
72
|
-
|
71
|
+
def value_for(lexeme)
|
72
|
+
lexeme.to_s.strip.gsub(/[<>"\[\]:]/, "")
|
73
|
+
end
|
74
|
+
|
73
75
|
end
|
74
|
-
end
|
76
|
+
end
|
@@ -16,14 +16,15 @@ module SetBuilder
|
|
16
16
|
|
17
17
|
def self.to_s(name, value)
|
18
18
|
if value.is_a?(Array)
|
19
|
-
values = value.map { |value|
|
20
|
-
|
21
|
-
when 0
|
22
|
-
when 1
|
23
|
-
when 2
|
24
|
-
else
|
19
|
+
values = value.map { |value| to_s(name, value) }
|
20
|
+
case value.length
|
21
|
+
when 0 then return ""
|
22
|
+
when 1 then return values.first
|
23
|
+
when 2 then return "#{values.first} or #{values.last}"
|
24
|
+
else return "#{values[0..-2].join(', ')}, or #{values.last}"
|
25
25
|
end
|
26
26
|
end
|
27
|
+
|
27
28
|
name = name.to_sym
|
28
29
|
map = @registered_value_maps[name]
|
29
30
|
if map
|
@@ -44,7 +45,7 @@ module SetBuilder
|
|
44
45
|
|
45
46
|
|
46
47
|
def self.register_collection(name, collection, name_method = :name, id_method = :id)
|
47
|
-
map = collection.map {|i| [i.send(id_method).to_s, i.send(name_method)]}
|
48
|
+
map = collection.map { |i| [i.send(id_method).to_s, i.send(name_method)] }
|
48
49
|
register(name, map)
|
49
50
|
end
|
50
51
|
|
data/lib/set_builder/version.rb
CHANGED
data/lib/set_builder.rb
CHANGED
@@ -8,8 +8,7 @@ require 'set_builder/engine'
|
|
8
8
|
|
9
9
|
|
10
10
|
module SetBuilder
|
11
|
-
|
12
|
-
|
11
|
+
|
13
12
|
def self.extended(base)
|
14
13
|
base.instance_variable_set("@traits", SetBuilder::Traits.new)
|
15
14
|
base.send(:include, SetBuilder::Modifiers)
|
@@ -18,47 +17,22 @@ module SetBuilder
|
|
18
17
|
|
19
18
|
attr_reader :traits
|
20
19
|
|
21
|
-
|
22
20
|
def modifiers
|
23
21
|
traits.modifiers
|
24
22
|
end
|
25
23
|
|
26
|
-
|
27
24
|
def that_belong_to(set)
|
28
25
|
SetBuilder::Set.new(self, to_scope, set)
|
29
26
|
end
|
30
27
|
|
31
|
-
|
32
28
|
def to_scope
|
33
29
|
scoped
|
34
30
|
end
|
35
|
-
|
36
|
-
|
31
|
+
|
37
32
|
protected
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
def trait(*args, &block)
|
42
|
-
part_of_speech = get_part_of_speech(args.shift)
|
43
|
-
name = args.shift
|
44
|
-
traits << Trait.new(name, part_of_speech, *args, &block)
|
45
|
-
end
|
46
|
-
|
47
|
-
|
48
|
-
def get_part_of_speech(arg)
|
49
|
-
case arg
|
50
|
-
when :is, :are, :reflexive
|
51
|
-
:reflexive
|
52
|
-
when nil, :active
|
53
|
-
:active
|
54
|
-
when :was, :were, :passive
|
55
|
-
:passive
|
56
|
-
when :has, :have, :perfect
|
57
|
-
:perfect
|
58
|
-
when :whose, :noun
|
59
|
-
:noun
|
60
|
-
end
|
33
|
+
|
34
|
+
def trait(trait_expression, &block)
|
35
|
+
traits << Trait.new(trait_expression, &block)
|
61
36
|
end
|
62
37
|
|
63
|
-
|
64
|
-
end
|
38
|
+
end
|
data/set_builder.gemspec
CHANGED
@@ -18,9 +18,10 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "rails", ">= 3.1", "<
|
22
|
-
spec.add_dependency "arel"
|
21
|
+
spec.add_dependency "rails", ">= 3.1", "< 4.2"
|
22
|
+
spec.add_dependency "arel"
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.3"
|
24
24
|
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "jspec"
|
25
26
|
spec.add_development_dependency "pry"
|
26
27
|
end
|
data/spec/dom.html
CHANGED
@@ -3,8 +3,7 @@
|
|
3
3
|
<link type="text/css" rel="stylesheet" href="./lib/jspec.css" />
|
4
4
|
<script src="./lib/jspec.js"></script>
|
5
5
|
<script src="./lib/jspec.xhr.js"></script>
|
6
|
-
<script src="../assets/
|
7
|
-
<script src="../assets/set_builder.js"></script>
|
6
|
+
<script src="../lib/assets/javascripts/set_builder.js"></script>
|
8
7
|
<script src="unit/spec.helper.js"></script>
|
9
8
|
<script>
|
10
9
|
function runSuites() {
|
@@ -21,4 +20,4 @@
|
|
21
20
|
<div id="jspec"></div>
|
22
21
|
<div id="jspec-bottom"></div>
|
23
22
|
</body>
|
24
|
-
</html>
|
23
|
+
</html>
|
data/spec/unit/array.spec.js
CHANGED
@@ -66,6 +66,14 @@ describe 'Array'
|
|
66
66
|
})).to(be, "what?")
|
67
67
|
end
|
68
68
|
end
|
69
|
+
|
70
|
+
describe '.select'
|
71
|
+
it 'should return all members of the array where fn(member) is true'
|
72
|
+
expect(["this", "nope", "that", "this"].select(function(word){
|
73
|
+
return word == "this";
|
74
|
+
})).to(eql, ["this", "this"]);
|
75
|
+
end
|
76
|
+
end
|
69
77
|
|
70
78
|
end
|
71
79
|
|
@@ -79,4 +87,4 @@ describe 'Object'
|
|
79
87
|
end
|
80
88
|
end
|
81
89
|
|
82
|
-
end
|
90
|
+
end
|
@@ -2,11 +2,25 @@ describe 'SetBuilder'
|
|
2
2
|
before_each
|
3
3
|
|
4
4
|
SetBuilder.registerTraits([
|
5
|
-
['
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
[['string','who are'],
|
6
|
+
['negative','not'],
|
7
|
+
['name','awesome']],
|
8
|
+
[['string','who'],
|
9
|
+
['negative','have not'],
|
10
|
+
['name','died']],
|
11
|
+
[['string','who were'],
|
12
|
+
['name','born'],
|
13
|
+
['modifier','date']],
|
14
|
+
[['string','whose'],
|
15
|
+
['name','age'],
|
16
|
+
['modifier','number']],
|
17
|
+
[['string','who have'],
|
18
|
+
['negative','not'],
|
19
|
+
['name','attended'],
|
20
|
+
['direct_object_type','school']],
|
21
|
+
[['string','whose'],
|
22
|
+
['name','name'],
|
23
|
+
['modifier','string']]
|
10
24
|
]);
|
11
25
|
|
12
26
|
SetBuilder.registerModifiers({
|
@@ -59,23 +73,19 @@ describe 'SetBuilder'
|
|
59
73
|
describe '.Trait'
|
60
74
|
|
61
75
|
describe '.constructor'
|
62
|
-
it 'should correctly parse
|
63
|
-
var trait = new SetBuilder.Trait(['
|
76
|
+
it 'should correctly parse the name of the trait'
|
77
|
+
var trait = new SetBuilder.Trait([['string', 'who are'], ['name', 'awesome']]);
|
64
78
|
expect(trait.name()).to(be, 'awesome');
|
65
|
-
expect(trait.toString()).to(eql, 'who are awesome');
|
66
79
|
end
|
67
80
|
|
68
|
-
it 'should correctly identify direct objects'
|
69
|
-
var trait = new SetBuilder.Trait([['
|
70
|
-
expect(trait.
|
71
|
-
expect(trait.requires_direct_object()).to(be, true);
|
72
|
-
expect(trait.toString()).to(eql, 'who have attended');
|
81
|
+
it 'should correctly identify when it expects a direct objects'
|
82
|
+
var trait = new SetBuilder.Trait([['string', 'who have'], ['name', 'attended'], ['direct_object_type', 'string']]);
|
83
|
+
expect(trait.requiresDirectObject()).to(be, true);
|
73
84
|
end
|
74
85
|
|
75
86
|
it 'should correctly parse paramters with modifiers'
|
76
|
-
var trait = new SetBuilder.Trait(['
|
87
|
+
var trait = new SetBuilder.Trait([['string', 'who were'], ['name', 'born'], ['modifier', 'date']]);
|
77
88
|
expect(trait.modifiers().length).to(be, 1);
|
78
|
-
expect(trait.toString()).to(eql, 'who were born');
|
79
89
|
end
|
80
90
|
end
|
81
91
|
|
@@ -90,17 +100,17 @@ describe 'SetBuilder'
|
|
90
100
|
|
91
101
|
describe '.length'
|
92
102
|
it 'should have parsed the data structure correctly'
|
93
|
-
expect(traits.length()).to(be,
|
103
|
+
expect(traits.length()).to(be, 6);
|
94
104
|
end
|
95
105
|
end
|
96
106
|
|
97
107
|
describe '.find'
|
98
108
|
it 'should get a SetBuilder.Trait object by name'
|
99
|
-
expect(traits.__find('awesome').
|
100
|
-
expect(traits.__find('died').
|
101
|
-
expect(traits.__find('born').
|
102
|
-
expect(traits.__find('attended').
|
103
|
-
expect(traits.__find('name').
|
109
|
+
expect(traits.__find('awesome').name()).to(eql, 'awesome');
|
110
|
+
expect(traits.__find('died').name()).to(eql, 'died');
|
111
|
+
expect(traits.__find('born').name()).to(eql, 'born');
|
112
|
+
expect(traits.__find('attended').name()).to(eql,'attended');
|
113
|
+
expect(traits.__find('name').name()).to(eql, 'name');
|
104
114
|
end
|
105
115
|
end
|
106
116
|
|
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class DatePrepositionTest < ActiveSupport::TestCase
|
4
4
|
include SetBuilder::Modifiers
|
5
5
|
|
6
6
|
|
7
7
|
test "should constrain our date queries to A.D." do
|
8
|
-
modifier =
|
8
|
+
modifier = DatePreposition.new({:in_the_last => [Date.today.year, "years"]})
|
9
9
|
assert_equal "x>='0001-01-01'", modifier.build_conditions_for("x")
|
10
10
|
end
|
11
11
|
|
12
12
|
|
13
|
-
end
|
13
|
+
end
|
data/test/inflector_test.rb
CHANGED
@@ -4,24 +4,24 @@ class InflectorTest < ActiveSupport::TestCase
|
|
4
4
|
|
5
5
|
|
6
6
|
test "active" do
|
7
|
-
assert_equal "who died", SetBuilder::Trait.new("died"
|
7
|
+
assert_equal "who died", SetBuilder::Trait.new('who "died"').to_s
|
8
8
|
end
|
9
9
|
|
10
10
|
test "perfect" do
|
11
|
-
assert_equal "who have attended", SetBuilder::Trait.new("attended"
|
11
|
+
assert_equal "who have attended", SetBuilder::Trait.new('who have "attended"').to_s
|
12
12
|
end
|
13
13
|
|
14
14
|
test "passive" do
|
15
|
-
assert_equal "who were born", SetBuilder::Trait.new("born"
|
15
|
+
assert_equal "who were born", SetBuilder::Trait.new('who were "born"').to_s
|
16
16
|
end
|
17
17
|
|
18
18
|
test "reflexive" do
|
19
|
-
assert_equal "who are awesome", SetBuilder::Trait.new("awesome"
|
19
|
+
assert_equal "who are awesome", SetBuilder::Trait.new('who are "awesome"').to_s
|
20
20
|
end
|
21
21
|
|
22
22
|
test "noun" do
|
23
|
-
assert_equal "whose name", SetBuilder::Trait.new("name"
|
23
|
+
assert_equal "whose name", SetBuilder::Trait.new('whose "name"').to_s
|
24
24
|
end
|
25
25
|
|
26
26
|
|
27
|
-
end
|
27
|
+
end
|
data/test/modifier_test.rb
CHANGED
@@ -5,11 +5,11 @@ class ModifierTest < ActiveSupport::TestCase
|
|
5
5
|
|
6
6
|
|
7
7
|
test "get type with string" do
|
8
|
-
assert_equal
|
8
|
+
assert_equal StringPreposition, SetBuilder::Modifier["StringPreposition"]
|
9
9
|
end
|
10
10
|
|
11
11
|
test "get type with symbol" do
|
12
|
-
assert_equal
|
12
|
+
assert_equal StringPreposition, SetBuilder::Modifier[:string]
|
13
13
|
end
|
14
14
|
|
15
15
|
test "registering a modifier" do
|
@@ -87,4 +87,4 @@ class HashModifier < SetBuilder::Modifier::Verb
|
|
87
87
|
[:has_key]
|
88
88
|
end
|
89
89
|
|
90
|
-
end
|
90
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class StringPrepositionTest < ActiveSupport::TestCase
|
4
4
|
include SetBuilder::Modifiers
|
5
5
|
|
6
6
|
attr_reader :table
|
@@ -11,7 +11,7 @@ class StringModifierTest < ActiveSupport::TestCase
|
|
11
11
|
|
12
12
|
|
13
13
|
test "#build_arel_for should generate the correct SQL" do
|
14
|
-
modifier =
|
14
|
+
modifier = StringPreposition.new({:does_not_contain => ["banana"]})
|
15
15
|
assert_equal "\"fruits\".\"name\" NOT LIKE '%banana%'", modifier.build_arel_for(table[:name]).to_sql
|
16
16
|
end
|
17
17
|
|
data/test/test_helper.rb
CHANGED
@@ -15,40 +15,33 @@ SetBuilder::ValueMap.register(:school, [[1, "Concordia"], [2, "McKendree"]])
|
|
15
15
|
class Friend
|
16
16
|
extend SetBuilder
|
17
17
|
|
18
|
-
|
19
|
-
trait(:is, "awesome") do |query, scope|
|
18
|
+
trait('who are [not] "awesome"') do |query, scope|
|
20
19
|
scope << {:conditions => {:awesome => true}}
|
21
20
|
end
|
22
21
|
|
23
|
-
trait(
|
22
|
+
trait('who [have not] "died"') do |query, scope|
|
24
23
|
scope << {:conditions => {:alive => false}}
|
25
24
|
end
|
26
25
|
|
27
|
-
|
28
|
-
trait(:was, "born", :date) do |query, scope|
|
26
|
+
trait('who were "born" <date>') do |query, scope|
|
29
27
|
scope << {:conditions => query.modifiers[0].build_conditions_for("friends.birthday")}
|
30
28
|
end
|
31
29
|
|
32
|
-
trait(
|
30
|
+
trait('whose "age" <number>') do |query, scope|
|
33
31
|
scope << {:conditions => query.modifiers[0].build_conditions_for("friends.age")}
|
34
32
|
end
|
35
33
|
|
36
|
-
|
37
|
-
trait(:has, {"attended" => :school}) do |query, scope|
|
34
|
+
trait('who have [not] "attended" :school') do |query, scope|
|
38
35
|
scope << {
|
39
36
|
:joins => "INNER JOIN schools ON friends.school_id=schools.id",
|
40
37
|
:conditions => {"schools.id" => query.direct_object}
|
41
38
|
}
|
42
39
|
end
|
43
40
|
|
44
|
-
|
45
|
-
# also modifiers can be classes
|
46
|
-
trait(:whose, "name", StringModifier) do |query, scope|
|
41
|
+
trait('whose "name" <string>') do |query, scope|
|
47
42
|
scope << {:conditions => query.modifiers[0].build_conditions_for("friends.name")}
|
48
43
|
end
|
49
44
|
|
50
|
-
|
51
|
-
|
52
45
|
# by stubbing out scoped, we can unit test the `performed` features
|
53
46
|
def self.to_scope
|
54
47
|
[]
|
data/test/trait_test.rb
CHANGED
@@ -10,7 +10,7 @@ class TraitTest < ActiveSupport::TestCase
|
|
10
10
|
|
11
11
|
constraint = trait.apply({:is => "Jerome"})
|
12
12
|
assert_equal 1, constraint.modifiers.length
|
13
|
-
assert_kind_of
|
13
|
+
assert_kind_of StringPreposition, constraint.modifiers.first
|
14
14
|
end
|
15
15
|
|
16
16
|
test "modifiers should find correct values" do
|
data/test/traits_test.rb
CHANGED
@@ -23,17 +23,30 @@ class TraitsTest < ActiveSupport::TestCase
|
|
23
23
|
end
|
24
24
|
|
25
25
|
test "collection of modifiers" do
|
26
|
-
expected_modifiers = %w{
|
26
|
+
expected_modifiers = %w{DatePreposition NumberPreposition StringPreposition}.collect {|name| "SetBuilder::Modifiers::#{name}"}
|
27
27
|
assert_equal expected_modifiers, Friend.traits.modifiers.collect(&:name).sort
|
28
28
|
end
|
29
29
|
|
30
30
|
test "to_json" do
|
31
|
-
expected_json = [[
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
expected_json = [[["string","who are"],
|
32
|
+
["negative","not"],
|
33
|
+
["name","awesome"]],
|
34
|
+
[["string","who"],
|
35
|
+
["negative","have not"],
|
36
|
+
["name","died"]],
|
37
|
+
[["string","who were"],
|
38
|
+
["name","born"],
|
39
|
+
["modifier","date"]],
|
40
|
+
[["string","whose"],
|
41
|
+
["name","age"],
|
42
|
+
["modifier","number"]],
|
43
|
+
[["string","who have"],
|
44
|
+
["negative","not"],
|
45
|
+
["name","attended"],
|
46
|
+
["direct_object_type","school"]],
|
47
|
+
[["string","whose"],
|
48
|
+
["name","name"],
|
49
|
+
["modifier","string"]]].to_json
|
37
50
|
assert_equal expected_json, Friend.traits.to_json
|
38
51
|
end
|
39
52
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: set_builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bob Lail
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: '3.1'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '4.2'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,21 +29,21 @@ dependencies:
|
|
29
29
|
version: '3.1'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '4.2'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: arel
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- - "
|
37
|
+
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '
|
39
|
+
version: '0'
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
|
-
- - "
|
44
|
+
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
46
|
+
version: '0'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: bundler
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,6 +72,20 @@ dependencies:
|
|
72
72
|
- - ">="
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: jspec
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
75
89
|
- !ruby/object:Gem::Dependency
|
76
90
|
name: pry
|
77
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -111,9 +125,9 @@ files:
|
|
111
125
|
- lib/set_builder/modifier/verb.rb
|
112
126
|
- lib/set_builder/modifier_collection.rb
|
113
127
|
- lib/set_builder/modifiers.rb
|
114
|
-
- lib/set_builder/modifiers/
|
115
|
-
- lib/set_builder/modifiers/
|
116
|
-
- lib/set_builder/modifiers/
|
128
|
+
- lib/set_builder/modifiers/date_preposition.rb
|
129
|
+
- lib/set_builder/modifiers/number_preposition.rb
|
130
|
+
- lib/set_builder/modifiers/string_preposition.rb
|
117
131
|
- lib/set_builder/query_builders/string.rb
|
118
132
|
- lib/set_builder/set.rb
|
119
133
|
- lib/set_builder/trait.rb
|
@@ -144,11 +158,11 @@ files:
|
|
144
158
|
- spec/unit/array.spec.js
|
145
159
|
- spec/unit/set_builder.spec.js
|
146
160
|
- spec/unit/spec.helper.js
|
147
|
-
- test/
|
161
|
+
- test/date_preposition_test.rb
|
148
162
|
- test/inflector_test.rb
|
149
163
|
- test/modifier_test.rb
|
150
164
|
- test/set_test.rb
|
151
|
-
- test/
|
165
|
+
- test/string_preposition_test.rb
|
152
166
|
- test/support/fake_connection.rb
|
153
167
|
- test/test_helper.rb
|
154
168
|
- test/trait_test.rb
|
@@ -204,11 +218,11 @@ test_files:
|
|
204
218
|
- spec/unit/array.spec.js
|
205
219
|
- spec/unit/set_builder.spec.js
|
206
220
|
- spec/unit/spec.helper.js
|
207
|
-
- test/
|
221
|
+
- test/date_preposition_test.rb
|
208
222
|
- test/inflector_test.rb
|
209
223
|
- test/modifier_test.rb
|
210
224
|
- test/set_test.rb
|
211
|
-
- test/
|
225
|
+
- test/string_preposition_test.rb
|
212
226
|
- test/support/fake_connection.rb
|
213
227
|
- test/test_helper.rb
|
214
228
|
- test/trait_test.rb
|