wrong 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/README.markdown +114 -25
  2. data/lib/predicated/Gemfile +15 -0
  3. data/lib/predicated/LICENSE +20 -0
  4. data/lib/predicated/README.markdown +191 -0
  5. data/lib/predicated/Rakefile +51 -0
  6. data/lib/predicated/lib/predicated.rb +4 -0
  7. data/lib/predicated/lib/predicated/autogen_call.rb +37 -0
  8. data/lib/predicated/lib/predicated/constrain.rb +66 -0
  9. data/lib/predicated/lib/predicated/evaluate.rb +94 -0
  10. data/lib/predicated/lib/predicated/from/callable_object.rb +108 -0
  11. data/lib/predicated/lib/predicated/from/json.rb +59 -0
  12. data/lib/predicated/lib/predicated/from/ruby_code_string.rb +73 -0
  13. data/lib/predicated/lib/predicated/from/url_part.rb +104 -0
  14. data/lib/predicated/lib/predicated/from/xml.rb +61 -0
  15. data/lib/predicated/lib/predicated/gem_check.rb +34 -0
  16. data/lib/predicated/lib/predicated/predicate.rb +111 -0
  17. data/lib/predicated/lib/predicated/print.rb +62 -0
  18. data/lib/predicated/lib/predicated/selectable.rb +102 -0
  19. data/lib/predicated/lib/predicated/simple_templated_predicate.rb +79 -0
  20. data/lib/predicated/lib/predicated/string_utils.rb +20 -0
  21. data/lib/predicated/lib/predicated/to/arel.rb +41 -0
  22. data/lib/predicated/lib/predicated/to/json.rb +48 -0
  23. data/lib/predicated/lib/predicated/to/sentence.rb +94 -0
  24. data/lib/predicated/lib/predicated/to/solr.rb +15 -0
  25. data/lib/predicated/lib/predicated/to/xml.rb +67 -0
  26. data/lib/predicated/lib/predicated/version.rb +3 -0
  27. data/lib/predicated/predicated.gemspec +22 -0
  28. data/lib/predicated/test/autogen_call_test.rb +40 -0
  29. data/lib/predicated/test/canonical_transform_cases.rb +63 -0
  30. data/lib/predicated/test/constrain_test.rb +86 -0
  31. data/lib/predicated/test/enumerable_test.rb +32 -0
  32. data/lib/predicated/test/equality_test.rb +32 -0
  33. data/lib/predicated/test/evaluate_test.rb +149 -0
  34. data/lib/predicated/test/from/callable_object_canonical_test.rb +43 -0
  35. data/lib/predicated/test/from/callable_object_test.rb +78 -0
  36. data/lib/predicated/test/from/json_test.rb +83 -0
  37. data/lib/predicated/test/from/ruby_code_string_canonical_test.rb +37 -0
  38. data/lib/predicated/test/from/ruby_code_string_test.rb +103 -0
  39. data/lib/predicated/test/from/url_part_parser_test.rb +123 -0
  40. data/lib/predicated/test/from/url_part_test.rb +48 -0
  41. data/lib/predicated/test/from/xml_test.rb +57 -0
  42. data/lib/predicated/test/json_conversion_test.rb +33 -0
  43. data/lib/predicated/test/print_test.rb +66 -0
  44. data/lib/predicated/test/selectable_test.rb +123 -0
  45. data/lib/predicated/test/simple_templated_predicate_test.rb +39 -0
  46. data/lib/predicated/test/suite.rb +2 -0
  47. data/lib/predicated/test/test_helper.rb +64 -0
  48. data/lib/predicated/test/test_helper_with_wrong.rb +6 -0
  49. data/lib/predicated/test/to/arel_test.rb +85 -0
  50. data/lib/predicated/test/to/json_test.rb +74 -0
  51. data/lib/predicated/test/to/sentence_test.rb +90 -0
  52. data/lib/predicated/test/to/solr_test.rb +39 -0
  53. data/lib/predicated/test/to/xml_test.rb +72 -0
  54. data/lib/predicated/test/xml_conversion_test.rb +34 -0
  55. data/lib/predicated/test_integration/arel_integration_test.rb +52 -0
  56. data/lib/predicated/test_integration/canonical_integration_cases.rb +66 -0
  57. data/lib/predicated/test_integration/schema.xml +83 -0
  58. data/lib/predicated/test_integration/solr_integration_test.rb +71 -0
  59. data/lib/predicated/test_integration/sqlite_db +0 -0
  60. data/lib/predicated/test_integration/suite.rb +2 -0
  61. data/lib/predicated/test_integration/usage_test.rb +252 -0
  62. data/lib/wrong.rb +3 -1
  63. data/lib/wrong/adapters/test_unit.rb +1 -3
  64. data/lib/wrong/assert.rb +81 -24
  65. data/lib/wrong/chunk.rb +145 -0
  66. data/lib/wrong/message/string_diff.rb +2 -4
  67. data/lib/wrong/message/test_context.rb +2 -2
  68. data/lib/wrong/version.rb +2 -2
  69. data/test/adapters/minitest_test.rb +16 -9
  70. data/test/adapters/test_unit_test.rb +1 -1
  71. data/test/assert_test.rb +90 -0
  72. data/test/catch_raise_test.rb +2 -2
  73. data/test/chunk_test.rb +236 -0
  74. data/test/failures_test.rb +109 -74
  75. data/test/message/array_diff_test.rb +35 -19
  76. data/test/message/string_diff_test.rb +39 -15
  77. data/test/message/test_context_text.rb +2 -2
  78. data/test/test_helper.rb +25 -7
  79. metadata +86 -33
  80. data/test/basic_assert_test.rb +0 -38
