wrong 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +114 -25
- data/lib/predicated/Gemfile +15 -0
- data/lib/predicated/LICENSE +20 -0
- data/lib/predicated/README.markdown +191 -0
- data/lib/predicated/Rakefile +51 -0
- data/lib/predicated/lib/predicated.rb +4 -0
- data/lib/predicated/lib/predicated/autogen_call.rb +37 -0
- data/lib/predicated/lib/predicated/constrain.rb +66 -0
- data/lib/predicated/lib/predicated/evaluate.rb +94 -0
- data/lib/predicated/lib/predicated/from/callable_object.rb +108 -0
- data/lib/predicated/lib/predicated/from/json.rb +59 -0
- data/lib/predicated/lib/predicated/from/ruby_code_string.rb +73 -0
- data/lib/predicated/lib/predicated/from/url_part.rb +104 -0
- data/lib/predicated/lib/predicated/from/xml.rb +61 -0
- data/lib/predicated/lib/predicated/gem_check.rb +34 -0
- data/lib/predicated/lib/predicated/predicate.rb +111 -0
- data/lib/predicated/lib/predicated/print.rb +62 -0
- data/lib/predicated/lib/predicated/selectable.rb +102 -0
- data/lib/predicated/lib/predicated/simple_templated_predicate.rb +79 -0
- data/lib/predicated/lib/predicated/string_utils.rb +20 -0
- data/lib/predicated/lib/predicated/to/arel.rb +41 -0
- data/lib/predicated/lib/predicated/to/json.rb +48 -0
- data/lib/predicated/lib/predicated/to/sentence.rb +94 -0
- data/lib/predicated/lib/predicated/to/solr.rb +15 -0
- data/lib/predicated/lib/predicated/to/xml.rb +67 -0
- data/lib/predicated/lib/predicated/version.rb +3 -0
- data/lib/predicated/predicated.gemspec +22 -0
- data/lib/predicated/test/autogen_call_test.rb +40 -0
- data/lib/predicated/test/canonical_transform_cases.rb +63 -0
- data/lib/predicated/test/constrain_test.rb +86 -0
- data/lib/predicated/test/enumerable_test.rb +32 -0
- data/lib/predicated/test/equality_test.rb +32 -0
- data/lib/predicated/test/evaluate_test.rb +149 -0
- data/lib/predicated/test/from/callable_object_canonical_test.rb +43 -0
- data/lib/predicated/test/from/callable_object_test.rb +78 -0
- data/lib/predicated/test/from/json_test.rb +83 -0
- data/lib/predicated/test/from/ruby_code_string_canonical_test.rb +37 -0
- data/lib/predicated/test/from/ruby_code_string_test.rb +103 -0
- data/lib/predicated/test/from/url_part_parser_test.rb +123 -0
- data/lib/predicated/test/from/url_part_test.rb +48 -0
- data/lib/predicated/test/from/xml_test.rb +57 -0
- data/lib/predicated/test/json_conversion_test.rb +33 -0
- data/lib/predicated/test/print_test.rb +66 -0
- data/lib/predicated/test/selectable_test.rb +123 -0
- data/lib/predicated/test/simple_templated_predicate_test.rb +39 -0
- data/lib/predicated/test/suite.rb +2 -0
- data/lib/predicated/test/test_helper.rb +64 -0
- data/lib/predicated/test/test_helper_with_wrong.rb +6 -0
- data/lib/predicated/test/to/arel_test.rb +85 -0
- data/lib/predicated/test/to/json_test.rb +74 -0
- data/lib/predicated/test/to/sentence_test.rb +90 -0
- data/lib/predicated/test/to/solr_test.rb +39 -0
- data/lib/predicated/test/to/xml_test.rb +72 -0
- data/lib/predicated/test/xml_conversion_test.rb +34 -0
- data/lib/predicated/test_integration/arel_integration_test.rb +52 -0
- data/lib/predicated/test_integration/canonical_integration_cases.rb +66 -0
- data/lib/predicated/test_integration/schema.xml +83 -0
- data/lib/predicated/test_integration/solr_integration_test.rb +71 -0
- data/lib/predicated/test_integration/sqlite_db +0 -0
- data/lib/predicated/test_integration/suite.rb +2 -0
- data/lib/predicated/test_integration/usage_test.rb +252 -0
- data/lib/wrong.rb +3 -1
- data/lib/wrong/adapters/test_unit.rb +1 -3
- data/lib/wrong/assert.rb +81 -24
- data/lib/wrong/chunk.rb +145 -0
- data/lib/wrong/message/string_diff.rb +2 -4
- data/lib/wrong/message/test_context.rb +2 -2
- data/lib/wrong/version.rb +2 -2
- data/test/adapters/minitest_test.rb +16 -9
- data/test/adapters/test_unit_test.rb +1 -1
- data/test/assert_test.rb +90 -0
- data/test/catch_raise_test.rb +2 -2
- data/test/chunk_test.rb +236 -0
- data/test/failures_test.rb +109 -74
- data/test/message/array_diff_test.rb +35 -19
- data/test/message/string_diff_test.rb +39 -15
- data/test/message/test_context_text.rb +2 -2
- data/test/test_helper.rb +25 -7
- metadata +86 -33
- data/test/basic_assert_test.rb +0 -38
data/README.markdown
CHANGED
@@ -1,56 +1,145 @@
|
|
1
|
+
"Feels so right, it can't be Wrong"
|
2
|
+
|
1
3
|
## Abstract ##
|
2
4
|
|
3
|
-
Wrong provides a general assert method that takes a predicate block.
|
5
|
+
Wrong provides a general assert method that takes a predicate block. Assertion failure
|
6
|
+
messages are rich in detail. The Wrong idea is to replace all those countless assert_this,
|
7
|
+
assert_that library methods which only exist to give a more useful failure message than
|
8
|
+
"assertion failed". Wrong replaces all of them in one fell swoop, since if you can write it
|
9
|
+
in Ruby, Wrong can make a sensible failure message out of it.
|
4
10
|
|
5
|
-
Wrong is alpha-quality
|
11
|
+
Wrong is alpha-quality. We'd very much appreciate feedback and bug reports. There are plenty of things left to be done
|
12
|
+
to make the results look uniformly clean and beautiful. We want your feedback, and especially to give us cases where
|
13
|
+
either it blows up or the output is ugly or uninformative.
|
6
14
|
|
7
|
-
It
|
8
|
-
[http://github.com/sconover/predicated](http://github.com/sconover/predicated)
|
15
|
+
It relies on [Predicated](http://github.com/sconover/predicated) for its main failure message.
|
9
16
|
|
10
|
-
Inspired by assert { 2.0 }
|
11
|
-
[http://assert2.rubyforge.org/](http://assert2.rubyforge.org/)
|
17
|
+
Inspired by [assert { 2.0 }](http://assert2.rubyforge.org/) but rewritten from scratch to be compatible with Ruby 1.8 and 1.9.
|
12
18
|
|
13
19
|
## Usage ##
|
14
20
|
|
15
|
-
Wrong provides a simple assert method:
|
21
|
+
Wrong provides a simple assert method that takes a block:
|
16
22
|
|
17
23
|
require "wrong"
|
18
24
|
|
19
25
|
include Wrong::Assert
|
20
26
|
|
21
|
-
assert{1==1}
|
27
|
+
assert {1==1}
|
22
28
|
==> nil
|
23
29
|
|
24
|
-
assert{2==1}
|
25
|
-
==> Wrong::Assert::AssertionFailedError: 2 is not equal to 1
|
26
|
-
|
30
|
+
assert {2==1}
|
31
|
+
==> Wrong::Assert::AssertionFailedError: Expected (2 == 1), but 2 is not equal to 1
|
32
|
+
|
33
|
+
If your assertion is more than a simple predicate, then Wrong will split it into parts and show you the values of all the relevant subexpressions.
|
34
|
+
|
35
|
+
x = 7; y = 10; assert { x == 7 && y == 11 }
|
36
|
+
==>
|
37
|
+
Wrong::Assert::AssertionFailedError: Expected ((x == 7) and (y == 11)), but
|
38
|
+
(x == 7) is true
|
39
|
+
x is 7
|
40
|
+
(y == 11) is false
|
41
|
+
y is 10
|
42
|
+
|
27
43
|
And a companion, 'deny':
|
28
44
|
|
29
45
|
deny{'abc'.include?('bc')}
|
30
|
-
==> Wrong::Assert::AssertionFailedError: 'abc' includes 'bc'
|
46
|
+
==> Wrong::Assert::AssertionFailedError: Didn't expect "abc".include?("bc"), but 'abc' includes 'bc'
|
31
47
|
|
32
|
-
There's a convenience method for catching errors:
|
48
|
+
There's also a convenience method for catching errors:
|
33
49
|
|
34
|
-
|
35
|
-
==>
|
50
|
+
assert{ catch_raise{raise "vanilla"}.message == "chocolate" }
|
51
|
+
==>
|
52
|
+
Wrong::Assert::AssertionFailedError: Expected (catch_raise { raise("vanilla") }.message == "chocolate"), but 'vanilla' is not equal to 'chocolate'
|
53
|
+
|
54
|
+
## Apology ##
|
55
|
+
|
56
|
+
So does the world need another assertion framework? In fact, it does not! We actually believe the world needs **fewer** assert methods.
|
57
|
+
|
58
|
+
The Wrong idea is to replace all those countless assert\_this, assert\_that library methods which only exist to give a more useful failure message than "assertion failed". Wrong replaces all of them in one fell swoop, since if you can write it in Ruby, Wrong can make a sensible failure message out of it.
|
59
|
+
|
60
|
+
Even the lowly workhorse `assert_equal` is bloated compared to Wrong: would you rather write this
|
61
|
+
|
62
|
+
assert_equal time, money
|
63
|
+
|
64
|
+
or this
|
65
|
+
|
66
|
+
assert { time == money }
|
67
|
+
|
68
|
+
? The Wrong version has the advantage of being plain, transparent Ruby code, not an awkward DSL that moves "equal" out of its natural place between the comparands. Plus, WYSIWYG! You know just from looking at it that "equal" means `==`, not `eql?` or `===` or `=~`.
|
69
|
+
|
70
|
+
Moreover, much like TDD itself, Wrong encourages you to write cleaner code. If your assertion messages are not clear and "Englishy", then maybe it's time for you to refactor a bit -- extract an informatively named variable or method, maybe push some function onto its natural object *a la* the [Law of Demeter](http://en.wikipedia.org/wiki/Law_of_Demeter)...
|
71
|
+
|
72
|
+
Wrong also lets you put the expected and actual values in any order you want! Consider the failure messages for
|
73
|
+
|
74
|
+
assert { current_user == "joe" } # => Expected (current_user == "joe") but current_user is "fred"
|
75
|
+
assert { "joe" == current_user } # => Expected ("joe" == current_user) but current_user is "fred"
|
76
|
+
|
77
|
+
You get just the information you want, and none you don't want. At least, that's the plan! :-)
|
78
|
+
|
79
|
+
## Algorithm ##
|
80
|
+
|
81
|
+
So wait a second. How do we do it? Doesn't Ruby have [poor support for AST introspection](http://blog.zenspider.com/2009/04/parsetree-eol.html)? Well, yes, it does, so we cheat: we figure out what file and line the assert block is defined in, then open the file, read the code, and parse it directly using Ryan Davis' amazing [RubyParser](http://parsetree.rubyforge.org/ruby_parser/) and [Ruby2Ruby](http://seattlerb.rubyforge.org/ruby2ruby/). You can bask in the kludge by examining `chunk.rb` and `assert.rb`. If you find some code it can't parse, please send it our way.
|
82
|
+
|
83
|
+
Before you get your knickers in a twist about how this is totally unacceptable because it doesn't support this or that use case, here are our caveats and excuses:
|
84
|
+
|
85
|
+
* It works! Tested in 1.8.6, 1.8.7, 1.9.1, and 1.9.2-rc2. (Thank you, [rvm](http://rvm.beginrescueend.com/)!)
|
86
|
+
* Your code needs to be in a file. That means it doesn't work in IRB. (If you're developing Ruby code without saving it to a mounted disk, then sorry, Wrong is not right for you.)
|
87
|
+
* It's a development-time testing library, not a production runtime library, so there are no security or filesystem issues.
|
88
|
+
* `eval` isn't evil, it's just misunderstood.
|
89
|
+
* It makes a few assumptions about the structure of your code, leading to some restrictions:
|
90
|
+
* You can't have more than one call to `assert` per line. (This should not be a problem since even if you're nesting asserts for some bizarre reason, we assume you know where your Return key is. And actually, technically you can put two asserts on a line, but it always describes the first one it sees, which means that if the second one executes, its failure message will be incorrect or broken.)
|
91
|
+
* You can't use metaprogramming to write your assert blocks.
|
92
|
+
* All variables and methods must be available in the binding of the assertion block.
|
36
93
|
|
37
94
|
## Adapters ##
|
38
95
|
|
39
96
|
Adapters for various test frameworks sit under wrong/adapters.
|
40
|
-
TODO
|
41
97
|
|
42
|
-
|
98
|
+
Currently we support
|
99
|
+
|
100
|
+
* Test::Unit
|
101
|
+
* Minitest
|
102
|
+
|
103
|
+
Coming soon
|
104
|
+
|
105
|
+
* RSpec
|
106
|
+
* ???
|
107
|
+
|
108
|
+
## Explanations ##
|
109
|
+
|
110
|
+
`assert` and `deny` can take an optional explanation, e.g.
|
111
|
+
|
112
|
+
assert("since we're on Earth") { sky.blue? }
|
113
|
+
|
114
|
+
Since the point of Wrong is to make asserts self-explanatory, you should feel free to use explanations only when they would add something that you couldn't get from reading the (failed) assertion code itself. Don't bother doing things like this:
|
115
|
+
|
116
|
+
assert("the sky should be blue") { sky.blue? } # redundant
|
117
|
+
|
118
|
+
The failure message of the above would be something like "Expected sky.blue? but sky is :green" which is not made clearer by the addition of "the sky should be blue". We already know it should be blue since we see right there that we're expecting it to be blue.
|
119
|
+
|
120
|
+
And if your assertion code isn't self-explanatory, then that's a hint that you might need to do some refactoring until it is. (Yes, even test code should be clean as a whistle. **Especially** test code.)
|
121
|
+
|
122
|
+
## Special Formatting ##
|
43
123
|
|
44
124
|
Enhancements for error messages sit under wrong/message.
|
45
|
-
TODO
|
46
125
|
|
47
|
-
|
126
|
+
Currently we support special messages for
|
127
|
+
|
128
|
+
* String ==
|
129
|
+
* Enumerable ==
|
130
|
+
* including nested string elements
|
131
|
+
|
132
|
+
## Helper Assert Methods ##
|
48
133
|
|
49
|
-
|
50
|
-
[http://www.pivotaltracker.com/projects/95014](http://www.pivotaltracker.com/projects/95014)
|
134
|
+
If you really want to, you can define your procs in one method, pass it in to another method, and have that method assert it. This is very bizarre and you probably shouldn't do it. Wrong will do its best to figure out where the actual assertion code is but it might not succeed.
|
51
135
|
|
52
|
-
|
136
|
+
If you're in Ruby 1.8, you **really** shouldn't do it! But if you do, you can use the "depth" parameter to give Wrong a better hint about how far up the stack it should crawl to find the code. See `assert_test.rb` for more details, if you dare.
|
137
|
+
|
138
|
+
## Authors ##
|
139
|
+
|
140
|
+
* Steve Conover - <sconover@gmail.com>
|
141
|
+
* Alex Chaffee - <alex@stinky.com> - <http://alexch.github.com>
|
142
|
+
|
143
|
+
## Etc ##
|
53
144
|
|
54
|
-
|
55
|
-
I'm right where I belong"
|
56
|
-
-Fixing a Hole
|
145
|
+
Tracker project: <http://www.pivotaltracker.com/projects/109993>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
source :gemcutter
|
2
|
+
gem "ruby_parser"
|
3
|
+
gem "ruby2ruby"
|
4
|
+
gem "ParseTree"
|
5
|
+
gem "diff"
|
6
|
+
gem "diff-lcs"
|
7
|
+
gem "minitest"
|
8
|
+
gem "nokogiri"
|
9
|
+
gem "arel", "~>0.4"
|
10
|
+
gem "sqlite3-ruby"
|
11
|
+
gem "activerecord", "~>3.0.0.beta"
|
12
|
+
gem "i18n"
|
13
|
+
gem "json", "1.1.9"
|
14
|
+
gem "treetop", "~>1.4.8"
|
15
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Steve Conover
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,191 @@
|
|
1
|
+
## Abstract ##
|
2
|
+
|
3
|
+
Predicated is a simple predicate model for Ruby. It provides useful predicate transformations and operations.
|
4
|
+
|
5
|
+
Tracker project:
|
6
|
+
[http://www.pivotaltracker.com/projects/95014](http://www.pivotaltracker.com/projects/95014)
|
7
|
+
|
8
|
+
## Transformations ##
|
9
|
+
|
10
|
+
- From:
|
11
|
+
- json
|
12
|
+
- xml
|
13
|
+
- url part, ex: "!(a=1&b=2|c=3)"
|
14
|
+
- callable objects (lambdas/procs, and therefore blocks) - ruby 1.8.x only
|
15
|
+
- ruby code - ruby 1.8.x only
|
16
|
+
- To:
|
17
|
+
- json
|
18
|
+
- xml
|
19
|
+
- sql where clause via [arel](http://github.com/rails/arel)
|
20
|
+
- [solr](http://lucene.apache.org/solr/) query string
|
21
|
+
- english sentence, ex: "'a' is not equal to 'b'"
|
22
|
+
|
23
|
+
## Usage ##
|
24
|
+
|
25
|
+
Note: The test suite acts as a comprehensive usage guide.
|
26
|
+
|
27
|
+
|
28
|
+
Evaluate a predicate:
|
29
|
+
|
30
|
+
require "predicated/evaluate"
|
31
|
+
include Predicated
|
32
|
+
|
33
|
+
Predicate { Eq(1, 2) }.evaluate == false
|
34
|
+
Predicate { Lt(1, 2) }.evaluate == true
|
35
|
+
Predicate { Or(Lt(1, 2),Eq(1, 2)) }.evaluate == true
|
36
|
+
|
37
|
+
x = 1
|
38
|
+
Predicate { Lt(x, 2) }.evaluate == true
|
39
|
+
|
40
|
+
|
41
|
+
Parse a predicate from part of a url and then turn it into a sql where clause:
|
42
|
+
|
43
|
+
require "predicated/from/url_part"
|
44
|
+
require "predicated/to/arel"
|
45
|
+
|
46
|
+
predicate = Predicated::Predicate.from_url_part("(color=red|color=green)&size=large")
|
47
|
+
|
48
|
+
predicate.inspect ==
|
49
|
+
"And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))"
|
50
|
+
|
51
|
+
predicate.to_arel(Table(:shirt)).to_sql ==
|
52
|
+
%{(("shirt"."color" = 'red' OR "shirt"."color" = 'green') AND "shirt"."size" = 'large')}
|
53
|
+
|
54
|
+
|
55
|
+
Parse a predicate from json and then turn it into a solr query string:
|
56
|
+
|
57
|
+
require "predicated/from/json"
|
58
|
+
require "predicated/to/solr"
|
59
|
+
|
60
|
+
predicate = Predicated::Predicate.from_json_str(%{
|
61
|
+
{"and":[{"or":[["color","==","red"],["color","==","green"]]},["size","==","large"]]}
|
62
|
+
})
|
63
|
+
|
64
|
+
predicate.inspect == "And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))"
|
65
|
+
|
66
|
+
predicate.to_solr == "((color:red OR color:green) AND size:large)"
|
67
|
+
|
68
|
+
|
69
|
+
From json:
|
70
|
+
|
71
|
+
require "predicated/from/json"
|
72
|
+
|
73
|
+
Predicated::Predicate.from_json_str(%{
|
74
|
+
{"and":[
|
75
|
+
{"or":[
|
76
|
+
["color","==","red"],
|
77
|
+
["color","==","green"]
|
78
|
+
]},
|
79
|
+
["size","==","large"]
|
80
|
+
]}
|
81
|
+
}).inspect == "And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))"
|
82
|
+
|
83
|
+
|
84
|
+
From xml:
|
85
|
+
|
86
|
+
require "predicated/from/xml"
|
87
|
+
|
88
|
+
Predicated::Predicate.from_xml(%{
|
89
|
+
<and>
|
90
|
+
<or>
|
91
|
+
<equal><left>color</left><right>red</right></equal>
|
92
|
+
<equal><left>color</left><right>green</right></equal>
|
93
|
+
</or>
|
94
|
+
<equal><left>size</left><right>large</right></equal>
|
95
|
+
</and>
|
96
|
+
}).inspect == "And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))"
|
97
|
+
|
98
|
+
|
99
|
+
From url part:
|
100
|
+
|
101
|
+
require "predicated/from/url_part"
|
102
|
+
|
103
|
+
Predicated::Predicate.from_url_part("(color=red|color=green)&size=large").inspect ==
|
104
|
+
"And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))"
|
105
|
+
|
106
|
+
|
107
|
+
From callable object:
|
108
|
+
|
109
|
+
require "predicated/from/callable_object"
|
110
|
+
|
111
|
+
Predicated::Predicate.from_callable_object{('color'=='red' || 'color'=='green') && 'size'=='large'}.inspect ==
|
112
|
+
"And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))"
|
113
|
+
|
114
|
+
|
115
|
+
From ruby code string:
|
116
|
+
|
117
|
+
require "predicated/from/ruby_code_string"
|
118
|
+
|
119
|
+
Predicated::Predicate.from_ruby_code_string("('color'=='red' || 'color'=='green') && 'size'=='large'").inspect ==
|
120
|
+
"And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))"
|
121
|
+
|
122
|
+
|
123
|
+
To json:
|
124
|
+
|
125
|
+
require "predicated/to/json"
|
126
|
+
include Predicated
|
127
|
+
|
128
|
+
Predicate{And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))}.to_json_str ==
|
129
|
+
%{
|
130
|
+
{"and":[
|
131
|
+
{"or":[
|
132
|
+
["color","==","red"],
|
133
|
+
["color","==","green"]
|
134
|
+
]},
|
135
|
+
["size","==","large"]
|
136
|
+
]}
|
137
|
+
}
|
138
|
+
|
139
|
+
|
140
|
+
To xml:
|
141
|
+
|
142
|
+
require "predicated/to/xml"
|
143
|
+
include Predicated
|
144
|
+
|
145
|
+
Predicate{And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))}.to_xml ==
|
146
|
+
%{
|
147
|
+
<and>
|
148
|
+
<or>
|
149
|
+
<equal><left>color</left><right>red</right></equal>
|
150
|
+
<equal><left>color</left><right>green</right></equal>
|
151
|
+
</or>
|
152
|
+
<equal><left>size</left><right>large</right></equal>
|
153
|
+
</and>
|
154
|
+
}
|
155
|
+
|
156
|
+
|
157
|
+
To arel (sql where clause):
|
158
|
+
|
159
|
+
require "predicated/to/arel"
|
160
|
+
include Predicated
|
161
|
+
|
162
|
+
Predicate{And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))}.to_arel(Table(:shirt)).to_sql ==
|
163
|
+
%{(("shirt"."color" = 'red' OR "shirt"."color" = 'green') AND "shirt"."size" = 'large')}
|
164
|
+
|
165
|
+
|
166
|
+
To solr query string:
|
167
|
+
|
168
|
+
require "predicated/to/solr"
|
169
|
+
include Predicated
|
170
|
+
|
171
|
+
Predicate{And(Or(Eq('color','red'),Eq('color','green')),Eq('size','large'))}.to_solr ==
|
172
|
+
"((color:red OR color:green) AND size:large)"
|
173
|
+
|
174
|
+
|
175
|
+
To sentence:
|
176
|
+
|
177
|
+
require "predicated/to/sentence"
|
178
|
+
include Predicated
|
179
|
+
|
180
|
+
Predicate{ And(Eq("a",1),Eq("b",2)) }.to_sentence ==
|
181
|
+
"'a' is equal to 1 and 'b' is equal to 2"
|
182
|
+
|
183
|
+
Predicate{ Gt("a",1) }.to_negative_sentence ==
|
184
|
+
"'a' is not greater than 1"
|
185
|
+
|
186
|
+
|
187
|
+
## Testing Notes ##
|
188
|
+
|
189
|
+
Right now this project makes use of Wrong for assertions. Wrong uses this project. It's kind of neat in an eat-your-own-dogfood sense, but it's possible that this will be problematic over time (particularly when changes in this project cause assertions to behave differently - if even temporarily).
|
190
|
+
|
191
|
+
A middle ground is to make "from ruby string" and "from callable object" use minitest asserts, since these are the "interesting" parts of Predicated relied on by Wrong.
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler"
|
3
|
+
Bundler.setup
|
4
|
+
|
5
|
+
def gemspec
|
6
|
+
@gemspec ||= begin
|
7
|
+
gemspec_file = File.expand_path('../predicated.gemspec', __FILE__)
|
8
|
+
gemspec = eval(File.read(gemspec_file), binding, gemspec_file)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default => :test
|
13
|
+
|
14
|
+
desc 'run all tests'
|
15
|
+
task :test do
|
16
|
+
sh %{ruby test/suite.rb}
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Build pkg/#{gemspec.full_name}.gem"
|
20
|
+
task :build => "gemspec:validate" do
|
21
|
+
sh %{gem build predicated.gemspec}
|
22
|
+
FileUtils.mkdir_p "pkg"
|
23
|
+
FileUtils.mv gemspec.file_name, "pkg"
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Install the latest built gem"
|
27
|
+
task :install => :build do
|
28
|
+
sh "gem install --local pkg/#{gemspec.file_name}"
|
29
|
+
end
|
30
|
+
|
31
|
+
namespace :release do
|
32
|
+
task :tag do
|
33
|
+
release_tag = "v#{gemspec.version}"
|
34
|
+
sh "git tag -a #{release_tag} -m 'Tagging #{release_tag}'"
|
35
|
+
sh "git push origin #{release_tag}"
|
36
|
+
end
|
37
|
+
|
38
|
+
task :gem => :build do
|
39
|
+
sh "gem push pkg/#{gemspec.file_name}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "Release the current branch to GitHub and Gemcutter"
|
44
|
+
task :release => %w(release:tag release:gem)
|
45
|
+
|
46
|
+
namespace :gemspec do
|
47
|
+
desc 'Validate the gemspec'
|
48
|
+
task :validate do
|
49
|
+
gemspec.validate
|
50
|
+
end
|
51
|
+
end
|