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.
@@ -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
+
@@ -1,4 +1,12 @@
1
1
  require "picard/version"
2
2
 
3
- module Picard
4
- end
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
@@ -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 = extract_statements(method_ast)[1..-1]
14
+ body_statements = extract_body_statements(method_ast)
11
15
  wrap_in_result_items body_statements
12
16
  end
13
17
 
14
- def find_all_statements_in_block items, block_name
15
- start_index = find_index_of_statements_calling(items, block_name)
16
- end_index = find_index_of_statements_calling(items, :where)
17
- end_index = -1 unless end_index
18
- start_index ? items[start_index + 1 ... end_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
- Sexp.new(:call, nil, :assert, Sexp.new(:arglist, ast))
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, new_ast
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] = new_ast
33
+ body_statements[index + 1] = new_statement_ast
29
34
  end
30
35
 
31
- def extract_ast method
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
- def find_all_local_variables_in_block items, block_name
36
- index = find_index_of_statements_calling(items, block_name)
37
- return [] unless index
38
- items[index + 1 .. -1].find_all do |e|
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
- private
46
- def find_index_of_statements_calling(items, method_name)
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
@@ -9,9 +9,5 @@ module Picard
9
9
  test_method? m
10
10
  end
11
11
  end
12
-
13
- def replace_method clazz, new_method
14
- clazz.class_eval new_method
15
- end
16
12
  end
17
13
  end
@@ -0,0 +1,3 @@
1
+ module Picard
2
+ Context = Struct.new(:file, :lineno)
3
+ end
@@ -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
@@ -0,0 +1,10 @@
1
+ module Picard
2
+ class ::Object
3
+ def metaclass; class << self; self; end; end
4
+ def meta_eval &blk; metaclass.instance_eval &blk; end
5
+
6
+ def meta_def name, &blk
7
+ meta_eval { define_method name, &blk }
8
+ end
9
+ end
10
+ end
@@ -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
- all_statements = @ast_helper.all_statements(method)
13
- assertions = @ast_helper.find_all_statements_in_block(all_statements, :expect)
14
- replace_all_statements_with_assertions assertions, method
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 ast_to_str ast
28
- str = Ruby2Ruby.new.process(ast)
29
- remove_spaces str
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
@@ -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
- new_method_str = @method_ripper.wrap_all_assertions(method)
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
@@ -0,0 +1,7 @@
1
+ module Picard
2
+ module SExpressionSugar
3
+ def s *args
4
+ Sexp.new *args
5
+ end
6
+ end
7
+ end
@@ -1,5 +1,7 @@
1
1
  module Picard
2
- module DummyMethods
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
- @tr ||= Picard::Preprocessor.new
13
- @tr.preprocess_method self, name
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, DummyMethods
25
+ clazz.send :include, InstanceMethods
20
26
  clazz.send :extend, ClassMethods
21
27
  end
22
28
  end
@@ -1,3 +1,3 @@
1
1
  module Picard
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -20,6 +20,5 @@ Gem::Specification.new do |s|
20
20
 
21
21
  s.add_dependency 'live_ast', '= 1.0.2'
22
22
  s.add_dependency 'live_ast_ripper', '= 0.6.5'
23
- s.add_development_dependency 'rr'
24
- s.add_development_dependency 'picard', '= 0.0.1'
23
+ s.add_development_dependency 'flexmock'
25
24
  end
@@ -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
- require_relative '../test_helper'
1
+ require File.expand_path("../../test_helper", __FILE__)
2
2
 
3
3
  class Picard::AstHelperTest < Test::Unit::TestCase
4
- class TestClass
5
- def test_method
6
- x = 10
4
+ include Picard::TestUnit
5
+ include Picard::SExpressionSugar
7
6
 
8
- expect
9
- x == 10
10
- x == 12
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
- def method_without_assertions
17
- 'dummy'
13
+ class TestClass1
14
+ def test_method
15
+ one
16
+ two
18
17
  end
18
+ end
19
19
 
20
- def test_method_to_replace_statements
21
- 'dummy'
22
- end
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
- where
28
- y = 20
29
- z = 30
34
+ class TestClass2
35
+ def test_method
36
+ one
37
+ expect
38
+ two
30
39
  end
31
40
  end
32
41
 
