citron 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gemspec ADDED
@@ -0,0 +1,152 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+
5
+ Gem::Specification.new do |gemspec|
6
+
7
+ manifest = Dir.glob('manifest{,.txt)', File::FNM_CASEFOLD).first
8
+
9
+ scm = case
10
+ when File.directory?('.git')
11
+ :git
12
+ end
13
+
14
+ files = case
15
+ when manifest
16
+ File.readlines(manifest).
17
+ map{ |line| line.srtip }.
18
+ reject{ |line| line.empty? || line[0,1] == '#' }
19
+ when scm == :git
20
+ `git ls-files -z`.split("\0")
21
+ else
22
+ Dir.glob('{**/}{.*,*}') # TODO: be more specific using standard locations ?
23
+ end.select{ |path| File.file?(path) }
24
+
25
+ patterns = {
26
+ :bin_files => 'bin/*',
27
+ :lib_files => 'lib/{**/}*.rb',
28
+ :ext_files => 'ext/{**/}extconf.rb',
29
+ :doc_files => '*.{txt,rdoc,md,markdown,tt,textile}',
30
+ :test_files => '{test/{**/}*_test.rb,spec/{**/}*_spec.rb}'
31
+ }
32
+
33
+ glob_files = lambda { |pattern|
34
+ Dir.glob(pattern).select { |path|
35
+ File.file?(path) && files.include?(path)
36
+ }
37
+ }
38
+
39
+ #files = glob_files[patterns[:files]]
40
+
41
+ executables = glob_files[patterns[:bin_files]].map do |path|
42
+ File.basename(path)
43
+ end
44
+
45
+ extensions = glob_files[patterns[:ext_files]].map do |path|
46
+ File.basename(path)
47
+ end
48
+
49
+ metadata = YAML.load_file('.ruby')
50
+
51
+ # build-out the gemspec
52
+
53
+ case metadata['revision']
54
+ when 0
55
+ gemspec.name = metadata['name']
56
+ gemspec.version = metadata['version']
57
+ gemspec.summary = metadata['summary']
58
+ gemspec.description = metadata['description']
59
+
60
+ metadata['authors'].each do |author|
61
+ gemspec.authors << author['name']
62
+
63
+ if author.has_key?('email')
64
+ if gemspec.email
65
+ gemspec.email << author['email']
66
+ else
67
+ gemspec.email = [author['email']]
68
+ end
69
+ end
70
+ end
71
+
72
+ gemspec.licenses = metadata['licenses']
73
+
74
+ metadata['requirements'].each do |req|
75
+ name = req['name']
76
+ version = req['version']
77
+ groups = req['groups'] || []
78
+
79
+ if md = /^(.*?)([+-~])$/.match(version)
80
+ version = case md[2]
81
+ when '+' then ">= #{$1}"
82
+ when '-' then "< #{$1}"
83
+ when '~' then "~> #{$1}"
84
+ else version
85
+ end
86
+ end
87
+
88
+ #development = req['development']
89
+ #if development
90
+ # # populate development dependencies
91
+ # if gemspec.respond_to?(:add_development_dependency)
92
+ # gemspec.add_development_dependency(name,*version)
93
+ # else
94
+ # gemspec.add_dependency(name,*version)
95
+ # end
96
+ #else
97
+ # # populate runtime dependencies
98
+ # if gemspec.respond_to?(:add_runtime_dependency)
99
+ # gemspec.add_runtime_dependency(name,*version)
100
+ # else
101
+ # gemspec.add_dependency(name,*version)
102
+ # end
103
+ #end
104
+
105
+ if groups.empty? or groups.include?('runtime')
106
+ # populate runtime dependencies
107
+ if gemspec.respond_to?(:add_runtime_dependency)
108
+ gemspec.add_runtime_dependency(name,*version)
109
+ else
110
+ gemspec.add_dependency(name,*version)
111
+ end
112
+ else
113
+ # populate development dependencies
114
+ if gemspec.respond_to?(:add_development_dependency)
115
+ gemspec.add_development_dependency(name,*version)
116
+ else
117
+ gemspec.add_dependency(name,*version)
118
+ end
119
+ end
120
+ end
121
+
122
+ # convert external dependencies into a requirements
123
+ if metadata['external_dependencies']
124
+ ##gemspec.requirements = [] unless metadata['external_dependencies'].empty?
125
+ metadata['external_dependencies'].each do |req|
126
+ gemspec.requirements << req.to_s
127
+ end
128
+ end
129
+
130
+ # determine homepage from resources
131
+ homepage = metadata['resources'].find{ |key, url| key =~ /^home/ }
132
+ gemspec.homepage = homepage.last if homepage
133
+
134
+ gemspec.require_paths = metadata['load_path'] || ['lib']
135
+ gemspec.post_install_message = metadata['install_message']
136
+
137
+ # RubyGems specific metadata
138
+ gemspec.files = files
139
+ gemspec.extensions = extensions
140
+ gemspec.executables = executables
141
+
142
+ if Gem::VERSION < '1.7.'
143
+ gemspec.default_executable = gemspec.executables.first
144
+ end
145
+
146
+ gemspec.test_files = glob_files[patterns[:test_files]]
147
+
148
+ unless gemspec.files.include?('.document')
149
+ gemspec.extra_rdoc_files = glob_files[patterns[:doc_files]]
150
+ end
151
+ end
152
+ end
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .yardoc
2
+ doc
3
+ log
4
+ pkg
5
+ site
6
+ tmp
data/.ruby ADDED
@@ -0,0 +1,50 @@
1
+ ---
2
+ authors:
3
+ - name: Thomas Sawyer
4
+ email: transfire@gmail.com
5
+ copyrights:
6
+ - holder: Thomas Sawyer
7
+ year: "2011"
8
+ license: BSD-2-Clause
9
+ replacements: []
10
+
11
+ conflicts: []
12
+
13
+ requirements:
14
+ - name: test
15
+ - name: ae
16
+ - name: detroit
17
+ groups:
18
+ - build
19
+ development: true
20
+ - name: reap
21
+ groups:
22
+ - build
23
+ development: true
24
+ - name: qed
25
+ groups:
26
+ - test
27
+ development: true
28
+ dependencies: []
29
+
30
+ repositories:
31
+ - uri: git://github.com/proutils/citron.git
32
+ scm: git
33
+ name: upstream
34
+ resources:
35
+ home: http://rubyworks.github.com/citron
36
+ code: http://github.com/rubyworks/citron
37
+ load_path:
38
+ - lib
39
+ extra:
40
+ manifest: MANIFEST
41
+ alternatives: []
42
+
43
+ revision: 0
44
+ name: citron
45
+ title: Citron
46
+ suite: RubyWorks
47
+ summary: Classic Unit-style Test Framework
48
+ description: Citron is a unit testing framework with a classic test-case/test-unit style.
49
+ version: 0.1.0
50
+ date: "2011-07-29"
data/.yardopts ADDED
@@ -0,0 +1,7 @@
1
+ --output-dir site
2
+ --protected
3
+ --readme README.md
4
+ lib
5
+ -
6
+ [A-Z]*.*
7
+
data/Assembly ADDED
@@ -0,0 +1,46 @@
1
+ ---
2
+ github:
3
+ active: true
4
+
5
+ gem:
6
+ active: true
7
+
8
+ dnote:
9
+ labels: ~
10
+ output: log/NOTES.rdoc
11
+
12
+ yard:
13
+ yardopts: true
14
+
15
+ qed:
16
+ files : ~
17
+ #exclude : ~
18
+ #loadpath: ~
19
+ #requires: ~
20
+ #live : false
21
+ active : false
22
+
23
+ qedoc:
24
+ files : spec/
25
+ output: QED.rdoc
26
+ active: false
27
+
28
+ vclog:
29
+ output: log/ChangeLog.rdoc
30
+ active: false
31
+
32
+ email:
33
+ service: Email
34
+ file : ~
35
+ subject: ~
36
+ mailto :
37
+ - ruby-talk@ruby-lang.org
38
+ - rubyworks-mailinglist@googlegroups.com
39
+ from : <%= ENV['EMAIL_ACCOUNT'] %>
40
+ server : <%= ENV['EMAIL_SERVER'] %>
41
+ port : <%= ENV['EMAIL_PORT'] %>
42
+ account: <%= ENV['EMAIL_ACCOUNT'] %>
43
+ domain : <%= ENV['EMAIL_DOMAIN'] %>
44
+ login : <%= ENV['EMAIL_LOGIN'] %>
45
+ secure : <%= ENV['EMAIL_SECURE'] %>
46
+
data/COPYING.rdoc ADDED
@@ -0,0 +1,31 @@
1
+ = COPYRIGHT NOTICES
2
+
3
+ == Citron
4
+
5
+ Copyright:: (c) 2011 Thomas Sawyer, RubyWorks
6
+ License:: BSD-2-Clause
7
+ Website:: http://rubyworks.github.com/citron
8
+
9
+ Copyright 2011 Thomas Sawyer. All rights reserved.
10
+
11
+ Redistribution and use in source and binary forms, with or without
12
+ modification, are permitted provided that the following conditions are met:
13
+
14
+ 1. Redistributions of source code must retain the above copyright notice,
15
+ this list of conditions and the following disclaimer.
16
+
17
+ 2. Redistributions in binary form must reproduce the above copyright
18
+ notice, this list of conditions and the following disclaimer in the
19
+ documentation and/or other materials provided with the distribution.
20
+
21
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
22
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
23
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24
+ COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
28
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
data/LICENSE.txt ADDED
@@ -0,0 +1,25 @@
1
+ BSD 2 Clause License
2
+
3
+ Copyright 2011 Thomas Sawyer. All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice,
9
+ this list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
18
+ COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+
data/MANIFEST ADDED
@@ -0,0 +1,12 @@
1
+ #!mast .ruby .yaropts bin lib spec test [A-Z][A-Z]*
2
+ .ruby
3
+ lib/citron/test_advice.rb
4
+ lib/citron/test_case.rb
5
+ lib/citron/test_setup.rb
6
+ lib/citron/test_unit.rb
7
+ lib/citron.rb
8
+ PROFILE
9
+ LICENSE.txt
10
+ README.md
11
+ VERSION
12
+ COPYING.rdoc
data/PROFILE ADDED
@@ -0,0 +1,29 @@
1
+ ---
2
+ name : citron
3
+ title : Citron
4
+ suite : RubyWorks
5
+ summary: Classic Unit-style Test Framework
6
+ authors:
7
+ - Thomas Sawyer <transfire@gmail.com>
8
+
9
+ description:
10
+ Citron is a unit testing framework with a classic
11
+ test-case/test-unit style.
12
+
13
+ resources:
14
+ home: http://rubyworks.github.com/citron
15
+ code: http://github.com/rubyworks/citron
16
+
17
+ repositories:
18
+ upstream: git://github.com/proutils/citron.git
19
+
20
+ copyrights:
21
+ - 2011 Thomas Sawyer (BSD-2-Clause)
22
+
23
+ requirements:
24
+ - test
25
+ - ae
26
+ - detroit (build)
27
+ - reap (build)
28
+ - qed (test)
29
+
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # Citron
2
+
3
+ <table>
4
+ <tr><td><b>Author </b></td><td>Thomas Sawyer</td></tr>
5
+ <tr><td><b>License </b></td><td>FreeBSD</td></tr>
6
+ <tr><td><b>Copyright</b></td><td>(c) 2011 Thomas Sawyer, Rubyworks</td></tr>
7
+ </table>
8
+
9
+ ## Description
10
+
11
+ Citron is a classic unit test framework. It defines a simple
12
+ domain language for create classic-style tests.
13
+
14
+ ## Example
15
+
16
+ Here's a fun example.
17
+
18
+ ``` ruby
19
+ TestCase "Show them how to Beat It" do
20
+
21
+ # fail
22
+ test "show them how to funky" do
23
+ "funky".assert != "funky"
24
+ end
25
+
26
+ # pass
27
+ test "show them what's right" do
28
+ "right".assert == "right"
29
+ end
30
+
31
+ # error
32
+ test "no one wants to be defeated" do
33
+ raise SyntaxError
34
+ end
35
+
36
+ # todo
37
+ test "better do what you can" do
38
+ raise NotImplementedError
39
+ end
40
+
41
+ # omit
42
+ test "just beat it" do
43
+ e = NotImplementedError.new
44
+ e.set_assertion(true)
45
+ raise e
46
+ end
47
+
48
+ end
49
+ ```
50
+
51
+ ## License
52
+
53
+ Copyright (c) 2011 Thomas Sawyer, Rubyworks
54
+
55
+ Citron is distributed according to the terms of the FreeBSD license.
56
+
57
+ See COPYING.rd for details.
58
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/citron.rb ADDED
@@ -0,0 +1,23 @@
1
+ module Citron
2
+ $TEST_SUITE ||= []
3
+
4
+ require 'citron/test_case'
5
+ require 'citron/test_unit'
6
+ require 'citron/test_advice'
7
+ require 'citron/test_setup'
8
+ end
9
+
10
+ module Test
11
+ extend self
12
+
13
+ # Define a general test case.
14
+ def Case(label, &block)
15
+ $TEST_SUITE << Citron::TestCase.new(nil, :label=>label, &block)
16
+ end
17
+
18
+ alias :TestCase :Case
19
+ alias :test_case :Case
20
+ alias :case :Case
21
+ end
22
+
23
+ extend Test
@@ -0,0 +1,59 @@
1
+ module Citron
2
+
3
+ # Test Advice
4
+ class TestAdvice
5
+
6
+ # The test case to which this advice belongs.
7
+ #attr :context
8
+
9
+ #
10
+ attr :table
11
+
12
+ # New case instance.
13
+ def initialize
14
+ @table = Hash.new{ |h,k| h[k] = {} }
15
+ end
16
+
17
+ #
18
+ def initialize_copy(original)
19
+ @table = original.table.clone
20
+ end
21
+
22
+ #
23
+ def [](type)
24
+ @table[type.to_sym]
25
+ end
26
+
27
+ =begin
28
+ #
29
+ #def teardown=(procedure)
30
+ # @teardown = procedure
31
+ #end
32
+
33
+ # Setup.
34
+ def setup(scope=nil)
35
+ if scope
36
+ scope.instance_eval(&@setup)
37
+ else
38
+ @setup
39
+ end
40
+ end
41
+
42
+ # Teardown.
43
+ def teardown(scope=nil)
44
+ if scope
45
+ scope.instance_eval(&@teardown) if @teardown
46
+ else
47
+ @teardown
48
+ end
49
+ end
50
+
51
+ # Returns the description with newlines removed.
52
+ def to_s
53
+ description.gsub(/\n/, ' ')
54
+ end
55
+ =end
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,297 @@
1
+ #require 'citron/pending'
2
+ #require 'citron/test_context'
3
+ require 'citron/test_advice'
4
+ require 'citron/test_setup'
5
+
6
+ module Citron
7
+
8
+ # Test Case encapsulates a collection of
9
+ # unit tests organized into groups of contexts.
10
+ #
11
+ class TestCase
12
+
13
+ # The parent context in which this case resides.
14
+ attr :context
15
+
16
+ # Brief description of the test case.
17
+ attr :label
18
+
19
+ # List of tests and sub-cases.
20
+ attr :tests
21
+
22
+ # The setup and teardown advice.
23
+ attr :setup
24
+
25
+ # Advice are labeled procedures, such as before
26
+ # and after advice.
27
+ attr :advice
28
+
29
+ # Module for evaluating tests.
30
+ attr :scope
31
+
32
+ # A test case +target+ is a class or module.
33
+ #
34
+ # @param [TestSuite] context
35
+ # The parent case to which this case belongs.
36
+ #
37
+ def initialize(context, settings={}, &block)
38
+ if context
39
+ @context = context
40
+ @advice = context.advice.clone
41
+ else
42
+ @context = nil
43
+ @advice = TestAdvice.new
44
+ end
45
+
46
+ @label = settings[:label]
47
+ @setup = settings[:setup]
48
+ @skip = settings[:skip]
49
+
50
+ @tests = []
51
+
52
+ domain = DSL.new(self, &block)
53
+ @scope = Module.new
54
+ @scope.extend domain
55
+ end
56
+
57
+ #
58
+ def <<(test_object)
59
+ @tests << test_object
60
+ end
61
+
62
+ # Iterate over each test and subcase.
63
+ def each(&block)
64
+ tests.each(&block)
65
+ end
66
+
67
+ # Number of tests plus subcases.
68
+ def size
69
+ tests.size
70
+ end
71
+
72
+ # Subclasses of TestCase can override this to describe
73
+ # the type of test case they define.
74
+ def type
75
+ 'Case'
76
+ end
77
+
78
+ #
79
+ def to_s
80
+ "#{type}: " + @label.to_s
81
+ end
82
+
83
+ #
84
+ def skip?
85
+ @skip
86
+ end
87
+
88
+ #
89
+ def skip=(boolean)
90
+ @skip = !!boolean
91
+ end
92
+
93
+ # Run test in the context of this case.
94
+ #
95
+ # @param [TestProc] test
96
+ # The test unit to run.
97
+ #
98
+ def run(test, &block)
99
+ advice[:before].each do |matches, block|
100
+ if matches.all?{ |match| test.match?(match) }
101
+ scope.instance_exec(test, &block) #block.call(unit)
102
+ end
103
+ end
104
+
105
+ block.call
106
+
107
+ advice[:after].each do |matches, block|
108
+ if matches.all?{ |match| test.match?(match) }
109
+ scope.instance_exec(test, &block) #block.call(unit)
110
+ end
111
+ end
112
+ end
113
+
114
+ #
115
+ #--
116
+ # TODO: Change so that the scope is the DSL
117
+ # and ** includes the DSL of the context ** !!!
118
+ #++
119
+ #def scope
120
+ # @scope ||= (
121
+ # scope = Object.new
122
+ # scope.extend(domain)
123
+ # scope
124
+ # )
125
+ #end
126
+
127
+ #
128
+ class DSL < Module
129
+
130
+ #
131
+ def initialize(testcase, &code)
132
+ @_case = testcase
133
+ @_setup = testcase.setup
134
+
135
+ if testcase.context
136
+ extend(testcase.context.scope)
137
+ end
138
+
139
+ module_eval(&code)
140
+ end
141
+
142
+ # Create a sub-case.
143
+ #--
144
+ # @TODO: Instead of resuing TestCase can we have a TestContext
145
+ # that more generically mimics it's context context?
146
+ #++
147
+ def Context(label, &block)
148
+ settings = {
149
+ :label => label,
150
+ :setup => @_setup
151
+ }
152
+ testcase = TestCase.new(@_case, settings, &block)
153
+ @_case.tests << testcase
154
+ testcase
155
+ end
156
+ alias_method :context, :Context
157
+
158
+ # Create a test.
159
+ def Test(label=nil, &procedure)
160
+ settings = {
161
+ :label => label,
162
+ :setup => @_setup
163
+ }
164
+ testunit = TestUnit.new(@_case, settings, &procedure)
165
+ if procedure.arity == 0
166
+ @_case.tests << testunit
167
+ else
168
+ @_test = testunit
169
+ end
170
+ testunit
171
+ end
172
+ alias_method :test, :Test
173
+
174
+ #
175
+ #
176
+ #
177
+ def Ok(*args)
178
+ test = @_test
179
+ test.arguments = args
180
+ @_case << test
181
+ @_test = nil
182
+ return test
183
+ end
184
+
185
+ #
186
+ #
187
+ #
188
+ def No(*args)
189
+ test = @_test
190
+ test.arguments = args
191
+ test.negate = true
192
+ @_case << test
193
+ @_test = nil
194
+ return test
195
+ end
196
+
197
+ # Setup is used to set things up for each unit test.
198
+ # The setup procedure is run before each unit.
199
+ #
200
+ # @param [String] description
201
+ # A brief description of what the setup procedure sets-up.
202
+ #
203
+ def Setup(description=nil, &procedure)
204
+ if procedure
205
+ @_setup = TestSetup.new(@_case, description, &procedure)
206
+ end
207
+ end
208
+
209
+ alias_method :setup, :Setup
210
+
211
+ #alias_method :Concern, :Setup
212
+ #alias_method :concern, :Setup
213
+
214
+ #alias_method :Subject, :Setup
215
+ #alias_method :subject, :Setup
216
+
217
+ # Teardown procedure is used to clean-up after each unit test.
218
+ #
219
+ def Teardown(&procedure)
220
+ @_setup.teardown = procedure
221
+ end
222
+
223
+ alias_method :teardown, :Teardown
224
+
225
+ # Define a _complex_ before procedure. The #before method allows
226
+ # before procedures to be defined that are triggered by a match
227
+ # against the unit's target method name or _aspect_ description.
228
+ # This allows groups of tests to be defined that share special
229
+ # setup code.
230
+ #
231
+ # @example
232
+ # Method :puts do
233
+ # Test "standard output (@stdout)" do
234
+ # puts "Hello"
235
+ # end
236
+ #
237
+ # Before /@stdout/ do
238
+ # $stdout = StringIO.new
239
+ # end
240
+ #
241
+ # After /@stdout/ do
242
+ # $stdout = STDOUT
243
+ # end
244
+ # end
245
+ #
246
+ # @param [Array<Symbol,Regexp>] matches
247
+ # List of match critera that must _all_ be matched
248
+ # to trigger the before procedure.
249
+ #
250
+ def Before(*matches, &procedure)
251
+ @_case.advice[:before][matches] = procedure
252
+ end
253
+
254
+ alias_method :before, :Before
255
+
256
+ # Define a _complex_ after procedure. The #before method allows
257
+ # before procedures to be defined that are triggered by a match
258
+ # against the unit's target method name or _aspect_ description.
259
+ # This allows groups of tests to be defined that share special
260
+ # teardown code.
261
+ #
262
+ # @example
263
+ # Method :puts do
264
+ # Test "standard output (@stdout)" do
265
+ # puts "Hello"
266
+ # end
267
+ #
268
+ # Before /@stdout/ do
269
+ # $stdout = StringIO.new
270
+ # end
271
+ #
272
+ # After /@stdout/ do
273
+ # $stdout = STDOUT
274
+ # end
275
+ # end
276
+ #
277
+ # @param [Array<Symbol,Regexp>] matches
278
+ # List of match critera that must _all_ be matched
279
+ # to trigger the after procedure.
280
+ #
281
+ def After(*matches, &procedure)
282
+ @_case.advice[:after][matches] = procedure
283
+ end
284
+
285
+ alias_method :after, :After
286
+
287
+ # Mark a test or testcase to be omitted.
288
+ #
289
+ def Omit(test_obect)
290
+ test_object.omit = true
291
+ end
292
+
293
+ end
294
+
295
+ end
296
+
297
+ end
@@ -0,0 +1,51 @@
1
+ module Citron
2
+
3
+ # Test Setup/Concern - Setup and Teardown code.
4
+ class TestSetup
5
+
6
+ # The test case to which this advice belong.
7
+ attr :context
8
+
9
+ # A brief description of this concern.
10
+ attr :label
11
+
12
+ # The setup procedure.
13
+ attr :setup
14
+
15
+ # The teardown procedure.
16
+ attr :teardown
17
+
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 = []
24
+ end
25
+
26
+ #
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
36
+ end
37
+
38
+ # Teardown.
39
+ def run_teardown(scope)
40
+ teardown.each do |proc|
41
+ scope.instance_eval(&proc)
42
+ end
43
+ end
44
+
45
+ # Returns the description with newlines removed.
46
+ def to_s
47
+ label.gsub(/\n/, ' ')
48
+ end
49
+ end
50
+
51
+ end
@@ -0,0 +1,123 @@
1
+ module Citron
2
+
3
+ #
4
+ class TestUnit
5
+
6
+ # New unit test procedure.
7
+ #
8
+ def initialize(context, options={}, &procedure)
9
+ @context = context
10
+
11
+ @setup = options[:setup]
12
+ @label = options[:label]
13
+ @skip = options[:skip]
14
+
15
+ @procedure = procedure
16
+ @tested = false
17
+ end
18
+
19
+ public
20
+
21
+ # The parent testcase to which this test belongs.
22
+ attr :context
23
+
24
+ #
25
+ alias :parent :context
26
+
27
+ # Setup and teardown procedures.
28
+ attr :setup
29
+
30
+ # Description of test.
31
+ attr :label
32
+
33
+ # Test procedure, in which test assertions should be made.
34
+ attr :procedure
35
+
36
+ # The before and after advice from the context.
37
+ def advice
38
+ context.advice
39
+ end
40
+
41
+ #
42
+ def type
43
+ 'Unit'
44
+ end
45
+
46
+ #
47
+ def skip? ; @skip ; end
48
+
49
+ #
50
+ def skip=(boolean)
51
+ @skip = !!boolean
52
+ end
53
+
54
+ #
55
+ def tested?
56
+ @tested
57
+ end
58
+
59
+ #
60
+ def tested=(boolean)
61
+ @tested = boolean
62
+ end
63
+
64
+ #
65
+ def to_s
66
+ label.to_s
67
+ end
68
+
69
+ #
70
+ def setup
71
+ @setup
72
+ end
73
+
74
+ #
75
+ alias :subtext :setup
76
+
77
+ #
78
+ def scope
79
+ context.scope
80
+ end
81
+
82
+ #
83
+ def arguments
84
+ @arguments
85
+ end
86
+
87
+ #
88
+ def arguments=(args)
89
+ @arguments = args
90
+ end
91
+
92
+ # TODO: how to handle negated tests?
93
+ def negate
94
+ @negate
95
+ end
96
+
97
+ #
98
+ def negate=(boolean)
99
+ @negate = !!boolean
100
+ end
101
+
102
+ #
103
+ def to_proc
104
+ lambda{ call }
105
+ end
106
+
107
+ #
108
+ def match?(match)
109
+ match == target || match === description
110
+ end
111
+
112
+ #
113
+ def call
114
+ context.run(self) do
115
+ setup.run_setup(scope) if setup
116
+ scope.instance_exec(*arguments, &procedure)
117
+ setup.run_teardown(scope) if setup
118
+ end
119
+ end
120
+
121
+ end
122
+
123
+ end
@@ -0,0 +1,30 @@
1
+ TestCase "Show them how to Beat It" do
2
+
3
+ # will fail
4
+ test "show them how to funky" do
5
+ "funky".assert != "funky"
6
+ end
7
+
8
+ # will pass
9
+ test "show them what's right" do
10
+ "right".assert == "right"
11
+ end
12
+
13
+ # will error
14
+ test "no one wants to be defeated" do
15
+ raise SyntaxError
16
+ end
17
+
18
+ # pending
19
+ test "better do what you can" do
20
+ raise NotImplementedError
21
+ end
22
+
23
+ # omit
24
+ test "just beat it" do
25
+ e = NotImplementedError.new
26
+ e.set_assertion(true)
27
+ raise e
28
+ end
29
+
30
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: citron
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Thomas Sawyer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-07-29 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: test
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: ae
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: detroit
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: reap
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: qed
61
+ prerelease: false
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :development
69
+ version_requirements: *id005
70
+ description: Citron is a unit testing framework with a classic test-case/test-unit style.
71
+ email:
72
+ - transfire@gmail.com
73
+ executables: []
74
+
75
+ extensions: []
76
+
77
+ extra_rdoc_files:
78
+ - LICENSE.txt
79
+ - COPYING.rdoc
80
+ - README.md
81
+ files:
82
+ - .gemspec
83
+ - .gitignore
84
+ - .ruby
85
+ - .yardopts
86
+ - Assembly
87
+ - COPYING.rdoc
88
+ - LICENSE.txt
89
+ - MANIFEST
90
+ - PROFILE
91
+ - README.md
92
+ - VERSION
93
+ - lib/citron.rb
94
+ - lib/citron/test_advice.rb
95
+ - lib/citron/test_case.rb
96
+ - lib/citron/test_setup.rb
97
+ - lib/citron/test_unit.rb
98
+ - try/case_example.rb
99
+ homepage: http://rubyworks.github.com/citron
100
+ licenses: []
101
+
102
+ post_install_message:
103
+ rdoc_options: []
104
+
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: "0"
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: "0"
119
+ requirements: []
120
+
121
+ rubyforge_project:
122
+ rubygems_version: 1.8.2
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: Classic Unit-style Test Framework
126
+ test_files: []
127
+