citron 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,6 @@
1
1
  module Citron
2
2
 
3
+ # Test procedure --what you would call a honest to goodness unit test.
3
4
  #
4
5
  class TestProc
5
6
 
@@ -7,9 +8,12 @@ module Citron
7
8
  #
8
9
  def initialize(options={}, &procedure)
9
10
  @context = options[:context]
10
- @setup = options[:setup]
11
+ #@setup = options[:setup]
11
12
  @label = options[:label]
13
+ @tags = options[:tags]
12
14
  @skip = options[:skip]
15
+ @file = options[:file]
16
+ @line = options[:line]
13
17
 
14
18
  @procedure = procedure
15
19
  @tested = false
@@ -17,106 +21,152 @@ module Citron
17
21
 
18
22
  public
19
23
 
24
+ #
20
25
  # The parent testcase to which this test belongs.
26
+ #
21
27
  attr :context
22
28
 
29
+ #
30
+ # Alias for `#context`.
23
31
  #
24
32
  alias :parent :context
25
33
 
26
- # Setup and teardown procedures.
27
- attr :setup
28
-
34
+ #
29
35
  # Description of test.
36
+ #
30
37
  attr :label
31
38
 
39
+ #
40
+ # Symbol list of tags. Trailing element may be Hash
41
+ # of `symbol => object`.
42
+ #
43
+ attr :tags
44
+
45
+ #
32
46
  # Test procedure, in which test assertions should be made.
47
+ #
33
48
  attr :procedure
34
49
 
35
- # The before and after advice from the context.
36
- def advice
37
- context.advice
38
- end
39
-
40
50
  #
41
- def type
42
- 'Test'
43
- end
51
+ #
52
+ #
53
+ #def type
54
+ # 'test'
55
+ #end
44
56
 
57
+ #
58
+ # Whether to skip this test.
59
+ #
60
+ # @return [Boolean,String]
45
61
  #
46
62
  def skip? ; @skip ; end
47
63
 
64
+ #
65
+ # Set whether this test should be skipped of not.
66
+ #
67
+ # @param [Boolean,String] reason
68
+ # Reason to skip, or simple boolean flag.
48
69
  #
49
70
  def skip=(reason)
50
71
  @skip = reason
51
72
  end
52
73
 
74
+ #
75
+ # @todo Is this necessary?
53
76
  #
54
77
  def tested?
55
78
  @tested
56
79
  end
57
80
 
81
+ #
82
+ # @todo Is this necessary?
58
83
  #
59
84
  def tested=(boolean)
60
85
  @tested = !!boolean
61
86
  end
62
87
 
88
+ #
89
+ # Test description.
90
+ #
91
+ # @return [String]
63
92
  #
64
93
  def to_s
65
94
  label.to_s
66
95
  end
67
96
 
97
+ #
98
+ # @return [TestSetup] setup
68
99
  #
69
100
  def setup
70
- @setup
101
+ @context.setup
71
102
  end
72
103
 
73
- # Ruby Test looks for `topic` as the desciption of a test's setup.
104
+ #
105
+ # Ruby Test looks for `#topic` as the desciption of a test's setup.
106
+ #
107
+ # @return [String] Description of the setup.
108
+ #
74
109
  def topic
75
- @setup.to_s
110
+ setup.to_s
76
111
  end
77
112
 
113
+ #
114
+ # Location of test definition.
78
115
  #
79
- def scope
80
- context.scope
116
+ def source_location
117
+ [file, line]
81
118
  end
82
119
 
83
120
  #
84
- def arguments
85
- @arguments
86
- end
87
-
121
+ # Match test's label and/or tags.
88
122
  #
89
- def arguments=(args)
90
- @arguments = args
91
- end
92
-
93
- # TODO: how to handle negated tests?
94
- def negate
95
- @negate
123
+ # @param [String,Symbol,Regexp,Hash] match
124
+ # Pattern to match against.
125
+ #
126
+ # @return [Boolean]
127
+ #
128
+ def match?(match)
129
+ case match
130
+ when Symbol
131
+ tags.include?(match)
132
+ when Hash
133
+ if Hash === tags.last
134
+ tags.last.any?{ |k,v| match[k] == v }
135
+ end
136
+ else
137
+ match === label
138
+ end
96
139
  end
97
140
 
98
141
  #
99
- def negate=(boolean)
100
- @negate = !!boolean
142
+ # Run this test in context.
143
+ #
144
+ def call
145
+ context.run(self)
101
146
  end
102
147
 
148
+ #
149
+ # Convert `#call` to Proc.
150
+ #
151
+ # @return [Proc]
103
152
  #
104
153
  def to_proc
105
154
  lambda{ call }
106
155
  end
107
156
 
108
157
  #
109
- def match?(match)
110
- match == target || match === description
111
- end
158
+ #def set_proc(&proc)
159
+ # @procedure = proc
160
+ #end
112
161
 
113
- #
114
- def call
115
- context.run(self) do
116
- setup.run_setup(scope) if setup
117
- scope.instance_exec(*arguments, &procedure)
118
- setup.run_teardown(scope) if setup
162
+ class Scope < World
163
+
164
+ def initialize(parent)
165
+ #include context
166
+ @_parent = parent
167
+ extend parent
119
168
  end
169
+
120
170
  end
121
171
 
122
172
  end
@@ -1,51 +1,73 @@
1
1
  module Citron
2
2
 
3
- # Test Setup/Concern - Setup and Teardown code.
3
+ # Ecapsulate a test case's setup code.
4
+ #
4
5
  class TestSetup