33
- def setup
34
- @helper = Picard::AstHelper.new
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
- assert_equal 1, actual[1].index
45
- assert_equal s(:call, nil, :expect, s(:arglist)), actual[1].ast
54
+ class TestClass3
55
+ def test_method
56
+ one
57
+ two
58
+ end
59
+ end
46
60
 
47
- assert_equal 2, actual[2].index
48
- assert_equal s(:call, s(:lvar, :x), :==, s(:arglist, s(:lit, 10))), actual[2].ast
61
+ def test_should_return_empty_array_if_block_is_not_found
62
+ given
63
+ method = TestClass3.instance_method(:test_method)
49
64
 
50
- assert_equal 3, actual[3].index
51
- assert_equal s(:call, s(:lvar, :x), :==, s(:arglist, s(:lit, 12))), actual[3].ast
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
- assert_equal 2, actual.size
70
+ class TestClass4
71
+ def test_method
72
+ false
73
+ end
74
+ end
60
75
 
61
- assert_equal 2, actual[0].index
62
- assert_equal s(:call, s(:lvar, :x), :==, s(:arglist, s(:lit, 10))), actual[0].ast
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
- assert_equal 3, actual[1].index
65
- assert_equal s(:call, s(:lvar, :x), :==, s(:arglist, s(:lit, 12))), actual[1].ast
82
+ expect
83
+ all_statements[0].ast == s(:lit, true)
66
84
  end
67
85
 
68
- def test_should_return_empty_array_if_specified_method_call_was_not_found
69
- method = TestClass.instance_method(:method_without_assertions)
70
- all_statements = @helper.all_statements(method)
71
- actual = @helper.find_all_statements_in_block(all_statements, :expect)
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
- result = @helper.wrap_assertion(s(:lit, true))
77
- assert_equal s(:call, nil, :assert, s(:arglist, s(:lit, true))), result
78
- end
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
- def test_should_replace_statement
81
- method = TestClass.instance_method(:test_method_to_replace_statements)
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
- def test_should_return_list_of_all_local_variables_defined_after_specified_method_call
89
- method = TestClass.instance_method(:test_method_with_where_block)
90
- all_statements = @helper.all_statements(method)
91
- actual = @helper.find_all_local_variables_in_block(all_statements, :where)
92
- assert_equal [:y, :z], actual
102
+
103
+ class TestClass5
104
+ def method
105
+ false
106
+ end
93
107
  end
94
108
 
95
- private
96
- def s(*args)
97
- Sexp.new *args
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
- require_relative '../test_helper'
1
+ require File.expand_path("../../test_helper", __FILE__)
2
2
 
3
3
  class Picard::ClassRipperTest < Test::Unit::TestCase
4
- class TestClass
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 test_should_return_if_method_is_test_method
25
- assert @ripper.test_method?('test_method')
26
- assert !@ripper.test_method?('regular_method')
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
- test_methods = @ripper.all_test_method_names(TestClass)
31
- assert_equal [:test_one, :test_two], test_methods
25
+ expect
26
+ @ripper.all_test_method_names(TestClass1) == [:test_one, :test_two]
32
27
  end
33
28
 
34
- def test_should_return_empty_list_if_there_are_no_test_methods
35
- test_methods = @ripper.all_test_method_names(TestClassWithoutTestMethods)
36
- assert_equal [], test_methods
29
+
30
+ class TestClass2
31
+ def method1; end
37
32
  end
38
33
 
39
- def test_should_replace_method_implementation
40
- @ripper.replace_method(DummyClass, "def dummy\n 'replaced' \n end")
41
- assert_equal 'replaced', DummyClass.new.dummy
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
- require_relative '../test_helper'
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
- 1 == 1
10
- 2 == 2
11
+ false
11
12
  end
12
13
 
13
14
  def regular_method
14
- 1 == 1
15
- 2 == 2
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
- @ripper = Picard::MethodRipper.new
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
- method = TestClass.instance_method(:test_method)
25
- new_method_str = @ripper.wrap_all_assertions(method)
26
- assert_equal "def test_method\ngiven\nsomething\nexpect\nassert((1 == 1))\nassert((2 == 2))\nend", new_method_str
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 test_should_return_existing_implementation_if_there_was_no_expect_method_call
30
- method = TestClass.instance_method(:regular_method)
31
- new_method_str = @ripper.wrap_all_assertions(method)
32
- assert_equal "def regular_method\n(1 == 1)\n(2 == 2)\nend", new_method_str
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
- require_relative '../test_helper'
1
+ require File.expand_path("../../test_helper", __FILE__)
2
2
 
