picard 0.0.2 → 0.0.3
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.rdoc +15 -0
- data/lib/picard.rb +10 -2
- data/lib/picard/assertion_wrapper.rb +56 -0
- data/lib/picard/ast_helper.rb +37 -22
- data/lib/picard/class_ripper.rb +0 -4
- data/lib/picard/context.rb +3 -0
- data/lib/picard/error_message_formatter.rb +28 -0
- data/lib/picard/extensions.rb +10 -0
- data/lib/picard/method_ripper.rb +9 -16
- data/lib/picard/preprocessor.rb +3 -4
- data/lib/picard/s_expression_sugar.rb +7 -0
- data/lib/picard/test_unit.rb +10 -4
- data/lib/picard/version.rb +1 -1
- data/picard.gemspec +1 -2
- data/test/picard/assertion_wrapper_test.rb +40 -0
- data/test/picard/ast_helper_test.rb +83 -65
- data/test/picard/class_ripper_test.rb +22 -27
- data/test/picard/demo_test.rb +21 -0
- data/test/picard/error_message_formatter_test.rb +24 -0
- data/test/picard/method_ripper_test.rb +32 -15
- data/test/picard/preprocessor_test.rb +76 -61
- data/test/picard/test_unit_test.rb +25 -12
- data/test/test_helper.rb +6 -2
- metadata +21 -23
- data/lib/picard/expect_block.rb +0 -7
- data/test/picard/expect_block_test.rb +0 -20
data/README.rdoc
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
== Test Framework "Picard"
|
2
|
+
|
3
|
+
Picard is a test framework heavily inspired by "Spock" (an excellent test framework for the Groovy programming language). It does some AST manipulation to make the structure of your test explicit:
|
4
|
+
|
5
|
+
def test_method
|
6
|
+
given
|
7
|
+
x = 1
|
8
|
+
|
9
|
+
expect
|
10
|
+
x == 1
|
11
|
+
end
|
12
|
+
|
13
|
+
The "given" block is a setup you do for your test. Every line in the "expect" block is an assertion.
|
14
|
+
|
15
|
+
|
data/lib/picard.rb
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
require "picard/version"
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require_relative 'picard/extensions'
|
4
|
+
require_relative 'picard/context'
|
5
|
+
require_relative 'picard/error_message_formatter'
|
6
|
+
require_relative 'picard/ast_helper'
|
7
|
+
require_relative 'picard/assertion_wrapper'
|
8
|
+
require_relative 'picard/s_expression_sugar'
|
9
|
+
require_relative 'picard/class_ripper'
|
10
|
+
require_relative 'picard/preprocessor'
|
11
|
+
require_relative 'picard/method_ripper'
|
12
|
+
require_relative 'picard/test_unit'
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'live_ast'
|
2
|
+
require 'ruby2ruby'
|
3
|
+
require_relative 's_expression_sugar'
|
4
|
+
|
5
|
+
module Picard
|
6
|
+
class AssertionWrapper
|
7
|
+
include Picard::SExpressionSugar
|
8
|
+
|
9
|
+
def initialize formatter = ErrorMessageFormatter.new
|
10
|
+
@formatter = formatter
|
11
|
+
end
|
12
|
+
|
13
|
+
def wrap_assertion ast, context
|
14
|
+
line = ast_to_str(ast)
|
15
|
+
message = @formatter.format_message(line, context)
|
16
|
+
|
17
|
+
if equal_to_assertion? ast
|
18
|
+
s(:call, nil,
|
19
|
+
:assert_equal,
|
20
|
+
s(:arglist,
|
21
|
+
extract_argument(ast),
|
22
|
+
extract_receiver(ast),
|
23
|
+
s(:str, message)))
|
24
|
+
else
|
25
|
+
s(:call, nil, :assert, s(:arglist,ast, s(:str, message)))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def equal_to_assertion? ast
|
32
|
+
ast[0] == :call and ast[2] == :==
|
33
|
+
end
|
34
|
+
|
35
|
+
def extract_argument ast
|
36
|
+
ast[3][1]
|
37
|
+
end
|
38
|
+
|
39
|
+
def extract_receiver ast
|
40
|
+
ast[1]
|
41
|
+
end
|
42
|
+
|
43
|
+
def ast_to_str ast
|
44
|
+
copy = Sexp.from_array(ast.to_a)
|
45
|
+
Ruby2Ruby.new.process copy
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class SimpleAssertionWrapper
|
50
|
+
include Picard::SExpressionSugar
|
51
|
+
|
52
|
+
def wrap_assertion ast, context
|
53
|
+
s(:call, nil,:assert,s(:arglist,ast))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/picard/ast_helper.rb
CHANGED
@@ -5,51 +5,66 @@ module Picard
|
|
5
5
|
class AstHelper
|
6
6
|
ResultItem = Struct.new(:index, :ast)
|
7
7
|
|
8
|
+
def initialize wrapper = Picard::AssertionWrapper.new
|
9
|
+
@wrapper = wrapper
|
10
|
+
end
|
11
|
+
|
8
12
|
def all_statements method
|
9
13
|
method_ast = method.to_ast
|
10
|
-
body_statements =
|
14
|
+
body_statements = extract_body_statements(method_ast)
|
11
15
|
wrap_in_result_items body_statements
|
12
16
|
end
|
13
17
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
start_index ?
|
18
|
+
def all_statements_in_block method, block_name
|
19
|
+
statements = all_statements(method)
|
20
|
+
|
21
|
+
start_index = find_index_of_statements_calling(statements, block_name)
|
22
|
+
start_index ? statements[start_index + 1 .. -1] : []
|
19
23
|
end
|
20
24
|
|
21
|
-
def wrap_assertion ast
|
22
|
-
|
25
|
+
def wrap_assertion method, ast
|
26
|
+
context = Picard::Context.new(method.source_location[0], ast.line)
|
27
|
+
@wrapper.wrap_assertion ast, context
|
23
28
|
end
|
24
29
|
|
25
|
-
def replace_statement method, index,
|
30
|
+
def replace_statement method, index, new_statement_ast
|
26
31
|
method_ast = method.to_ast
|
27
32
|
body_statements = extract_statements(method_ast)
|
28
|
-
body_statements[index + 1] =
|
33
|
+
body_statements[index + 1] = new_statement_ast
|
29
34
|
end
|
30
35
|
|
31
|
-
def
|
32
|
-
method.to_ast
|
36
|
+
def method_to_string method
|
37
|
+
ast = method.to_ast
|
38
|
+
str = ast_to_str ast
|
39
|
+
remove_spaces str
|
33
40
|
end
|
34
41
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
e.ast[0] == :lasgn
|
40
|
-
end.collect do |e|
|
41
|
-
e.ast[1]
|
42
|
-
end
|
42
|
+
private
|
43
|
+
|
44
|
+
def ast_to_str ast
|
45
|
+
Ruby2Ruby.new.process ast
|
43
46
|
end
|
44
47
|
|
45
|
-
|
46
|
-
|
48
|
+
def remove_spaces str
|
49
|
+
str.gsub(/\n\s+/, "\n")
|
50
|
+
end
|
51
|
+
|
52
|
+
def find_index_of_statements_calling items, method_name
|
47
53
|
items.index do |item|
|
48
54
|
ast = item.ast
|
49
55
|
ast[0] == :call and ast[2] == method_name
|
50
56
|
end
|
51
57
|
end
|
52
58
|
|
59
|
+
def extract_body_statements method_ast
|
60
|
+
st = extract_statements(method_ast)
|
61
|
+
remove_prefix_statement st
|
62
|
+
end
|
63
|
+
|
64
|
+
def remove_prefix_statement statements
|
65
|
+
statements[1..-1]
|
66
|
+
end
|
67
|
+
|
53
68
|
def extract_statements method_ast
|
54
69
|
method_ast[3][1]
|
55
70
|
end
|
data/lib/picard/class_ripper.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
module Picard
|
2
|
+
class ErrorMessageFormatter
|
3
|
+
def format_message message, context
|
4
|
+
location = "File: #{context.file}, Line: #{context.lineno}"
|
5
|
+
new_message = "Failed Assertion: #{message}"
|
6
|
+
|
7
|
+
lines = make_same_size(location, new_message)
|
8
|
+
border = '-' * (lines.first.length + 4) #4 = 2 pipes + 2 spaces
|
9
|
+
"#{border}\n| #{lines[0]} |\n| #{lines[1]} |\n#{border}"
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def make_same_size a, b
|
14
|
+
return make_same_size(b, a) if a.length < b.length
|
15
|
+
if a.length > b.length
|
16
|
+
[a, b + ' ' * (a.length - b.length)]
|
17
|
+
else
|
18
|
+
[a + ' ' * (b.length - a.length), b]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class SimpleErrorMessageFormatter
|
24
|
+
def format_message message, context
|
25
|
+
message
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/picard/method_ripper.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
require 'live_ast'
|
2
|
-
require 'live_ast/to_ruby'
|
3
|
-
require 'ruby2ruby'
|
4
2
|
|
5
3
|
module Picard
|
6
4
|
class MethodRipper
|
@@ -8,29 +6,24 @@ module Picard
|
|
8
6
|
@ast_helper = ast_helper
|
9
7
|
end
|
10
8
|
|
11
|
-
def wrap_all_assertions method
|
12
|
-
|
13
|
-
assertions
|
14
|
-
|
15
|
-
ast_to_str @ast_helper.extract_ast(method)
|
9
|
+
def wrap_all_assertions! method
|
10
|
+
assertions = @ast_helper.all_statements_in_block(method, :expect)
|
11
|
+
replace_all_statements_with_assertions! assertions, method
|
12
|
+
replace_method_implementation_in_owner! method
|
16
13
|
end
|
17
14
|
|
18
15
|
private
|
19
16
|
|
20
|
-
def replace_all_statements_with_assertions assertions, method
|
17
|
+
def replace_all_statements_with_assertions! assertions, method
|
21
18
|
assertions.each do |e|
|
22
|
-
wrapped = @ast_helper.wrap_assertion(e.ast)
|
19
|
+
wrapped = @ast_helper.wrap_assertion(method, e.ast)
|
23
20
|
@ast_helper.replace_statement(method, e.index, wrapped)
|
24
21
|
end
|
25
22
|
end
|
26
23
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
def remove_spaces str
|
33
|
-
str.gsub(/\n\s+/, "\n")
|
24
|
+
def replace_method_implementation_in_owner! method
|
25
|
+
new_method_str = @ast_helper.method_to_string(method)
|
26
|
+
method.owner.class_eval new_method_str
|
34
27
|
end
|
35
28
|
end
|
36
29
|
end
|
data/lib/picard/preprocessor.rb
CHANGED
@@ -22,15 +22,14 @@ module Picard
|
|
22
22
|
return unless @class_ripper.test_method?(method_name)
|
23
23
|
|
24
24
|
mark_as_preprocessed method_name
|
25
|
-
replace_method_with_preprocessed clazz, method_name
|
25
|
+
replace_method_with_preprocessed! clazz, method_name
|
26
26
|
end
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
-
def replace_method_with_preprocessed clazz, method_name
|
30
|
+
def replace_method_with_preprocessed! clazz, method_name
|
31
31
|
method = clazz.instance_method(method_name)
|
32
|
-
|
33
|
-
@class_ripper.replace_method clazz, new_method_str
|
32
|
+
@method_ripper.wrap_all_assertions!(method)
|
34
33
|
end
|
35
34
|
|
36
35
|
def preprocessed? method_name
|
data/lib/picard/test_unit.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Picard
|
2
|
-
|
2
|
+
PREPROCESSOR = Picard::Preprocessor.new
|
3
|
+
|
4
|
+
module InstanceMethods
|
3
5
|
def given
|
4
6
|
end
|
5
7
|
|
@@ -9,14 +11,18 @@ module Picard
|
|
9
11
|
|
10
12
|
module ClassMethods
|
11
13
|
def method_added name
|
12
|
-
|
13
|
-
|
14
|
+
preprocess_add_method name
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def preprocess_add_method name
|
19
|
+
Picard::PREPROCESSOR.preprocess_method self, name
|
14
20
|
end
|
15
21
|
end
|
16
22
|
|
17
23
|
module TestUnit
|
18
24
|
def self.included clazz
|
19
|
-
clazz.send :include,
|
25
|
+
clazz.send :include, InstanceMethods
|
20
26
|
clazz.send :extend, ClassMethods
|
21
27
|
end
|
22
28
|
end
|
data/lib/picard/version.rb
CHANGED
data/picard.gemspec
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path("../../test_helper", __FILE__)
|
2
|
+
|
3
|
+
class Picard::AssertionWrapperTest < Test::Unit::TestCase
|
4
|
+
include Picard::TestUnit
|
5
|
+
include Picard::SExpressionSugar
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@formatter = flexmock('formatter')
|
9
|
+
@wrapper = Picard::AssertionWrapper.new @formatter
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_should_wrap_simple_assertions
|
13
|
+
given
|
14
|
+
ast = s(:lit, true)
|
15
|
+
context = flexmock(:file => 'file', :lineno => 1)
|
16
|
+
@formatter.should_receive(:format_message).with('true', context).and_return('generated error message')
|
17
|
+
|
18
|
+
expect
|
19
|
+
@wrapper.wrap_assertion(ast, context) == s(:call, nil,
|
20
|
+
:assert,
|
21
|
+
s(:arglist,
|
22
|
+
s(:lit, true),
|
23
|
+
s(:str, 'generated error message')))
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_should_wrap_equal_to_assertions
|
27
|
+
given
|
28
|
+
ast = s(:call, s(:lit, 1), :==, s(:arglist, s(:lit, 2)))
|
29
|
+
context = flexmock(:file => 'file', :lineno => 1)
|
30
|
+
@formatter.should_receive(:format_message).with('(1 == 2)', context).and_return('generated error message')
|
31
|
+
|
32
|
+
expect
|
33
|
+
@wrapper.wrap_assertion(ast, context) == s(:call, nil,
|
34
|
+
:assert_equal,
|
35
|
+
s(:arglist,
|
36
|
+
s(:lit, 2),
|
37
|
+
s(:lit, 1),
|
38
|
+
s(:str, 'generated error message')))
|
39
|
+
end
|
40
|
+
end
|
@@ -1,99 +1,117 @@
|
|
1
|
-
|
1
|
+
require File.expand_path("../../test_helper", __FILE__)
|
2
2
|
|
3
3
|
class Picard::AstHelperTest < Test::Unit::TestCase
|
4
|
-
|
5
|
-
|
6
|
-
x = 10
|
4
|
+
include Picard::TestUnit
|
5
|
+
include Picard::SExpressionSugar
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
def setup
|
8
|
+
@wrapper = flexmock('wrapper')
|
9
|
+
@helper = Picard::AstHelper.new @wrapper
|
10
|
+
end
|
11
11
|
|
12
|
-
where
|
13
|
-
y = 1
|
14
|
-
end
|
15
12
|
|
16
|
-
|
17
|
-
|
13
|
+
class TestClass1
|
14
|
+
def test_method
|
15
|
+
one
|
16
|
+
two
|
18
17
|
end
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def test_should_return_all_statements_of_method
|
21
|
+
given
|
22
|
+
method = TestClass1.instance_method(:test_method)
|
23
|
+
actual = @helper.all_statements(method)
|
24
|
+
|
25
|
+
expect
|
26
|
+
actual[0].index == 0
|
27
|
+
actual[0].ast == s(:call, nil, :one, s(:arglist))
|
28
|
+
|
29
|
+
actual[1].index == 1
|
30
|
+
actual[1].ast == s(:call, nil, :two, s(:arglist))
|
31
|
+
end
|
23
32
|
|
24
|
-
def test_method_with_where_block
|
25
|
-
x = 10
|
26
33
|
|
27
|
-
|
28
|
-
|
29
|
-
|
34
|
+
class TestClass2
|
35
|
+
def test_method
|
36
|
+
one
|
37
|
+
expect
|
38
|
+
two
|
30
39
|
end
|
31
40
|
end
|
32
41
|
|
33
|
-
def
|
34
|
-
|
42
|
+
def test_should_find_all_statements_in_specified_block
|
43
|
+
given
|
44
|
+
method = TestClass2.instance_method(:test_method)
|
45
|
+
actual = @helper.all_statements_in_block(method, :expect)
|
46
|
+
|
47
|
+
expect
|
48
|
+
actual.size == 1
|
49
|
+
actual[0].index == 2
|
50
|
+
actual[0].ast == s(:call, nil, :two, s(:arglist))
|
35
51
|
end
|
36
52
|
|
37
|
-
def test_should_return_all_statements_of_method
|
38
|
-
method = TestClass.instance_method(:test_method)
|
39
|
-
actual = @helper.all_statements(method)
|
40
|
-
|
41
|
-
assert_equal 0, actual[0].index
|
42
|
-
assert_equal s(:lasgn, :x, s(:lit, 10)), actual[0].ast
|
43
53
|
|
44
|
-
|
45
|
-
|
54
|
+
class TestClass3
|
55
|
+
def test_method
|
56
|
+
one
|
57
|
+
two
|
58
|
+
end
|
59
|
+
end
|
46
60
|
|
47
|
-
|
48
|
-
|
61
|
+
def test_should_return_empty_array_if_block_is_not_found
|
62
|
+
given
|
63
|
+
method = TestClass3.instance_method(:test_method)
|
49
64
|
|
50
|
-
|
51
|
-
|
65
|
+
expect
|
66
|
+
@helper.all_statements_in_block(method, :where) == []
|
52
67
|
end
|
53
68
|
|
54
|
-
def test_should_find_all_statements_in_specified_block
|
55
|
-
method = TestClass.instance_method(:test_method)
|
56
|
-
all_statements = @helper.all_statements(method)
|
57
|
-
actual = @helper.find_all_statements_in_block(all_statements, :expect)
|
58
69
|
|
59
|
-
|
70
|
+
class TestClass4
|
71
|
+
def test_method
|
72
|
+
false
|
73
|
+
end
|
74
|
+
end
|
60
75
|
|
61
|
-
|
62
|
-
|
76
|
+
def test_should_replace_statement
|
77
|
+
given
|
78
|
+
method = TestClass4.instance_method(:test_method)
|
79
|
+
@helper.replace_statement(method, 0, s(:lit, true))
|
80
|
+
all_statements = @helper.all_statements(method)
|
63
81
|
|
64
|
-
|
65
|
-
|
82
|
+
expect
|
83
|
+
all_statements[0].ast == s(:lit, true)
|
66
84
|
end
|
67
85
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
assert_equal [], actual
|
86
|
+
|
87
|
+
class TestClass5
|
88
|
+
def method
|
89
|
+
end
|
73
90
|
end
|
74
91
|
|
75
92
|
def test_should_wrap_assertion
|
76
|
-
|
77
|
-
|
78
|
-
|
93
|
+
given
|
94
|
+
method = TestClass5.instance_method(:method)
|
95
|
+
ast = s(:lit, true)
|
96
|
+
@wrapper.should_receive(:wrap_assertion).and_return('wrapped ast')
|
79
97
|
|
80
|
-
|
81
|
-
|
82
|
-
@helper.replace_statement(method, 0, s(:lit, true))
|
83
|
-
|
84
|
-
all_statements = @helper.all_statements(method)
|
85
|
-
assert_equal s(:lit, true), all_statements[0].ast
|
98
|
+
expect
|
99
|
+
@helper.wrap_assertion(method, ast) == 'wrapped ast'
|
86
100
|
end
|
87
101
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
102
|
+
|
103
|
+
class TestClass5
|
104
|
+
def method
|
105
|
+
false
|
106
|
+
end
|
93
107
|
end
|
94
108
|
|
95
|
-
|
96
|
-
|
97
|
-
|
109
|
+
def test_should_return_string_representation_of_a_method_reflecting_updated_ast
|
110
|
+
given
|
111
|
+
method = TestClass5.instance_method(:method)
|
112
|
+
@helper.replace_statement(method, 0, s(:lit, true))
|
113
|
+
|
114
|
+
expect
|
115
|
+
@helper.method_to_string(method) == "def method\ntrue\nend"
|
98
116
|
end
|
99
117
|
end
|
@@ -1,44 +1,39 @@
|
|
1
|
-
|
1
|
+
require File.expand_path("../../test_helper", __FILE__)
|
2
2
|
|
3
3
|
class Picard::ClassRipperTest < Test::Unit::TestCase
|
4
|
-
|
5
|
-
def test_one; end
|
6
|
-
def test_two; end
|
7
|
-
def three; end
|
8
|
-
end
|
9
|
-
|
10
|
-
class TestClassWithoutTestMethods
|
11
|
-
def method1; end
|
12
|
-
end
|
13
|
-
|
14
|
-
class DummyClass
|
15
|
-
def dummy
|
16
|
-
'dummy'
|
17
|
-
end
|
18
|
-
end
|
4
|
+
include Picard::TestUnit
|
19
5
|
|
20
6
|
def setup
|
21
7
|
@ripper = Picard::ClassRipper.new
|
22
8
|
end
|
9
|
+
|
23
10
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
11
|
+
def test_should_tell_if_method_name_is_test_method_name
|
12
|
+
expect
|
13
|
+
@ripper.test_method?('test_method')
|
14
|
+
!@ripper.test_method?('regular_method')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
class TestClass1
|
19
|
+
def test_one; end
|
20
|
+
def test_two; end
|
21
|
+
def three; end
|
27
22
|
end
|
28
23
|
|
29
24
|
def test_should_return_list_of_all_test_methods
|
30
|
-
|
31
|
-
|
25
|
+
expect
|
26
|
+
@ripper.all_test_method_names(TestClass1) == [:test_one, :test_two]
|
32
27
|
end
|
33
28
|
|
34
|
-
|
35
|
-
|
36
|
-
|
29
|
+
|
30
|
+
class TestClass2
|
31
|
+
def method1; end
|
37
32
|
end
|
38
33
|
|
39
|
-
def
|
40
|
-
|
41
|
-
|
34
|
+
def test_should_return_empty_list_if_there_are_no_test_methods
|
35
|
+
expect
|
36
|
+
@ripper.all_test_method_names(TestClass2) == []
|
42
37
|
end
|
43
38
|
end
|
44
39
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path("../../test_helper", __FILE__)
|
2
|
+
require 'live_ast'
|
3
|
+
|
4
|
+
module Picard
|
5
|
+
class DemoTest < Test::Unit::TestCase
|
6
|
+
include Picard::TestUnit
|
7
|
+
#
|
8
|
+
#def test_one
|
9
|
+
# expect
|
10
|
+
# 1 == 2
|
11
|
+
#end
|
12
|
+
#def regular_method
|
13
|
+
# method 1, 2
|
14
|
+
#end
|
15
|
+
#
|
16
|
+
#def test_two
|
17
|
+
# ast = DemoTest.instance_method(:regular_method).to_ast
|
18
|
+
# puts ast.class.name
|
19
|
+
#end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path("../../test_helper", __FILE__)
|
2
|
+
|
3
|
+
class Picard::ErrorMessageFormatterTest < Test::Unit::TestCase
|
4
|
+
include Picard::TestUnit
|
5
|
+
|
6
|
+
def test_should_wrap_error_message
|
7
|
+
given
|
8
|
+
formatter = Picard::ErrorMessageFormatter.new
|
9
|
+
expected = <<str
|
10
|
+
-----------------------------
|
11
|
+
| Failed Assertion: message |
|
12
|
+
| File: file, Line: 1 |
|
13
|
+
-----------------------------
|
14
|
+
str
|
15
|
+
|
16
|
+
expect
|
17
|
+
formatter.format_message('message', create_context('file', 1)) == expected.chomp
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def create_context(filename, lineno)
|
22
|
+
Struct.new(:file, :lineno).new(filename, lineno)
|
23
|
+
end
|
24
|
+
end
|
@@ -1,34 +1,51 @@
|
|
1
|
-
|
1
|
+
require File.expand_path("../../test_helper", __FILE__)
|
2
2
|
|
3
3
|
class Picard::MethodRipperTest < Test::Unit::TestCase
|
4
|
+
include Picard::TestUnit
|
5
|
+
|
4
6
|
class TestClass
|
7
|
+
attr_reader :assert_args
|
8
|
+
|
5
9
|
def test_method
|
6
|
-
given
|
7
|
-
something
|
8
10
|
expect
|
9
|
-
|
10
|
-
2 == 2
|
11
|
+
false
|
11
12
|
end
|
12
13
|
|
13
14
|
def regular_method
|
14
|
-
|
15
|
-
|
15
|
+
false
|
16
|
+
end
|
17
|
+
|
18
|
+
def expect; end
|
19
|
+
|
20
|
+
def assert arg
|
21
|
+
@assert_args ||= []
|
22
|
+
@assert_args << arg
|
16
23
|
end
|
17
24
|
end
|
18
25
|
|
19
26
|
def setup
|
20
|
-
|
27
|
+
wrapper = Picard::SimpleAssertionWrapper.new
|
28
|
+
helper = Picard::AstHelper.new(wrapper)
|
29
|
+
@ripper = Picard::MethodRipper.new(helper)
|
21
30
|
end
|
22
31
|
|
23
32
|
def test_should_wrap_all_assertions_after_expect_method_call
|
24
|
-
|
25
|
-
|
26
|
-
|
33
|
+
given
|
34
|
+
method = TestClass.instance_method(:test_method)
|
35
|
+
@ripper.wrap_all_assertions!(method)
|
36
|
+
tc = TestClass.new
|
37
|
+
tc.test_method
|
38
|
+
|
39
|
+
expect
|
40
|
+
tc.assert_args == [false]
|
27
41
|
end
|
28
42
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
43
|
+
def test_should_not_change_method_if_no_expect_block
|
44
|
+
given
|
45
|
+
method = TestClass.instance_method(:regular_method)
|
46
|
+
@ripper.wrap_all_assertions! method
|
47
|
+
|
48
|
+
expect
|
49
|
+
TestClass.new.regular_method == false
|
33
50
|
end
|
34
51
|
end
|
@@ -1,114 +1,129 @@
|
|
1
|
-
|
1
|
+
require File.expand_path("../../test_helper", __FILE__)
|
2
2
|
|
3
3
|
class Picard::PreprocessorTest < Test::Unit::TestCase
|
4
|
-
include
|
4
|
+
include Picard::TestUnit
|
5
5
|
|
6
6
|
class BaseTestClass
|
7
7
|
attr_reader :assert_args
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
def given
|
14
|
-
end
|
9
|
+
def given; end
|
10
|
+
def expect; end
|
11
|
+
def where; end
|
12
|
+
def picard_format_error_message(m,l); end
|
15
13
|
|
16
|
-
def expect
|
17
|
-
end
|
18
|
-
|
19
|
-
def where
|
20
|
-
end
|
21
14
|
|
22
|
-
def assert arg
|
15
|
+
def assert arg, message
|
16
|
+
@assert_args ||= []
|
23
17
|
@assert_args << arg
|
24
18
|
end
|
25
19
|
end
|
26
20
|
|
27
|
-
|
28
|
-
|
21
|
+
def setup
|
22
|
+
@pr = Picard::Preprocessor.new
|
23
|
+
end
|
24
|
+
|
25
|
+
class TestClass1 < BaseTestClass
|
29
26
|
def test_method
|
30
27
|
expect
|
31
|
-
|
28
|
+
false
|
32
29
|
end
|
33
30
|
end
|
34
31
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
32
|
+
def test_should_wrap_assertions_after_expect_in_all_test_methods
|
33
|
+
given
|
34
|
+
@pr.preprocess_class(TestClass1)
|
35
|
+
tc = TestClass1.new
|
36
|
+
tc.test_method
|
38
37
|
|
39
|
-
|
40
|
-
|
41
|
-
assert_equal [false], tc.assert_args
|
38
|
+
expect
|
39
|
+
tc.assert_args == [false]
|
42
40
|
end
|
43
41
|
|
44
42
|
|
45
43
|
class TestClass2 < BaseTestClass
|
46
44
|
def test_method
|
47
45
|
expect
|
48
|
-
|
46
|
+
false
|
49
47
|
end
|
50
48
|
end
|
51
49
|
|
52
50
|
def test_should_wrap_all_assertions_in_specified_method
|
53
|
-
|
54
|
-
|
51
|
+
given
|
52
|
+
@pr.preprocess_method(TestClass2, :test_method)
|
53
|
+
tc = TestClass2.new
|
54
|
+
tc.test_method
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
assert_equal [false], tc.assert_args
|
56
|
+
expect
|
57
|
+
tc.assert_args == [false]
|
59
58
|
end
|
60
59
|
|
61
60
|
|
62
61
|
class TestClass3 < BaseTestClass
|
63
62
|
def test_method
|
64
63
|
expect
|
65
|
-
|
64
|
+
false
|
66
65
|
end
|
67
66
|
end
|
68
67
|
|
69
|
-
def
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
def test_should_be_idempotent
|
69
|
+
given
|
70
|
+
@pr.preprocess_method(TestClass3, :test_method)
|
71
|
+
@pr.preprocess_method(TestClass3, :test_method)
|
72
|
+
|
73
|
+
tc = TestClass3.new
|
74
|
+
tc.test_method
|
73
75
|
|
74
|
-
|
75
|
-
|
76
|
-
assert_equal [false], tc.assert_args
|
76
|
+
expect
|
77
|
+
tc.assert_args == [false]
|
77
78
|
end
|
78
79
|
|
79
80
|
|
80
81
|
class TestClass4 < BaseTestClass
|
81
82
|
def regular_method
|
82
|
-
|
83
|
+
false
|
83
84
|
end
|
84
85
|
end
|
85
86
|
|
86
87
|
def test_should_ignore_non_test_methods
|
87
|
-
|
88
|
-
|
88
|
+
given
|
89
|
+
@pr.preprocess_method(TestClass4, :regular_method)
|
90
|
+
tc = TestClass4.new
|
91
|
+
tc.regular_method
|
92
|
+
|
93
|
+
expect
|
94
|
+
tc.assert_args == nil
|
95
|
+
end
|
89
96
|
|
90
|
-
|
91
|
-
|
92
|
-
|
97
|
+
|
98
|
+
class TestClass5 < BaseTestClass
|
99
|
+
def test_empty
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_should_successfully_transform_empty_methods
|
104
|
+
given
|
105
|
+
@pr.preprocess_method(TestClass5, :test_empty)
|
106
|
+
tc = TestClass5.new
|
107
|
+
tc.test_empty
|
108
|
+
|
109
|
+
expect
|
110
|
+
tc.assert_args == nil
|
93
111
|
end
|
94
112
|
|
95
113
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
# tc.test_method
|
112
|
-
# assert_equal [false], tc.assert_args
|
113
|
-
#end
|
114
|
+
class TestClass6 < BaseTestClass
|
115
|
+
def test_empty
|
116
|
+
expect
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_should_successfully_transform_methods_with_empty_expect_block
|
121
|
+
given
|
122
|
+
@pr.preprocess_method(TestClass6, :test_empty)
|
123
|
+
tc = TestClass6.new
|
124
|
+
tc.test_empty
|
125
|
+
|
126
|
+
expect
|
127
|
+
tc.assert_args == nil
|
128
|
+
end
|
114
129
|
end
|
@@ -1,27 +1,40 @@
|
|
1
|
-
|
1
|
+
require File.expand_path("../../test_helper", __FILE__)
|
2
2
|
|
3
3
|
class Picard::TestUnitTest < Test::Unit::TestCase
|
4
|
+
include Picard::TestUnit
|
5
|
+
|
4
6
|
class TestUsingPicard
|
5
7
|
include Picard::TestUnit
|
6
|
-
attr_reader :
|
8
|
+
attr_reader :assert_arg, :assert_message
|
7
9
|
|
8
10
|
def test_method
|
9
|
-
given
|
10
|
-
x = 1
|
11
|
-
|
12
11
|
expect
|
13
|
-
|
12
|
+
false
|
14
13
|
end
|
15
14
|
|
16
|
-
def assert arg
|
17
|
-
@
|
18
|
-
@
|
15
|
+
def assert arg, message
|
16
|
+
@assert_arg = arg
|
17
|
+
@assert_message = message
|
19
18
|
end
|
20
19
|
end
|
21
20
|
|
22
21
|
def test_should_add_assertions_to_all_test_methods
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
given
|
23
|
+
test = TestUsingPicard.new
|
24
|
+
test.test_method
|
25
|
+
|
26
|
+
expect
|
27
|
+
test.assert_arg == false
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_should_use_specific_messages
|
31
|
+
given
|
32
|
+
test = TestUsingPicard.new
|
33
|
+
test.test_method
|
34
|
+
|
35
|
+
expect
|
36
|
+
test.assert_message.split("\n")[2] =~ /Failed Assertion: false/
|
37
|
+
test.assert_message.split("\n")[1] =~ /test_unit_test.rb/
|
38
|
+
test.assert_message.split("\n")[1] =~ /Line: 13/ #TODO fixit, it must be Line: 12
|
26
39
|
end
|
27
40
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
require 'test/unit'
|
2
|
-
require '
|
2
|
+
require 'flexmock/test_unit'
|
3
3
|
|
4
|
+
require_relative '../lib/picard/extensions'
|
5
|
+
require_relative '../lib/picard/context'
|
6
|
+
require_relative '../lib/picard/error_message_formatter'
|
4
7
|
require_relative '../lib/picard/ast_helper'
|
8
|
+
require_relative '../lib/picard/assertion_wrapper'
|
9
|
+
require_relative '../lib/picard/s_expression_sugar'
|
5
10
|
require_relative '../lib/picard/class_ripper'
|
6
11
|
require_relative '../lib/picard/preprocessor'
|
7
12
|
require_relative '../lib/picard/method_ripper'
|
8
|
-
require_relative '../lib/picard/expect_block'
|
9
13
|
require_relative '../lib/picard/test_unit'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: picard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,12 +9,12 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-10-02 00:00:00.000000000 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: live_ast
|
17
|
-
requirement: &
|
17
|
+
requirement: &2169351160 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - =
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: 1.0.2
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *2169351160
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: live_ast_ripper
|
28
|
-
requirement: &
|
28
|
+
requirement: &2169350560 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - =
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: 0.6.5
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *2169350560
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
|
-
name:
|
39
|
-
requirement: &
|
38
|
+
name: flexmock
|
39
|
+
requirement: &2169350180 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,18 +44,7 @@ dependencies:
|
|
44
44
|
version: '0'
|
45
45
|
type: :development
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
48
|
-
- !ruby/object:Gem::Dependency
|
49
|
-
name: picard
|
50
|
-
requirement: &2168698520 !ruby/object:Gem::Requirement
|
51
|
-
none: false
|
52
|
-
requirements:
|
53
|
-
- - =
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version: 0.0.1
|
56
|
-
type: :development
|
57
|
-
prerelease: false
|
58
|
-
version_requirements: *2168698520
|
47
|
+
version_requirements: *2169350180
|
59
48
|
description: Test framework inspired by Spock
|
60
49
|
email:
|
61
50
|
- vic.savkin@gmail.com
|
@@ -66,19 +55,26 @@ files:
|
|
66
55
|
- .gitignore
|
67
56
|
- Gemfile
|
68
57
|
- Gemfile.lock
|
58
|
+
- README.rdoc
|
69
59
|
- Rakefile
|
70
60
|
- lib/picard.rb
|
61
|
+
- lib/picard/assertion_wrapper.rb
|
71
62
|
- lib/picard/ast_helper.rb
|
72
63
|
- lib/picard/class_ripper.rb
|
73
|
-
- lib/picard/
|
64
|
+
- lib/picard/context.rb
|
65
|
+
- lib/picard/error_message_formatter.rb
|
66
|
+
- lib/picard/extensions.rb
|
74
67
|
- lib/picard/method_ripper.rb
|
75
68
|
- lib/picard/preprocessor.rb
|
69
|
+
- lib/picard/s_expression_sugar.rb
|
76
70
|
- lib/picard/test_unit.rb
|
77
71
|
- lib/picard/version.rb
|
78
72
|
- picard.gemspec
|
73
|
+
- test/picard/assertion_wrapper_test.rb
|
79
74
|
- test/picard/ast_helper_test.rb
|
80
75
|
- test/picard/class_ripper_test.rb
|
81
|
-
- test/picard/
|
76
|
+
- test/picard/demo_test.rb
|
77
|
+
- test/picard/error_message_formatter_test.rb
|
82
78
|
- test/picard/method_ripper_test.rb
|
83
79
|
- test/picard/preprocessor_test.rb
|
84
80
|
- test/picard/test_unit_test.rb
|
@@ -109,9 +105,11 @@ signing_key:
|
|
109
105
|
specification_version: 3
|
110
106
|
summary: Test framework inspired by Spock
|
111
107
|
test_files:
|
108
|
+
- test/picard/assertion_wrapper_test.rb
|
112
109
|
- test/picard/ast_helper_test.rb
|
113
110
|
- test/picard/class_ripper_test.rb
|
114
|
-
- test/picard/
|
111
|
+
- test/picard/demo_test.rb
|
112
|
+
- test/picard/error_message_formatter_test.rb
|
115
113
|
- test/picard/method_ripper_test.rb
|
116
114
|
- test/picard/preprocessor_test.rb
|
117
115
|
- test/picard/test_unit_test.rb
|
data/lib/picard/expect_block.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
require_relative '../test_helper'
|
2
|
-
|
3
|
-
class Picard::ExpectBlockTest < Test::Unit::TestCase
|
4
|
-
|
5
|
-
def test_should_call_passed_block
|
6
|
-
res = nil
|
7
|
-
Picard::ExpectBlock.invoke do
|
8
|
-
res = true
|
9
|
-
end
|
10
|
-
assert res
|
11
|
-
end
|
12
|
-
|
13
|
-
def test_should_use_passed_variables_in_block
|
14
|
-
res = nil
|
15
|
-
Picard::ExpectBlock.invoke(true) do |x|
|
16
|
-
res = x
|
17
|
-
end
|
18
|
-
assert res
|
19
|
-
end
|
20
|
-
end
|