predicated 0.1.0 → 0.2.0
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/README.markdown +183 -1
- data/lib/predicated.rb +1 -3
- data/lib/predicated/constrain.rb +2 -0
- data/lib/predicated/evaluate.rb +25 -6
- data/lib/predicated/from/callable_object.rb +7 -8
- data/lib/predicated/from/json.rb +59 -0
- data/lib/predicated/from/{ruby_string.rb → ruby_code_string.rb} +13 -5
- data/lib/predicated/from/{url_fragment.rb → url_part.rb} +17 -10
- data/lib/predicated/from/xml.rb +61 -0
- data/lib/predicated/predicate.rb +62 -43
- data/lib/predicated/print.rb +28 -16
- data/lib/predicated/selectable.rb +102 -0
- data/lib/predicated/simple_templated_predicate.rb +79 -0
- data/lib/predicated/string_utils.rb +20 -0
- data/lib/predicated/to/arel.rb +28 -22
- data/lib/predicated/to/json.rb +48 -0
- data/lib/predicated/to/sentence.rb +17 -14
- data/lib/predicated/to/solr.rb +15 -0
- data/lib/predicated/to/xml.rb +67 -0
- data/lib/predicated/version.rb +2 -2
- data/test/canonical_transform_cases.rb +67 -0
- data/test/constrain_test.rb +20 -11
- data/test/enumerable_test.rb +6 -34
- data/test/equality_test.rb +15 -4
- data/test/evaluate_test.rb +31 -26
- data/test/from/callable_object_canonical_test.rb +43 -0
- data/test/from/callable_object_test.rb +16 -40
- data/test/from/json_test.rb +83 -0
- data/test/from/ruby_code_string_canonical_test.rb +37 -0
- data/test/from/ruby_code_string_test.rb +103 -0
- data/test/from/{url_fragment_parser_test.rb → url_part_parser_test.rb} +20 -13
- data/test/from/url_part_test.rb +48 -0
- data/test/from/xml_test.rb +57 -0
- data/test/json_conversion_test.rb +33 -0
- data/test/print_test.rb +26 -25
- data/test/selectable_test.rb +123 -0
- data/test/simple_templated_predicate_test.rb +39 -0
- data/test/suite.rb +2 -4
- data/test/test_helper.rb +26 -4
- data/test/test_helper_with_wrong.rb +3 -2
- data/test/to/arel_test.rb +71 -31
- data/test/to/json_test.rb +74 -0
- data/test/to/sentence_test.rb +41 -34
- data/test/to/solr_test.rb +39 -0
- data/test/to/xml_test.rb +72 -0
- data/test/xml_conversion_test.rb +34 -0
- metadata +44 -16
- data/lib/predicated/selector.rb +0 -55
- data/test/from/ruby_string_test.rb +0 -135
- data/test/from/url_fragment_test.rb +0 -37
- data/test/selector_test.rb +0 -82
@@ -0,0 +1,34 @@
|
|
1
|
+
require "./test/test_helper_with_wrong"
|
2
|
+
|
3
|
+
require "predicated/from/xml"
|
4
|
+
require "predicated/to/xml"
|
5
|
+
include Predicated
|
6
|
+
|
7
|
+
regarding "convert xml back and forth" do
|
8
|
+
|
9
|
+
test "string to predicate to string" do
|
10
|
+
assert{ Predicate.from_xml("<equal><left>a</left><right>3</right></equal>").to_xml ==
|
11
|
+
"<equal><left>a</left><right>3</right></equal>" }
|
12
|
+
|
13
|
+
complex_xml = %{
|
14
|
+
<or>
|
15
|
+
<and>
|
16
|
+
<equal><left>a</left><right>1</right></equal>
|
17
|
+
<equal><left>b</left><right>2</right></equal>
|
18
|
+
</and>
|
19
|
+
<equal><left>c</left><right>3</right></equal>
|
20
|
+
</or>
|
21
|
+
}
|
22
|
+
|
23
|
+
assert{ Predicate.from_xml(complex_xml).to_xml.gsub(/\s/, "") ==
|
24
|
+
complex_xml.gsub(/\s/, "") }
|
25
|
+
end
|
26
|
+
|
27
|
+
test "predicate to string to predicate. note the loss of type fidelity." do
|
28
|
+
assert{ Predicate.from_xml(Predicate{ Eq("a",3) }.to_xml) == Predicate{ Eq("a",'3') } }
|
29
|
+
|
30
|
+
assert{ Predicate.from_xml(Predicate{ Or(And(Eq("a",1),Eq("b",2)), Eq("c",3)) }.to_xml) ==
|
31
|
+
Predicate{ Or(And(Eq("a",'1'),Eq("b",'2')), Eq("c",'3')) } }
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: predicated
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 27
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
|
-
-
|
7
|
+
- 2
|
9
8
|
- 0
|
10
|
-
version: 0.
|
9
|
+
version: 0.2.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Steve Conover
|
@@ -31,32 +30,50 @@ files:
|
|
31
30
|
- lib/predicated/constrain.rb
|
32
31
|
- lib/predicated/evaluate.rb
|
33
32
|
- lib/predicated/from/callable_object.rb
|
34
|
-
- lib/predicated/from/
|
35
|
-
- lib/predicated/from/
|
33
|
+
- lib/predicated/from/json.rb
|
34
|
+
- lib/predicated/from/ruby_code_string.rb
|
35
|
+
- lib/predicated/from/url_part.rb
|
36
|
+
- lib/predicated/from/xml.rb
|
36
37
|
- lib/predicated/gem_check.rb
|
37
38
|
- lib/predicated/predicate.rb
|
38
39
|
- lib/predicated/print.rb
|
39
|
-
- lib/predicated/
|
40
|
+
- lib/predicated/selectable.rb
|
41
|
+
- lib/predicated/simple_templated_predicate.rb
|
42
|
+
- lib/predicated/string_utils.rb
|
40
43
|
- lib/predicated/to/arel.rb
|
44
|
+
- lib/predicated/to/json.rb
|
41
45
|
- lib/predicated/to/sentence.rb
|
46
|
+
- lib/predicated/to/solr.rb
|
47
|
+
- lib/predicated/to/xml.rb
|
42
48
|
- lib/predicated/version.rb
|
43
49
|
- lib/predicated.rb
|
44
50
|
- README.markdown
|
51
|
+
- test/canonical_transform_cases.rb
|
45
52
|
- test/constrain_test.rb
|
46
53
|
- test/enumerable_test.rb
|
47
54
|
- test/equality_test.rb
|
48
55
|
- test/evaluate_test.rb
|
56
|
+
- test/from/callable_object_canonical_test.rb
|
49
57
|
- test/from/callable_object_test.rb
|
50
|
-
- test/from/
|
51
|
-
- test/from/
|
52
|
-
- test/from/
|
58
|
+
- test/from/json_test.rb
|
59
|
+
- test/from/ruby_code_string_canonical_test.rb
|
60
|
+
- test/from/ruby_code_string_test.rb
|
61
|
+
- test/from/url_part_parser_test.rb
|
62
|
+
- test/from/url_part_test.rb
|
63
|
+
- test/from/xml_test.rb
|
64
|
+
- test/json_conversion_test.rb
|
53
65
|
- test/print_test.rb
|
54
|
-
- test/
|
66
|
+
- test/selectable_test.rb
|
67
|
+
- test/simple_templated_predicate_test.rb
|
55
68
|
- test/suite.rb
|
56
69
|
- test/test_helper.rb
|
57
70
|
- test/test_helper_with_wrong.rb
|
58
71
|
- test/to/arel_test.rb
|
72
|
+
- test/to/json_test.rb
|
59
73
|
- test/to/sentence_test.rb
|
74
|
+
- test/to/solr_test.rb
|
75
|
+
- test/to/xml_test.rb
|
76
|
+
- test/xml_conversion_test.rb
|
60
77
|
has_rdoc: true
|
61
78
|
homepage: http://github.com/sconover/predicated
|
62
79
|
licenses: []
|
@@ -71,7 +88,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
88
|
requirements:
|
72
89
|
- - ">="
|
73
90
|
- !ruby/object:Gem::Version
|
74
|
-
hash:
|
91
|
+
hash: 2382763030672668207
|
75
92
|
segments:
|
76
93
|
- 0
|
77
94
|
version: "0"
|
@@ -80,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
97
|
requirements:
|
81
98
|
- - ">="
|
82
99
|
- !ruby/object:Gem::Version
|
83
|
-
hash:
|
100
|
+
hash: 2382763030672668207
|
84
101
|
segments:
|
85
102
|
- 0
|
86
103
|
version: "0"
|
@@ -92,18 +109,29 @@ signing_key:
|
|
92
109
|
specification_version: 3
|
93
110
|
summary: Predicated is a simple predicate model for Ruby
|
94
111
|
test_files:
|
112
|
+
- test/canonical_transform_cases.rb
|
95
113
|
- test/constrain_test.rb
|
96
114
|
- test/enumerable_test.rb
|
97
115
|
- test/equality_test.rb
|
98
116
|
- test/evaluate_test.rb
|
117
|
+
- test/from/callable_object_canonical_test.rb
|
99
118
|
- test/from/callable_object_test.rb
|
100
|
-
- test/from/
|
101
|
-
- test/from/
|
102
|
-
- test/from/
|
119
|
+
- test/from/json_test.rb
|
120
|
+
- test/from/ruby_code_string_canonical_test.rb
|
121
|
+
- test/from/ruby_code_string_test.rb
|
122
|
+
- test/from/url_part_parser_test.rb
|
123
|
+
- test/from/url_part_test.rb
|
124
|
+
- test/from/xml_test.rb
|
125
|
+
- test/json_conversion_test.rb
|
103
126
|
- test/print_test.rb
|
104
|
-
- test/
|
127
|
+
- test/selectable_test.rb
|
128
|
+
- test/simple_templated_predicate_test.rb
|
105
129
|
- test/suite.rb
|
106
130
|
- test/test_helper.rb
|
107
131
|
- test/test_helper_with_wrong.rb
|
108
132
|
- test/to/arel_test.rb
|
133
|
+
- test/to/json_test.rb
|
109
134
|
- test/to/sentence_test.rb
|
135
|
+
- test/to/solr_test.rb
|
136
|
+
- test/to/xml_test.rb
|
137
|
+
- test/xml_conversion_test.rb
|
data/lib/predicated/selector.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
module Predicated
|
2
|
-
module Selector
|
3
|
-
#this is no doubt totally non-performant with all the extends, and
|
4
|
-
#could probably be just done better / more elegantly
|
5
|
-
#seek help.
|
6
|
-
|
7
|
-
def self.SelectorEnumerable(key_to_selecting_proc)
|
8
|
-
Module.new do
|
9
|
-
@key_to_selecting_proc = key_to_selecting_proc
|
10
|
-
|
11
|
-
def self.extended(base)
|
12
|
-
sym = "@key_to_selecting_proc".to_sym
|
13
|
-
hash = base.instance_variable_get(sym) || {}
|
14
|
-
base.instance_variable_set(sym, hash.merge(@key_to_selecting_proc))
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.included(base)
|
18
|
-
extended(base)
|
19
|
-
end
|
20
|
-
|
21
|
-
#ugh ugh
|
22
|
-
def key_to_selecting_proc
|
23
|
-
@key_to_selecting_proc || self.class.instance_variable_get("@key_to_selecting_proc".to_sym)
|
24
|
-
end
|
25
|
-
|
26
|
-
def select(*keys, &block)
|
27
|
-
key = keys.shift if keys.length>=1
|
28
|
-
result =
|
29
|
-
if key
|
30
|
-
selecting_proc = key_to_selecting_proc[key]
|
31
|
-
raise "no selector found for '#{key}'. current selectors: [#{key_to_selecting_proc.collect{|k,v|k.to_s}.join(",")}]" unless selecting_proc
|
32
|
-
memos_for(:select)[key] ||= super(&selecting_proc)
|
33
|
-
else
|
34
|
-
super(&block)
|
35
|
-
end
|
36
|
-
#ugh
|
37
|
-
result.extend(Predicated::Selector.SelectorEnumerable(key_to_selecting_proc))
|
38
|
-
keys.length>=1 ? result.select(*keys, &block) : result
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
def memos_for(group)
|
43
|
-
@memos ||= {}
|
44
|
-
@memos[group] ||= {}
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
#ugh
|
50
|
-
def SelectorEnumerable(key_to_selecting_proc)
|
51
|
-
Predicated::Selector.SelectorEnumerable(key_to_selecting_proc)
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
end
|
@@ -1,135 +0,0 @@
|
|
1
|
-
require "test/test_helper"
|
2
|
-
|
3
|
-
require "predicated/from/ruby_string"
|
4
|
-
include Predicated
|
5
|
-
|
6
|
-
apropos "parse a ruby predicate string" do
|
7
|
-
|
8
|
-
apropos "basic operations" do
|
9
|
-
|
10
|
-
#'Wrong'-style asserts are specifically avoided here.
|
11
|
-
#the circularity between the two projects will make you crazy if you're not careful
|
12
|
-
|
13
|
-
test "simple signs" do
|
14
|
-
assert_equal Predicate.from_ruby_string("1==1"), Predicate{ Eq(1,1) }
|
15
|
-
assert_equal Predicate.from_ruby_string(" 1 == 1 "), Predicate{ Eq(1,1) }
|
16
|
-
assert_equal Predicate.from_ruby_string("0<1"), Predicate{ Lt(0,1) }
|
17
|
-
assert_equal Predicate.from_ruby_string("2>1"), Predicate{ Gt(2,1) }
|
18
|
-
assert_equal Predicate.from_ruby_string("1<=1"), Predicate{ Lte(1,1) }
|
19
|
-
assert_equal Predicate.from_ruby_string("1>=1"), Predicate{ Gte(1,1) }
|
20
|
-
end
|
21
|
-
|
22
|
-
test "primitive types" do
|
23
|
-
assert_equal Predicate.from_ruby_string("false==true"), Predicate{ Eq(false,true) }
|
24
|
-
assert_equal Predicate.from_ruby_string("'yyy'=='zzz'"), Predicate{ Eq("yyy","zzz") }
|
25
|
-
end
|
26
|
-
|
27
|
-
test "simple and + or" do
|
28
|
-
assert_equal Predicate.from_ruby_string("1==1 && 2==2"), Predicate{ And(Eq(1,1),Eq(2,2)) }
|
29
|
-
assert_equal Predicate.from_ruby_string("1==1 and 2==2"), Predicate{ And(Eq(1,1),Eq(2,2)) }
|
30
|
-
assert_equal Predicate.from_ruby_string("1==1 || 2==2"), Predicate{ Or(Eq(1,1),Eq(2,2)) }
|
31
|
-
end
|
32
|
-
|
33
|
-
class Color
|
34
|
-
attr_reader :name
|
35
|
-
def initialize(name)
|
36
|
-
@name = name
|
37
|
-
end
|
38
|
-
|
39
|
-
def ==(other)
|
40
|
-
other.is_a?(Color) && @name == other.name
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
test "substitute in from the binding" do
|
45
|
-
a = 1
|
46
|
-
b = "1"
|
47
|
-
c = "c"
|
48
|
-
d = Color.new("purple")
|
49
|
-
|
50
|
-
assert_equal Predicate.from_ruby_string("a==1", binding()), Predicate{ Eq(1,1) }
|
51
|
-
assert_equal Predicate.from_ruby_string("b==1", binding()), Predicate{ Eq("1",1) }
|
52
|
-
assert_equal Predicate.from_ruby_string("c==b", binding()), Predicate{ Eq("c","1") }
|
53
|
-
assert_equal Predicate.from_ruby_string("d==d", binding()), Predicate{ Eq(Color.new("purple"),
|
54
|
-
Color.new("purple")) }
|
55
|
-
assert_equal Predicate.from_ruby_string("d==d", binding()).left, d
|
56
|
-
|
57
|
-
assert_equal Predicate.from_ruby_string("a==b && b==c", binding()),
|
58
|
-
Predicate{ And(Eq(1,"1"),Eq("1","c")) }
|
59
|
-
end
|
60
|
-
|
61
|
-
|
62
|
-
test "complex and + or" do
|
63
|
-
assert_equal Predicate.from_ruby_string("1==1 && 2==2 || 3==3"),
|
64
|
-
Predicate{ Or( And(Eq(1,1),Eq(2,2)), Eq(3,3) ) }
|
65
|
-
end
|
66
|
-
|
67
|
-
test "parens change precedence" do
|
68
|
-
assert_equal Predicate.from_ruby_string("1==1 || 2==2 && 3==3"),
|
69
|
-
Predicate{ Or( Eq(1,1), And(Eq(2,2),Eq(3,3)) ) }
|
70
|
-
|
71
|
-
assert_equal Predicate.from_ruby_string("(1==1 || 2==2) && 3==3"),
|
72
|
-
Predicate{ And( Or(Eq(1,1),Eq(2,2)), Eq(3,3) ) }
|
73
|
-
end
|
74
|
-
|
75
|
-
apropos "only pay attention to the final line" do
|
76
|
-
#might hate myself one day for this. but what else does it make sense to do?
|
77
|
-
|
78
|
-
test "simple" do
|
79
|
-
assert_equal Predicate.from_ruby_string("z=2\nb=5\n1==1"), Predicate{ Eq(1,1) }
|
80
|
-
end
|
81
|
-
|
82
|
-
test "can make use of variables defined earlier in the block" do
|
83
|
-
#might hate myself one day for this. but what else does it make sense to do?
|
84
|
-
assert_equal Predicate.from_ruby_string("z=2\nb=5\nz==1"), Predicate{ Eq(2,1) }
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
test "a call that returns a boolean result" do
|
89
|
-
assert_equal Predicate.from_ruby_string("'abc'.include?('bc')"),
|
90
|
-
Predicate{ Call("abc", :include?, "bc") }
|
91
|
-
|
92
|
-
color = Color.new("purple")
|
93
|
-
assert_equal Predicate.from_ruby_string("color.name.include?('rp')", binding()),
|
94
|
-
Predicate{ Call("purple", :include?, "rp") }
|
95
|
-
|
96
|
-
assert_equal Predicate.from_ruby_string("'abc'.nil?"),
|
97
|
-
Predicate{ Call("abc", :nil?, nil) }
|
98
|
-
end
|
99
|
-
|
100
|
-
test "use of instance variables" do
|
101
|
-
@a = 1
|
102
|
-
|
103
|
-
assert_equal Predicate.from_ruby_string("@a==1", binding()), Predicate{ Eq(1,1) }
|
104
|
-
end
|
105
|
-
|
106
|
-
test "use of inline assignments" do
|
107
|
-
assert_equal Predicate.from_ruby_string("(a=2)==1 && a==1"),
|
108
|
-
Predicate{ And(Eq(2,1), Eq(2,1)) }
|
109
|
-
end
|
110
|
-
|
111
|
-
test "use of inline expressions" do
|
112
|
-
assert_equal Predicate.from_ruby_string("(2*1)==1"),
|
113
|
-
Predicate{ Eq(2,1) }
|
114
|
-
|
115
|
-
assert_equal Predicate.from_ruby_string("[2,1].first==1"),
|
116
|
-
Predicate{ Eq(2,1) }
|
117
|
-
end
|
118
|
-
|
119
|
-
|
120
|
-
end
|
121
|
-
|
122
|
-
apropos "errors" do
|
123
|
-
test "can't parse" do
|
124
|
-
assert_raises(Racc::ParseError) do
|
125
|
-
Predicate.from_ruby_string("bad ruby @@@@@****()(((")
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
test "predicates only" do
|
130
|
-
assert_raises(Predicated::Predicate::DontKnowWhatToDoWithThisSexpError) do
|
131
|
-
Predicate.from_ruby_string("a=1")
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require "test/test_helper_with_wrong"
|
2
|
-
|
3
|
-
require "predicated/from/url_fragment"
|
4
|
-
include Predicated
|
5
|
-
|
6
|
-
apropos "parse url fragments and convert them into predicates" do
|
7
|
-
|
8
|
-
apropos "basic operations" do
|
9
|
-
|
10
|
-
test "simple signs" do
|
11
|
-
assert { Predicate.from_url_fragment("a=1") == Predicate{ Eq("a","1") } }
|
12
|
-
assert { Predicate.from_url_fragment("a<1") == Predicate{ Lt("a","1") } }
|
13
|
-
assert { Predicate.from_url_fragment("a>1") == Predicate{ Gt("a","1") } }
|
14
|
-
assert { Predicate.from_url_fragment("a<=1") == Predicate{ Lte("a","1") } }
|
15
|
-
assert { Predicate.from_url_fragment("a>=1") == Predicate{ Gte("a","1") } }
|
16
|
-
end
|
17
|
-
|
18
|
-
test "simple and + or" do
|
19
|
-
assert { Predicate.from_url_fragment("a=1&b=2") == Predicate{ And(Eq("a","1"),Eq("b","2")) } }
|
20
|
-
assert { Predicate.from_url_fragment("a=1|b=2") == Predicate{ Or(Eq("a","1"),Eq("b","2")) } }
|
21
|
-
end
|
22
|
-
|
23
|
-
test "complex and + or" do
|
24
|
-
assert { Predicate.from_url_fragment("a=1&b=2|c=3") ==
|
25
|
-
Predicate{ Or( And(Eq("a","1"),Eq("b","2")), Eq("c","3") ) } }
|
26
|
-
end
|
27
|
-
|
28
|
-
test "parens change precedence" do
|
29
|
-
assert { Predicate.from_url_fragment("a=1|b=2&c=3") ==
|
30
|
-
Predicate{ Or( Eq("a","1"), And(Eq("b","2"),Eq("c","3")) ) } }
|
31
|
-
|
32
|
-
assert { Predicate.from_url_fragment("(a=1|b=2)&c=3") ==
|
33
|
-
Predicate{ And( Or(Eq("a","1"),Eq("b","2")), Eq("c","3") ) } }
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
data/test/selector_test.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
require "test/test_helper_with_wrong"
|
2
|
-
|
3
|
-
require "predicated/selector"
|
4
|
-
include Predicated::Selector
|
5
|
-
|
6
|
-
apropos "part one: selectors on an array (simple enumerable). proving them out more generally." do
|
7
|
-
before do
|
8
|
-
@arr = [1,2,"c",4,"e",6]
|
9
|
-
@arr.extend SelectorEnumerable(
|
10
|
-
:strings => proc{|item|item.is_a?(String)},
|
11
|
-
:numbers => proc{|item|item.is_a?(Numeric)},
|
12
|
-
:less_than_3 => proc{|item|item < 3}
|
13
|
-
)
|
14
|
-
end
|
15
|
-
|
16
|
-
test %{selection basics.
|
17
|
-
People often remark that this kind of thing is jQuery-like.
|
18
|
-
I keep thinking I got it from Eric Evans.} do
|
19
|
-
assert{ @arr.select(:strings) == ["c","e"] }
|
20
|
-
assert{ @arr.select(:numbers) == [1,2,4,6] }
|
21
|
-
assert{ @arr.select(:numbers).select(:less_than_3) == [1,2] }
|
22
|
-
|
23
|
-
assert do
|
24
|
-
catch_raise{@arr.select(:less_than_3)}.is_a?(ArgumentError)
|
25
|
-
#because strings don't respond to <
|
26
|
-
#...there's no substitute for knowing what you're doing.
|
27
|
-
end
|
28
|
-
|
29
|
-
#normal select still works
|
30
|
-
assert{ @arr.select{|item|item.is_a?(String)} == ["c","e"] }
|
31
|
-
end
|
32
|
-
|
33
|
-
test "...selector name can be any object" do
|
34
|
-
arr = [1,2,"c",4,"e",6]
|
35
|
-
arr.extend SelectorEnumerable(
|
36
|
-
String => proc{|item|item.is_a?(String)},
|
37
|
-
Numeric => proc{|item|item.is_a?(Numeric)},
|
38
|
-
:less_than_3 => proc{|item|item < 3}
|
39
|
-
)
|
40
|
-
|
41
|
-
assert{ arr.select(String) == ["c","e"] }
|
42
|
-
assert{ arr.select(Numeric) == [1,2,4,6] }
|
43
|
-
assert{ arr.select(Numeric).select(:less_than_3) == [1,2] }
|
44
|
-
end
|
45
|
-
|
46
|
-
test "chaining. also works using varargs" do
|
47
|
-
assert{ @arr.select(:numbers).select(:less_than_3) == [1,2] }
|
48
|
-
assert{ @arr.select(:numbers, :less_than_3) == [1,2] }
|
49
|
-
end
|
50
|
-
|
51
|
-
test "extending twice is additive (not destructive)" do
|
52
|
-
arr = [1,2,"c",4,"e",6]
|
53
|
-
arr.extend SelectorEnumerable(:strings => proc{|item|item.is_a?(String)})
|
54
|
-
arr.extend SelectorEnumerable(:numbers => proc{|item|item.is_a?(Numeric)})
|
55
|
-
|
56
|
-
assert{ arr.select(:strings) == ["c","e"] }
|
57
|
-
assert{ arr.select(:numbers) == [1,2,4,6] }
|
58
|
-
end
|
59
|
-
|
60
|
-
test "works as an include" do
|
61
|
-
class MyArray < Array
|
62
|
-
include SelectorEnumerable(:strings => proc{|item|item.is_a?(String)})
|
63
|
-
include SelectorEnumerable(:numbers => proc{|item|item.is_a?(Numeric)})
|
64
|
-
end
|
65
|
-
arr = MyArray.new
|
66
|
-
arr.replace([1,2,"c",4,"e",6])
|
67
|
-
|
68
|
-
assert{ arr.select(:strings) == ["c","e"] }
|
69
|
-
assert{ arr.select(:numbers) == [1,2,4,6] }
|
70
|
-
end
|
71
|
-
|
72
|
-
test %{memoizes.
|
73
|
-
Selector enumerable assumes an immutable collection.
|
74
|
-
I'm going to use that assumption against it, and cleverly prove that memoization works.
|
75
|
-
(Others might choose to mock in similar circumstances.)} do
|
76
|
-
assert{ @arr.select(:strings) == ["c","e"] }
|
77
|
-
|
78
|
-
@arr << "zzz"
|
79
|
-
|
80
|
-
assert{ @arr.select(:strings) == ["c","e"] }
|
81
|
-
end
|
82
|
-
end
|