3
3
  class Picard::PreprocessorTest < Test::Unit::TestCase
4
- include RR::Adapters::RRMethods
4
+ include Picard::TestUnit
5
5
 
6
6
  class BaseTestClass
7
7
  attr_reader :assert_args
8
8
 
9
- def initialize
10
- @assert_args = []
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
- # We need to use a class per test for test isolation
28
- class TestClass < BaseTestClass
21
+ def setup
22
+ @pr = Picard::Preprocessor.new
23
+ end
24
+
25
+ class TestClass1 < BaseTestClass
29
26
  def test_method
30
27
  expect
31
- 1 == 2
28
+ false
32
29
  end
33
30
  end
34
31
 
35
- def test_should_wrap_all_assertions_after_expect_in_all_test_methods
36
- tr = Picard::Preprocessor.new
37
- tr.preprocess_class(TestClass)
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
- tc = TestClass.new
40
- tc.test_method
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
- 1 == 2
46
+ false
49
47
  end
50
48
  end
51
49
 
52
50
  def test_should_wrap_all_assertions_in_specified_method
53
- tr = Picard::Preprocessor.new
54
- tr.preprocess_method(TestClass2, :test_method)
51
+ given
52
+ @pr.preprocess_method(TestClass2, :test_method)
53
+ tc = TestClass2.new
54
+ tc.test_method
55
55
 
56
- tc = TestClass2.new
57
- tc.test_method
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
- 1 == 2
64
+ false
66
65
  end
67
66
  end
68
67
 
69
- def test_should_not_preprocess_the_same_method_twice
70
- tr = Picard::Preprocessor.new
71
- tr.preprocess_method(TestClass3, :test_method)
72
- tr.preprocess_method(TestClass3, :test_method)
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
- tc = TestClass3.new
75
- tc.test_method
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
- 1 == 2
83
+ false
83
84
  end
84
85
  end
85
86
 
86
87
  def test_should_ignore_non_test_methods
87
- tr = Picard::Preprocessor.new
88
- tr.preprocess_method(TestClass4, :regular_method)
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
- tc = TestClass4.new
91
- tc.regular_method
92
- assert_equal [], tc.assert_args
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
- #class TestClass5 < BaseTestClass
97
- # def test_method
98
- # expect
99
- # x == 1
100
- #
101
- # where
102
- # x = 2
103
- # end
104
- #end
105
- #
106
- #def test_should_use_local_variables_from_where_block
107
- # tr = Picard::Preprocessor.new ClassRipper.new,
108
- # tr.preprocess_method(TestClass5, :test_method)
109
- #
110
- # tc = TestClass5.new
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
- require_relative '../test_helper'
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 :assert_args
8
+ attr_reader :assert_arg, :assert_message
7
9
 
8
10
  def test_method
9
- given
10
- x = 1
11
-
12
11
  expect
13
- x == 2
12
+ false
14
13
  end
15
14
 
16
- def assert arg
17
- @assert_args ||= []
18
- @assert_args << arg
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
- test = TestUsingPicard.new
24
- test.test_method
25
- assert_equal [false], test.assert_args
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
@@ -1,9 +1,13 @@
1
1
  require 'test/unit'
2
- require 'rr'
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.2
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-09-05 00:00:00.000000000 -04:00
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: &2168700440 !ruby/object:Gem::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: *2168700440
25
+ version_requirements: *2169351160
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: live_ast_ripper
28
- requirement: &2168699820 !ruby/object:Gem::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: *2168699820
36
+ version_requirements: *2169350560
37
37
  - !ruby/object:Gem::Dependency
38
- name: rr
39
- requirement: &2168699280 !ruby/object:Gem::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: *2168699280
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/expect_block.rb
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/expect_block_test.rb
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/expect_block_test.rb
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
@@ -1,7 +0,0 @@
1
- module Picard
2
- class ExpectBlock
3
- def self.invoke *args
4
- yield *args
5
- end
6
- end
7
- end
@@ -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