wrong 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.
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