5
6
 
7
+ #
6
8
  # The test case to which this advice belong.
9
+ #
7
10
  attr :context
8
11
 
9
- # A brief description of this concern.
10
- attr :label
12
+ #
13
+ # The setup procedures.
14
+ #
15
+ attr :procedures
11
16
 
12
- # The setup procedure.
13
- attr :setup
17
+ #
18
+ # A brief description of the setup.
19
+ #
20
+ attr :label
14
21
 
15
- # The teardown procedure.
16
- attr :teardown
22
+ #
23
+ # Initialize new Setup instance.
24
+ #
25
+ def initialize(context, label, &proc)
26
+ @context = context
27
+ @label = label.to_s
28
+ @procedures = []
17
29
 
18
- # New case instance.
19
- def initialize(context, label, options={}, &setup)
20
- @context = context
21
- @label = label.to_s
22
- @setup = [setup].flatten
23
- @teardown = []
30
+ @procedures << proc if proc
24
31
  end
25
32
 
26
33
  #
27
- def teardown=(procedure)
28
- @teardown = [procedure]
29
- end
30
-
31
- # Setup.
32
- def run_setup(scope)
33
- setup.each do |proc|
34
- scope.instance_eval(&proc)
35
- end
34
+ # Copy the setup for a new context.
35
+ #
36
+ def copy(context)
37
+ c = self.class.new(context, label)
38
+ c.procedures = procedures
39
+ c
36
40
  end
37
41
 
38
- # Teardown.
39
- def run_teardown(scope)
40
- teardown.each do |proc|
42
+ #
43
+ # Run setup procedure in test scope.
44
+ #
45
+ def call(scope)
46
+ procedures.each do |proc|
41
47
  scope.instance_eval(&proc)
42
48
  end
43
49
  end
44
50
 
51
+ #
45
52
  # Returns the description with newlines removed.
53
+ #
46
54
  def to_s
47
55
  label.gsub(/\n/, ' ')
48
56
  end
57
+
58
+ #
59
+ # Add a setup procedure.
60
+ #
61
+ def add(&proc)
62
+ @procedures << proc
63
+ end
64
+
65
+ protected
66
+
67
+ def procedures=(procedures)
68
+ @procedures = procedures
69
+ end
70
+
49
71
  end
50
72
 
51
73
  end
@@ -0,0 +1,60 @@
1
+ module Citron
2
+
3
+ # Ecapsulate a test case's teardown code.
4
+ #
5
+ class TestTeardown
6
+
7
+ #
8
+ # The test case to which this advice belong.
9
+ #
10
+ attr :context
11
+
12
+ #
13
+ # The setup procedures.
14
+ #
15
+ attr :procedures
16
+
17
+ #
18
+ # Initialize new Setup instance.
19
+ #
20
+ def initialize(context, &proc)
21
+ @context = context
22
+ @procedures = []
23
+
24
+ @procedures << proc if proc
25
+ end
26
+
27
+ #
28
+ # Copy the teardown for a new context.
29
+ #
30
+ def copy(context)
31
+ c = self.class.new(context)
32
+ c.procedures = procedures
33
+ c
34
+ end
35
+
36
+ #
37
+ # Run teardown procedure in test scope.
38
+ #
39
+ def call(scope)
40
+ procedures.each do |proc|
41
+ scope.instance_eval(&proc)
42
+ end
43
+ end
44
+
45
+ #
46
+ # Add a teardown procedure.
47
+ #
48
+ def add(&proc)
49
+ procedures << proc
50
+ end
51
+
52
+ protected
53
+
54
+ def procedures=(procedures)
55
+ @procedures = procedures
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -1,7 +1,10 @@
1
1
  module Citron
2
2
 
3
+ # To add global helpers to test case context, you can
4
+ # add that functionality to the Citron::World module.
3
5
  #
4
6
  class World < Module
5
7
  end
6
8
 
7
9
  end
10
+
@@ -0,0 +1,7 @@
1
+ testcase "basic test case" do
2
+
3
+ test "basic test" do
4
+ assert true
5
+ end
6
+
7
+ end
@@ -0,0 +1,10 @@
1
+ testcase "parametric tests" do
2
+
3
+ test "example parametric test" do |x|
4
+ x.assert.even?
5
+ end
6
+
7
+ ok 2
8
+ ok 4
9
+
10
+ end
@@ -0,0 +1,25 @@
1
+ testcase "Test Scope" do
2
+
3
+ def helper_method
4
+ "helped!"
5
+ end
6
+
7
+ test "can use helper method" do
8
+ helper_method.assert == "helped!"
9
+ end
10
+
11
+ context "sub-case inherits helpers" do
12
+
13
+ test "can use helper method" do
14
+ helper_method.assert == "helped!"
15
+ end
16
+
17
+ end
18
+
19
+ test "test can't access case methods" do
20
+ expect NameError do
21
+ method(:ok)
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,26 @@
1
+ testcase "Example of using setup in a testcase" do
2
+ setup "the number one" do
3
+ @x = 1
4
+ end
5
+
6
+ test "has setup without a topic" do
7
+ @x.assert == 1
8
+ end
9
+
10
+ context "sub-case inherits parent setup" do
11
+ test "has setup" do
12
+ @x.assert == 1
13
+ end
14
+ end
15
+
16
+ context "sub-case with setup override parent setup" do
17
+ setup "has setup" do
18
+ @y = 10
19
+ end
20
+
21
+ test "has setup" do
22
+ @x.assert == nil
23
+ @y.assert == 10
24
+ end
25
+ end
26
+ end