@@ -0,0 +1,123 @@
1
+ require "./test/test_helper_with_wrong"
2
+
3
+ require "predicated/selectable"
4
+
5
+ regarding "part one: selectors on an array (simple enumerable). proving them out more generally." do
6
+ before do
7
+ @arr = [1,2,"c",4,"e",6]
8
+ Predicated::Selectable.bless_enumerable(@arr,
9
+ :strings => proc{|item|item.is_a?(String)},
10
+ :numbers => proc{|item|item.is_a?(Numeric)},
11
+ :less_than_3 => proc{|item|item < 3}
12
+ )
13
+ end
14
+
15
+ test %{selection basics.
16
+ People often remark that this kind of thing is jQuery-like.
17
+ I keep thinking I got it from Eric Evans.} do
18
+ assert{ @arr.select(:numbers) == [1,2,4,6] }
19
+ assert{ @arr.select(:strings) == ["c","e"] }
20
+ assert{ @arr.select(:numbers).select(:less_than_3) == [1,2] }
21
+
22
+ assert do
23
+ catch_raise{ @arr.select(:less_than_3) }.is_a?(ArgumentError)
24
+ #because strings don't respond to <
25
+ #...there's no substitute for knowing what you're doing.
26
+ end
27
+
28
+ #normal select still works
29
+ assert{ @arr.select{|item|item.is_a?(String)} == ["c","e"] }
30
+ end
31
+
32
+ test "...selector name can be any object" do
33
+ arr = [1,2,"c",4,"e",6]
34
+
35
+ Predicated::Selectable.bless_enumerable(arr,
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
+ Predicated::Selectable.bless_enumerable(arr, :strings => proc{|item|item.is_a?(String)})
54
+ Predicated::Selectable.bless_enumerable(arr, :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 a macro" do
61
+ class MyArray < Array
62
+ include Predicated::Selectable
63
+ selector :strings => proc{|item|item.is_a?(String)}
64
+ selector :numbers => proc{|item|item.is_a?(Numeric)}
65
+ selector :small => proc{|item|item.is_a?(Numeric) && item < 3},
66
+ :big => proc{|item|item.is_a?(Numeric) && item >= 3}
67
+ end
68
+
69
+ arr = MyArray.new
70
+ arr.replace([1,2,"c",4,"e",6])
71
+
72
+ assert{ arr.select(:strings) == ["c","e"] }
73
+ assert{ arr.select(:numbers) == [1,2,4,6] }
74
+ assert{ arr.select(:small) == [1,2] }
75
+ assert{ arr.select(:big) == [4,6] }
76
+ end
77
+
78
+ test %{memoizes.
79
+ Selector enumerable assumes an immutable collection.
80
+ I'm going to use that assumption against it, and cleverly prove that memoization works.
81
+ (Others might choose to mock in similar circumstances.)} do
82
+ assert{ @arr.select(:strings) == ["c","e"] }
83
+
84
+ @arr << "zzz"
85
+
86
+ assert{ @arr.select(:strings) == ["c","e"] }
87
+ end
88
+ end
89
+
90
+ include Predicated
91
+ regarding "there are convenient selectors defined for getting things out of a predicate" do
92
+ class ::Array
93
+ def predicates
94
+ collect{|p, a|p}
95
+ end
96
+ end
97
+
98
+ it "gets predicate parts by type" do
99
+ root = Predicate { And(Eq(1, 2), Or(Eq(3, 4), Eq(5, 6))) }
100
+ the_or = Predicate { Or(Eq(3, 4), Eq(5, 6)) }
101
+
102
+ assert{ root.select(:all).predicates == [root, Equal.new(1, 2), the_or, Equal.new(3, 4), Equal.new(5, 6)] }
103
+
104
+ assert{ root.select(And).predicates == [root] }
105
+ assert{ root.select(Or).predicates == [the_or] }
106
+ assert{ root.select(Equal).predicates == [Equal.new(1, 2), Equal.new(3, 4), Equal.new(5, 6)] }
107
+ assert{ root.select(GreaterThan).predicates == [] }
108
+
109
+ gt_lt = Predicate { And(Gt(1, 2), Lt(3, 4)) }
110
+ assert{ gt_lt.select(GreaterThan).predicates == [GreaterThan.new(1, 2)] }
111
+ assert{ gt_lt.select(LessThan).predicates == [LessThan.new(3, 4)] }
112
+
113
+ gte_lte = Predicate { And(Gte(1, 2), Lte(3, 4)) }
114
+ assert{ gte_lte.select(GreaterThanOrEqualTo).predicates == [GreaterThanOrEqualTo.new(1, 2)] }
115
+ assert{ gte_lte.select(LessThanOrEqualTo).predicates == [LessThanOrEqualTo.new(3, 4)] }
116
+
117
+ mixed = Predicate { And(Eq(1, 2), Or(Gt(3, 4), Lt(5, 6))) }
118
+ mixed_or = Predicate { Or(Gt(3, 4), Lt(5, 6)) }
119
+ assert{ mixed.select(Operation).predicates == [Equal.new(1, 2), GreaterThan.new(3, 4), LessThan.new(5, 6)] }
120
+ assert{ mixed.select(Operation).select(Equal).predicates == [Equal.new(1, 2)] }
121
+ assert{ mixed.select(Binary).predicates == [mixed, Equal.new(1, 2), mixed_or, GreaterThan.new(3, 4), LessThan.new(5, 6)] }
122
+ end
123
+ end
@@ -0,0 +1,39 @@
1
+ require "./test/test_helper_with_wrong"
2
+
3
+ require "predicated/simple_templated_predicate"
4
+ include Predicated
5
+
6
+ regarding "simple templated predicates. the left sides of operations and calls is a common unbound variable" do
7
+
8
+ test "operations. the left side is a placeholder" do
9
+ assert{ SimpleTemplatedPredicate{ Eq(1) }.fill_in(1) == Predicate { Eq(1, 1) } }
10
+ assert{ SimpleTemplatedPredicate{ Lt(2) }.fill_in(1) == Predicate { Lt(1, 2) } }
11
+ assert{ SimpleTemplatedPredicate{ Gt(1) }.fill_in(2) == Predicate { Gt(2, 1) } }
12
+ assert{ SimpleTemplatedPredicate{ Gte(1) }.fill_in(2) == Predicate { Gte(2, 1) } }
13
+ assert{ SimpleTemplatedPredicate{ Lte(2) }.fill_in(1) == Predicate { Lte(1, 2) } }
14
+
15
+ assert{ SimpleTemplatedPredicate{ Eq(true) }.fill_in(true) == Predicate { Eq(true, true) } }
16
+ end
17
+
18
+ test "and, or, not. just pass on the fill_in" do
19
+ assert{ SimpleTemplatedPredicate{ And(Gt(3),Lt(5)) }.fill_in(4) == Predicate { And(Gt(4,3),Lt(4,5)) } }
20
+ assert{ SimpleTemplatedPredicate{ Or(Gt(3),Lt(5)) }.fill_in(4) == Predicate { Or(Gt(4,3),Lt(4,5)) } }
21
+ assert{ SimpleTemplatedPredicate{ Not(Gt(5)) }.fill_in(4) == Predicate { Not(Gt(4,5)) } }
22
+ end
23
+
24
+ test "call. left side is a placeholder" do
25
+ assert{ SimpleTemplatedPredicate{ Call(:include?, "bc") }.fill_in("abc") ==
26
+ Predicate { Call("abc", :include?, "bc") } }
27
+
28
+ assert{ SimpleTemplatedPredicate{ Call(:nil?) }.fill_in("abc") ==
29
+ Predicate { Call("abc", :nil?) } }
30
+ end
31
+
32
+ test "to_s and inspect" do
33
+ assert{ SimpleTemplatedPredicate{ Eq(1) }.inspect == "Eq(1)" }
34
+ assert{ SimpleTemplatedPredicate{ Eq(1) }.to_s == "Eq(1)" }
35
+
36
+ assert{ SimpleTemplatedPredicate{ Call(:include?, "bc") }.inspect == "Call(include?('bc'))" }
37
+ assert{ SimpleTemplatedPredicate{ Call(:include?, "bc") }.to_s == "Call(include?('bc'))" }
38
+ end
39
+ end
@@ -0,0 +1,2 @@
1
+ require "./test/test_helper"
2
+ run_suite("test/**/*_test.rb")
@@ -0,0 +1,64 @@
1
+ dir = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift "#{dir}/../lib"
3
+ $LOAD_PATH.unshift "../wrong/lib"
4
+ require "rubygems"
5
+ require "minitest/spec"
6
+ require "pp"
7
+
8
+ #DO NOT REQUIRE WRONG IN HERE
9
+ #The circularity between projects will cause certain tests to not work.
10
+
11
+ class Color
12
+ attr_reader :name
13
+ def initialize(name)
14
+ @name = name
15
+ end
16
+
17
+ def ==(other)
18
+ other.is_a?(Color) && @name == other.name
19
+ end
20
+
21
+ def to_s
22
+ "name:#{@name}"
23
+ end
24
+ end
25
+
26
+ def run_suite(wildcard)
27
+ #simple way to make sure requires are isolated
28
+ result = Dir[wildcard].collect{|test_file| system("ruby #{test_file}") }.uniq == [true]
29
+ puts "suite " + (result ? "passed" : "FAILED")
30
+ exit(result ? 0 : 1)
31
+ end
32
+
33
+ class MiniTest::Unit::TestCase
34
+
35
+ def assert_raise(exception_info_regex)
36
+ begin
37
+ yield
38
+ rescue Exception => e
39
+ assert{ exception_info_regex =~ "#{e.class.name} #{e.message}" }
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ module Kernel
46
+ alias_method :regarding, :describe
47
+
48
+ def xregarding(str)
49
+ puts "x'd out 'regarding \"#{str}\"'"
50
+ end
51
+ end
52
+
53
+ class MiniTest::Spec
54
+ class << self
55
+ alias_method :test, :it
56
+
57
+ def xtest(str)
58
+ puts "x'd out 'test \"#{str}\"'"
59
+ end
60
+
61
+ end
62
+ end
63
+
64
+ MiniTest::Unit.autorun
@@ -0,0 +1,6 @@
1
+ require "./test/test_helper"
2
+
3
+ require "wrong"
4
+ require "wrong/adapters/minitest"
5
+ require "wrong/message/test_context"
6
+ require "wrong/message/string_diff"
@@ -0,0 +1,85 @@
1
+ require "./test/test_helper_with_wrong"
2
+ require "./test/canonical_transform_cases"
3
+
4
+ unless RUBY_VERSION=="1.8.6"
5
+
6
+ require "predicated/to/arel"
7
+ include Predicated
8
+
9
+ regarding "convert a predicate to an arel where clause" do
10
+ include CanonicalTransformCases
11
+
12
+ class FakeEngine
13
+ def connection
14
+ end
15
+
16
+ def table_exists?(name)
17
+ true
18
+ end
19
+ end
20
+
21
+ class FakeColumn
22
+ attr_reader :name, :type
23
+ def initialize(name, type)
24
+ @name = name
25
+ @type = type
26
+ end
27
+
28
+ def type_cast(value)
29
+ value
30
+ end
31
+ end
32
+
33
+ @table = Arel::Table.new(:widget, :engine => FakeEngine.new)
34
+ Arel::Table.tables = [@table]
35
+ @table.instance_variable_set("@columns".to_sym, [
36
+ FakeColumn.new("a", :integer),
37
+ FakeColumn.new("b", :integer),
38
+ FakeColumn.new("c", :integer)
39
+ ])
40
+
41
+
42
+ @to_expectations = {
43
+ "simple operations" => {
44
+ "eq" => Arel::Predicates::Equality.new(@table.attributes["a"], 3),
45
+ "gt" => Arel::Predicates::GreaterThan.new(@table.attributes["a"], 3),
46
+ "lt" => Arel::Predicates::LessThan.new(@table.attributes["a"], 3),
47
+ "gte" => Arel::Predicates::GreaterThanOrEqualTo.new(@table.attributes["a"], 3),
48
+ "lte" => Arel::Predicates::LessThanOrEqualTo.new(@table.attributes["a"], 3)
49
+ },
50
+ "primitive types" => {
51
+ "false" => Arel::Predicates::Equality.new(@table.attributes["a"], false),
52
+ "true" => Arel::Predicates::Equality.new(@table.attributes["a"], true),
53
+ "string" => Arel::Predicates::Equality.new(@table.attributes["a"], "yyy")
54
+ },
55
+ "not" => {
56
+ "simple" => Arel::Predicates::Not.new(Arel::Predicates::Equality.new(@table.attributes["a"], true))
57
+ },
58
+ "simple and / or" => {
59
+ "and" => Arel::Predicates::And.new(
60
+ Arel::Predicates::Equality.new(@table.attributes["a"], 1),
61
+ Arel::Predicates::Equality.new(@table.attributes["b"], 2)
62
+ ),
63
+ "or" => Arel::Predicates::Or.new(
64
+ Arel::Predicates::Equality.new(@table.attributes["a"], 1),
65
+ Arel::Predicates::Equality.new(@table.attributes["b"], 2)
66
+ )
67
+ },
68
+ "complex and / or" => {
69
+ "or and" => Arel::Predicates::Or.new(
70
+ Arel::Predicates::And.new(
71
+ Arel::Predicates::Equality.new(@table.attributes["a"], 1),
72
+ Arel::Predicates::Equality.new(@table.attributes["b"], 2)
73
+ ),
74
+ Arel::Predicates::Equality.new(@table.attributes["c"], 3)
75
+ )
76
+ }
77
+ }
78
+
79
+ create_canonical_tests(@to_expectations) do |predicate|
80
+ predicate.to_arel(@table)
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,74 @@
1
+ require "./test/test_helper_with_wrong"
2
+ require "./test/canonical_transform_cases"
3
+
4
+ require "predicated/to/json"
5
+ include Predicated
6
+
7
+ regarding "convert a predicate to a json structure" do
8
+ include CanonicalTransformCases
9
+
10
+ @to_expectations = {
11
+ "simple operations" => {
12
+ "eq" => ["a", "==", 3],
13
+ "gt" => ["a", ">", 3],
14
+ "lt" => ["a", "<", 3],
15
+ "gte" => ["a", ">=", 3],
16
+ "lte" => ["a", "<=", 3]
17
+ },
18
+ "primitive types" => {
19
+ "false" => ["a", "==", false],
20
+ "true" => ["a", "==", true],
21
+ "string" => ["a", "==", "yyy"]
22
+ },
23
+ "not" => {
24
+ "simple" => {"not" => ["a", "==", true]}
25
+ },
26
+ "simple and / or" => {
27
+ "and" => {"and" => [["a", "==", 1], ["b", "==", 2]] },
28
+ "or" => {"or" => [["a", "==", 1], ["b", "==", 2]] }
29
+ },
30
+ "complex and / or" => {
31
+ "or and" => {"or" => [
32
+ {"and" => [["a", "==", 1], ["b", "==", 2]]},
33
+ ["c", "==", 3]
34
+ ]}
35
+ }
36
+ }
37
+
38
+ create_canonical_tests(@to_expectations) do |predicate|
39
+ predicate.to_json_struct
40
+ end
41
+ end
42
+
43
+ regarding "convert a predicate to a json string" do
44
+ include CanonicalTransformCases
45
+
46
+ @to_expectations = {
47
+ "simple operations" => {
48
+ "eq" => %{["a","==",3]},
49
+ "gt" => %{["a",">",3]},
50
+ "lt" => %{["a","<",3]},
51
+ "gte" => %{["a",">=",3]},
52
+ "lte" => %{["a","<=",3]}
53
+ },
54
+ "primitive types" => {
55
+ "false" => %{["a","==",false]},
56
+ "true" => %{["a","==",true]},
57
+ "string" => %{["a","==","yyy"]}
58
+ },
59
+ "not" => {
60
+ "simple" => %{{"not":["a","==",true]}}
61
+ },
62
+ "simple and / or" => {
63
+ "and" => %{{"and":[["a","==",1],["b","==",2]]}},
64
+ "or" => %{{"or":[["a","==",1],["b","==",2]]}}
65
+ },
66
+ "complex and / or" => {
67
+ "or and" => %{{"or":[{"and":[["a","==",1],["b","==",2]]},["c","==",3]]}}
68
+ }
69
+ }
70
+
71
+ create_canonical_tests(@to_expectations) do |predicate|
72
+ predicate.to_json_str.gsub("\n", "").gsub(" ", "")
73
+ end
74
+ end
@@ -0,0 +1,90 @@
1
+ require "./test/test_helper_with_wrong"
2
+
3
+ require "predicated/to/sentence"
4
+ include Predicated
5
+
6
+ regarding "convert a predicate to an english sentence" do
7
+
8
+ after do
9
+ Operation.reset_verb_phrases
10
+ end
11
+
12
+ test "operations" do
13
+ assert { Predicate{ Eq("a",1) }.to_sentence == '"a" is equal to 1' }
14
+ assert { Predicate{ Gt("a",1) }.to_sentence == '"a" is greater than 1' }
15
+ assert { Predicate{ Lt("a",1) }.to_sentence == '"a" is less than 1' }
16
+ assert { Predicate{ Gte("a",1) }.to_sentence == '"a" is greater than or equal to 1' }
17
+ assert { Predicate{ Lte("a",1) }.to_sentence == '"a" is less than or equal to 1' }
18
+
19
+ assert { Predicate{ Eq("a",1) }.to_negative_sentence == '"a" is not equal to 1' }
20
+ assert { Predicate{ Gt("a",1) }.to_negative_sentence == '"a" is not greater than 1' }
21
+ assert { Predicate{ Lt("a",1) }.to_negative_sentence == '"a" is not less than 1' }
22
+ assert { Predicate{ Gte("a",1) }.to_negative_sentence == '"a" is not greater than or equal to 1' }
23
+ assert { Predicate{ Lte("a",1) } .to_negative_sentence == '"a" is not less than or equal to 1' }
24
+ end
25
+
26
+ test "primitive types" do
27
+ assert { Predicate{ Eq("a",1) }.to_sentence == '"a" is equal to 1' }
28
+ assert { Predicate{ Eq("a",nil) }.to_sentence == '"a" is equal to nil' }
29
+ assert { Predicate{ Eq("a",true) }.to_sentence == '"a" is equal to true' }
30
+ assert { Predicate{ Eq("a",3.14) }.to_sentence == '"a" is equal to 3.14' }
31
+ end
32
+
33
+ test "not" do
34
+ assert { Predicate{ Not(Eq("a",1)) }.to_sentence == '"a" is not equal to 1' }
35
+ assert { Predicate{ Not(Eq("a",1)) }.to_negative_sentence == '"a" is equal to 1' }
36
+ end
37
+
38
+ test "complex types" do
39
+ assert { Predicate{ Eq([1,2],{3=>4}) }.to_sentence == "[1, 2] is equal to {3=>4}" }
40
+ end
41
+
42
+ test "default verb phrases for unknown methods (which are awkward/ESL-ish)" do
43
+ assert { Predicate{ Call("abc", :exclude?, "bc") }.to_sentence ==
44
+ '"abc" is exclude "bc"' }
45
+
46
+ assert { Predicate{ Call("abc", :exclude?, "bc") }.to_negative_sentence ==
47
+ '"abc" is not exclude "bc"' }
48
+
49
+ assert { Predicate{ Call("abc", :friends_with?, "bc") }.to_sentence ==
50
+ '"abc" is friends with "bc"' }
51
+ end
52
+
53
+ test "register methods and their verb phrases" do
54
+ Operation.register_verb_phrase(:exclude?, "excludes", "does not exclude")
55
+ assert { Predicate{ Call("abc", :exclude?, "bc") }.to_sentence ==
56
+ '"abc" excludes "bc"' }
57
+
58
+ assert { Predicate{ Call("abc", :exclude?, "bc") }.to_negative_sentence ==
59
+ '"abc" does not exclude "bc"' }
60
+ end
61
+
62
+ test "some other common methods have sensible verb phrases by default" do
63
+ assert { Predicate{ Call("abc", :include?, 'bc') }.to_sentence == '"abc" includes "bc"' }
64
+ assert { Predicate{ Call("abc", :include?, 'bc') }.to_negative_sentence == '"abc" does not include "bc"' }
65
+
66
+ s = Predicate{ Call("abc", :is_a?, String) }.to_sentence
67
+ assert { s == '"abc" is a String' }
68
+ assert { Predicate{ Call("abc", :is_a?, String) }.to_negative_sentence == '"abc" is not a String' }
69
+ end
70
+
71
+ test "nothing on the far side" do
72
+ assert { Predicate{ Call("abc", :nil?) }.to_sentence == '"abc" is nil' }
73
+ assert { Predicate{ Call("abc", :nil?) }.to_negative_sentence == '"abc" is not nil' }
74
+ end
75
+
76
+ test "simple and + or" do
77
+ assert { Predicate{ And(Eq("a", 1),Eq("b", 2)) }.to_sentence ==
78
+ '"a" is equal to 1 and "b" is equal to 2' }
79
+
80
+ assert { Predicate{ Or(Eq("a", 1),Eq("b", 2)) }.to_sentence ==
81
+ '"a" is equal to 1 or "b" is equal to 2' }
82
+
83
+ assert { Predicate{ And(Eq("a", 1),Eq("b", 2)) }.to_negative_sentence ==
84
+ 'This is not true: "a" is equal to 1 and "b" is equal to 2' }
85
+
86
+ assert { Predicate{ Or(Eq("a", 1),Eq("b", 2)) }.to_negative_sentence ==
87
+ 'This is not true: "a" is equal to 1 or "b" is equal to 2' }
88
+ end
89
+
90
+ end