spectroscope 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/.ruby +53 -0
- data/COPYING.rdoc +36 -0
- data/HISTORY.md +10 -0
- data/LICENSE.txt +25 -0
- data/README.md +77 -0
- data/lib/spectroscope.rb +68 -0
- data/lib/spectroscope.yml +53 -0
- data/lib/spectroscope/context.rb +431 -0
- data/lib/spectroscope/example.rb +243 -0
- data/lib/spectroscope/hooks.rb +104 -0
- data/lib/spectroscope/world.rb +7 -0
- data/spec/hooks_spec.rb +83 -0
- data/spec/let_spec.rb +34 -0
- data/spec/scope_spec.rb +15 -0
- data/spec/shared_example_spec.rb +34 -0
- data/spec/subject_spec.rb +26 -0
- metadata +128 -0
data/.ruby
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
---
|
2
|
+
source:
|
3
|
+
- Profile
|
4
|
+
authors:
|
5
|
+
- name: Trans
|
6
|
+
email: transfire@gmail.com
|
7
|
+
copyrights:
|
8
|
+
- holder: Rubyworks
|
9
|
+
year: '2012'
|
10
|
+
license: BSD-2-Clause
|
11
|
+
requirements:
|
12
|
+
- name: rubytest
|
13
|
+
- name: detroit
|
14
|
+
groups:
|
15
|
+
- build
|
16
|
+
development: true
|
17
|
+
- name: reap
|
18
|
+
groups:
|
19
|
+
- build
|
20
|
+
development: true
|
21
|
+
- name: mast
|
22
|
+
groups:
|
23
|
+
- build
|
24
|
+
development: true
|
25
|
+
- name: ae
|
26
|
+
groups:
|
27
|
+
- test
|
28
|
+
development: true
|
29
|
+
dependencies: []
|
30
|
+
alternatives: []
|
31
|
+
conflicts: []
|
32
|
+
repositories:
|
33
|
+
- uri: git://github.com/proutils/spectroscope.git
|
34
|
+
scm: git
|
35
|
+
name: upstream
|
36
|
+
resources:
|
37
|
+
home: http://rubyworks.github.com/spectroscope
|
38
|
+
code: http://github.com/rubyworks/spectroscope
|
39
|
+
mail: http://groups.google.com/groups/rubyworks-mailinglist
|
40
|
+
extra: {}
|
41
|
+
load_path:
|
42
|
+
- lib
|
43
|
+
revision: 0
|
44
|
+
name: spectroscope
|
45
|
+
title: Spectroscope
|
46
|
+
version: 0.1.0
|
47
|
+
summary: RSpec-like BDD on RubyTest
|
48
|
+
created: '2012-02-22'
|
49
|
+
description: Spectroscope is a BDD framework built on RubyTest designed to emulate
|
50
|
+
RSpec in most respects. It is assertion framework independent so any number of assertion
|
51
|
+
systems can be used, such as Assay or AE.
|
52
|
+
organization: RubyWorks
|
53
|
+
date: '2012-02-23'
|
data/COPYING.rdoc
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
= COPYRIGHT
|
2
|
+
|
3
|
+
== NOTICES
|
4
|
+
|
5
|
+
=== Spectra
|
6
|
+
|
7
|
+
Copyright:: (c) 2011 RubyWorks
|
8
|
+
License:: BSD-2-Clause
|
9
|
+
Website:: http://rubyworks.github.com/spectra
|
10
|
+
|
11
|
+
|
12
|
+
== LICENSES
|
13
|
+
|
14
|
+
=== BSD-2-Clause
|
15
|
+
|
16
|
+
Redistribution and use in source and binary forms, with or without
|
17
|
+
modification, are permitted provided that the following conditions are met:
|
18
|
+
|
19
|
+
1. Redistributions of source code must retain the above copyright notice,
|
20
|
+
this list of conditions and the following disclaimer.
|
21
|
+
|
22
|
+
2. Redistributions in binary form must reproduce the above copyright
|
23
|
+
notice, this list of conditions and the following disclaimer in the
|
24
|
+
documentation and/or other materials provided with the distribution.
|
25
|
+
|
26
|
+
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
27
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
28
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
29
|
+
COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
30
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
31
|
+
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
32
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
33
|
+
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
34
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
35
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
36
|
+
|
data/HISTORY.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Spectra, Copyright 2012 Rubyworks. All rights reserved.
|
2
|
+
|
3
|
+
BSD-2-Clause License
|
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/README.md
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# Spectroscope
|
2
|
+
|
3
|
+
FreeBSD Copyright (c) 2012 Rubyworks
|
4
|
+
|
5
|
+
[Homepage](http://rubyworks.github.com/spectroscope) /
|
6
|
+
[Report Issue](http://github.com/rubyworks/spectroscope/issues) /
|
7
|
+
[Source Code](http://github.com/rubyworks/spectroscope)
|
8
|
+
|
9
|
+
[](http://travis-ci.org/rubyworks/spectroscope)
|
10
|
+
|
11
|
+
|
12
|
+
## Description
|
13
|
+
|
14
|
+
Spectroscope is an RSpec-style BDD framework that runs on top of the [Ruby Test](http://rubyworks.github.com/rubytest),
|
15
|
+
the Ruby universal test harness. It supports all of RSpec's syntax, with a
|
16
|
+
few exceptions.
|
17
|
+
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
|
21
|
+
$ gem install spectroscope
|
22
|
+
|
23
|
+
|
24
|
+
## Instruction
|
25
|
+
|
26
|
+
### Writing Specifications
|
27
|
+
|
28
|
+
Specifications are written as block of `describe` and `it` definitions.
|
29
|
+
|
30
|
+
Here's RSpec classic example:
|
31
|
+
|
32
|
+
describe Order do
|
33
|
+
it "sums the prices of its line items" do
|
34
|
+
order = Order.new
|
35
|
+
order.add_entry(LineItem.new(:item => Item.new(
|
36
|
+
:price => Money.new(1.11, :USD)
|
37
|
+
)))
|
38
|
+
order.add_entry(LineItem.new(:item => Item.new(
|
39
|
+
:price => Money.new(2.22, :USD),
|
40
|
+
:quantity => 2
|
41
|
+
)))
|
42
|
+
order.total.should eq(Money.new(5.55, :USD))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
Spectroscope only handle the specification structure, it does not provide an
|
47
|
+
assertions system. For that use any of a number of available libraries,
|
48
|
+
such [Assay-RSpec](http://rubyworks.github.com/assay-rspec) or [AE](http://rubyworks.github.com/ae).
|
49
|
+
You can require these in a helper script, or in Ruby Test configuration (see below).
|
50
|
+
|
51
|
+
### Running Specifications
|
52
|
+
|
53
|
+
Running specification is done with the `rubytest` command line utility.
|
54
|
+
|
55
|
+
$ rubytest -Ilib -rae/should spec/*_spec.rb
|
56
|
+
|
57
|
+
To make things simpler, create a `.test` configuration file.
|
58
|
+
|
59
|
+
require 'ae/should'
|
60
|
+
|
61
|
+
Test.run :default do |run|
|
62
|
+
run.files << 'spec/*_spec.rb'
|
63
|
+
end
|
64
|
+
|
65
|
+
Then simply use:
|
66
|
+
|
67
|
+
$ rubytest
|
68
|
+
|
69
|
+
|
70
|
+
## Copyrights
|
71
|
+
|
72
|
+
Copyright (c) 2012 Rubyworks
|
73
|
+
|
74
|
+
Spectroscope is distributable according to the terms of the **FreeBSD** license.
|
75
|
+
|
76
|
+
See COPYING.rdoc for details.
|
77
|
+
|
data/lib/spectroscope.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
$TEST_SUITE ||= []
|
2
|
+
|
3
|
+
module Spectroscope
|
4
|
+
|
5
|
+
require 'spectroscope/world'
|
6
|
+
require 'spectroscope/hooks'
|
7
|
+
require 'spectroscope/example'
|
8
|
+
require 'spectroscope/context'
|
9
|
+
|
10
|
+
# The DSL module extends the toplevel.
|
11
|
+
#
|
12
|
+
module DSL
|
13
|
+
|
14
|
+
#
|
15
|
+
# Define an example group.
|
16
|
+
#
|
17
|
+
def describe(topic, *tags, &block)
|
18
|
+
settings = {}
|
19
|
+
|
20
|
+
if Class === topic
|
21
|
+
settings[:subject] = topic
|
22
|
+
settings[:label] = topic.name
|
23
|
+
else
|
24
|
+
settings[:label] = topic
|
25
|
+
end
|
26
|
+
|
27
|
+
$TEST_SUITE << Spectroscope::Context.new(settings, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
#
|
32
|
+
#
|
33
|
+
def shared_examples_for(label, &block)
|
34
|
+
Spectroscope.shared_examples[label] = block
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Store for shared examples.
|
40
|
+
#
|
41
|
+
# @return [Hash] shared examples
|
42
|
+
#
|
43
|
+
def self.shared_examples
|
44
|
+
@shared_examples ||= {}
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Access to project metadata.
|
49
|
+
#
|
50
|
+
# @return [Hash] metadata
|
51
|
+
#
|
52
|
+
def self.metadata
|
53
|
+
@metadata ||= (
|
54
|
+
require 'yaml'
|
55
|
+
YAML.load_file(File.dirname(__FILE__), '/spectrascope.yml')
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# If constant is missing, check for it in project metadata.
|
61
|
+
#
|
62
|
+
def self.const_missing(name)
|
63
|
+
metadata[name.to_s.downcase] || super(name)
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
extend Spectroscope::DSL
|
@@ -0,0 +1,53 @@
|
|
1
|
+
---
|
2
|
+
source:
|
3
|
+
- Profile
|
4
|
+
authors:
|
5
|
+
- name: Trans
|
6
|
+
email: transfire@gmail.com
|
7
|
+
copyrights:
|
8
|
+
- holder: Rubyworks
|
9
|
+
year: '2012'
|
10
|
+
license: BSD-2-Clause
|
11
|
+
requirements:
|
12
|
+
- name: rubytest
|
13
|
+
- name: detroit
|
14
|
+
groups:
|
15
|
+
- build
|
16
|
+
development: true
|
17
|
+
- name: reap
|
18
|
+
groups:
|
19
|
+
- build
|
20
|
+
development: true
|
21
|
+
- name: mast
|
22
|
+
groups:
|
23
|
+
- build
|
24
|
+
development: true
|
25
|
+
- name: ae
|
26
|
+
groups:
|
27
|
+
- test
|
28
|
+
development: true
|
29
|
+
dependencies: []
|
30
|
+
alternatives: []
|
31
|
+
conflicts: []
|
32
|
+
repositories:
|
33
|
+
- uri: git://github.com/proutils/spectroscope.git
|
34
|
+
scm: git
|
35
|
+
name: upstream
|
36
|
+
resources:
|
37
|
+
home: http://rubyworks.github.com/spectroscope
|
38
|
+
code: http://github.com/rubyworks/spectroscope
|
39
|
+
mail: http://groups.google.com/groups/rubyworks-mailinglist
|
40
|
+
extra: {}
|
41
|
+
load_path:
|
42
|
+
- lib
|
43
|
+
revision: 0
|
44
|
+
name: spectroscope
|
45
|
+
title: Spectroscope
|
46
|
+
version: 0.1.0
|
47
|
+
summary: RSpec-like BDD on RubyTest
|
48
|
+
created: '2012-02-22'
|
49
|
+
description: Spectroscope is a BDD framework built on RubyTest designed to emulate
|
50
|
+
RSpec in most respects. It is assertion framework independent so any number of assertion
|
51
|
+
systems can be used, such as Assay or AE.
|
52
|
+
organization: RubyWorks
|
53
|
+
date: '2012-02-23'
|
@@ -0,0 +1,431 @@
|
|
1
|
+
module Spectroscope
|
2
|
+
|
3
|
+
# This is the BDD form of a test case. It encapsulates a collection
|
4
|
+
# of examples.
|
5
|
+
#
|
6
|
+
# This is the `describe` in your specs.
|
7
|
+
#
|
8
|
+
class Context
|
9
|
+
|
10
|
+
#
|
11
|
+
# The parent context in which this describe resides.
|
12
|
+
#
|
13
|
+
attr :parent
|
14
|
+
|
15
|
+
#
|
16
|
+
# A description of the describe clause.
|
17
|
+
#
|
18
|
+
attr :label
|
19
|
+
|
20
|
+
#
|
21
|
+
# A target class, if any.
|
22
|
+
#
|
23
|
+
attr :subject
|
24
|
+
|
25
|
+
#
|
26
|
+
# Array and/or metadata Hash of tags.
|
27
|
+
#
|
28
|
+
attr :tags
|
29
|
+
|
30
|
+
#
|
31
|
+
# List of examples and sub-specifications.
|
32
|
+
#
|
33
|
+
attr :specs
|
34
|
+
|
35
|
+
#
|
36
|
+
# The before and after hooks.
|
37
|
+
#
|
38
|
+
attr :hooks
|
39
|
+
|
40
|
+
#
|
41
|
+
# Skip critera.
|
42
|
+
#
|
43
|
+
# @return [Array<String,Proc>]
|
44
|
+
#
|
45
|
+
attr :skips
|
46
|
+
|
47
|
+
#
|
48
|
+
# Omit criteria.
|
49
|
+
#
|
50
|
+
# @return [Array<String,Proc>]
|
51
|
+
#
|
52
|
+
attr :omits
|
53
|
+
|
54
|
+
#
|
55
|
+
# DSL module for evaluating `describe` blocks.
|
56
|
+
#
|
57
|
+
attr :scope
|
58
|
+
|
59
|
+
#
|
60
|
+
# A test case +target+ is a class or module.
|
61
|
+
#
|
62
|
+
def initialize(settings={}, &block)
|
63
|
+
@parent = settings[:parent]
|
64
|
+
@subject = settings[:subject]
|
65
|
+
@label = settings[:label]
|
66
|
+
@tags = settings[:tags]
|
67
|
+
#@skips = settings[:skips]
|
68
|
+
#@hooks = settings[:hooks]
|
69
|
+
|
70
|
+
if @parent
|
71
|
+
@hooks = parent.hooks.clone
|
72
|
+
@skips = parent.skips.clone
|
73
|
+
@omits = parent.omits.clone
|
74
|
+
else
|
75
|
+
@hooks = Hooks.new
|
76
|
+
@skips = []
|
77
|
+
@omits = []
|
78
|
+
end
|
79
|
+
|
80
|
+
@specs = []
|
81
|
+
|
82
|
+
@scope = Scope.new(self)
|
83
|
+
|
84
|
+
evaluate(&block)
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# Evalute a block of code in the context of the Context's scope.
|
89
|
+
# When finished it iterates over `omits` and `skips`, removing and
|
90
|
+
# marks examples to be skipped respectively.
|
91
|
+
#
|
92
|
+
def evaluate(&block)
|
93
|
+
@scope.module_eval(&block)
|
94
|
+
|
95
|
+
specs.delete_if do |spec|
|
96
|
+
omits.any?{ |reason, block| block.call(spec) }
|
97
|
+
end
|
98
|
+
|
99
|
+
specs.each do |spec|
|
100
|
+
skips.each do |reason, block|
|
101
|
+
if spec.match?(match)
|
102
|
+
spec.skip = reason
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
# Shared runtime scope for specs.
|
110
|
+
#
|
111
|
+
def it_scope
|
112
|
+
@it_scope ||= Example::Scope.new(self)
|
113
|
+
end
|
114
|
+
|
115
|
+
#
|
116
|
+
# Add `it` or sub-`describe` to group.
|
117
|
+
#
|
118
|
+
def <<(spec)
|
119
|
+
@specs << spec
|
120
|
+
end
|
121
|
+
|
122
|
+
#
|
123
|
+
# Iterate over each test and subcase.
|
124
|
+
#
|
125
|
+
def each(&block)
|
126
|
+
specs.each(&block)
|
127
|
+
end
|
128
|
+
|
129
|
+
#
|
130
|
+
# Run before-all and after-all advice around yeilding
|
131
|
+
# to test runss.
|
132
|
+
#
|
133
|
+
def call
|
134
|
+
hooks.run(self, :before, :all, it_scope)
|
135
|
+
yield
|
136
|
+
hooks.run(self, :after, :all, it_scope)
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
# Number of specs plus subcases.
|
141
|
+
#
|
142
|
+
def size
|
143
|
+
specs.size
|
144
|
+
end
|
145
|
+
|
146
|
+
#
|
147
|
+
# Ruby Test supports `type` to describe the nature of
|
148
|
+
# the underlying test system.
|
149
|
+
#
|
150
|
+
def type
|
151
|
+
'describe'
|
152
|
+
end
|
153
|
+
|
154
|
+
alias :inspect :to_s
|
155
|
+
|
156
|
+
#
|
157
|
+
# Returns the subject/label as string.
|
158
|
+
#
|
159
|
+
def to_s
|
160
|
+
label.to_s
|
161
|
+
end
|
162
|
+
|
163
|
+
#
|
164
|
+
# Skip this group?
|
165
|
+
#
|
166
|
+
def skip?
|
167
|
+
@skip
|
168
|
+
end
|
169
|
+
|
170
|
+
#
|
171
|
+
#
|
172
|
+
#
|
173
|
+
def skip=(reason)
|
174
|
+
@skip = reason
|
175
|
+
end
|
176
|
+
|
177
|
+
#
|
178
|
+
# Run test in the parent of this case.
|
179
|
+
#
|
180
|
+
# @param [TestProc] test
|
181
|
+
# The test unit to run.
|
182
|
+
#
|
183
|
+
def run(test, &block)
|
184
|
+
#hooks[:before].each do |match, block|
|
185
|
+
# next if Symbol == match
|
186
|
+
# if test.match?(match)
|
187
|
+
# scope.instance_exec(test, &block) #block.call(unit)
|
188
|
+
# end
|
189
|
+
#end
|
190
|
+
|
191
|
+
block.call
|
192
|
+
|
193
|
+
#hooks[:after].each do |match, block|
|
194
|
+
# next if Symbol == match
|
195
|
+
# if test.match?(match)
|
196
|
+
# scope.instance_exec(test, &block) #block.call(unit)
|
197
|
+
# end
|
198
|
+
#end
|
199
|
+
end
|
200
|
+
|
201
|
+
# Context scope is used for defining sepcifications.
|
202
|
+
#
|
203
|
+
class Scope < World
|
204
|
+
|
205
|
+
#
|
206
|
+
# Setup new evaluation scope.
|
207
|
+
#
|
208
|
+
def initialize(group)
|
209
|
+
@_group = group
|
210
|
+
@_hooks = group.hooks
|
211
|
+
@_skips = group.skips
|
212
|
+
@_omits = group.omits
|
213
|
+
|
214
|
+
if group.parent
|
215
|
+
include(group.parent.scope)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
#
|
220
|
+
# Create a new sub-specification.
|
221
|
+
#
|
222
|
+
def describe(topic, *tags, &block)
|
223
|
+
settings = {}
|
224
|
+
settings[:parent] = @_group
|
225
|
+
settings[:subject] = @_group.subject
|
226
|
+
settings[:tags] = tags
|
227
|
+
|
228
|
+
if Class === topic
|
229
|
+
settings[:subject] = topic
|
230
|
+
settings[:label] = topic.name
|
231
|
+
else
|
232
|
+
settings[:label] = topic
|
233
|
+
end
|
234
|
+
|
235
|
+
group = Context.new(settings, &block)
|
236
|
+
|
237
|
+
@_group.specs << group
|
238
|
+
|
239
|
+
return group
|
240
|
+
end
|
241
|
+
|
242
|
+
alias_method :context, :describe
|
243
|
+
|
244
|
+
#
|
245
|
+
# Create an example behavior.
|
246
|
+
#
|
247
|
+
# If tags or keys are given, so must a label.
|
248
|
+
#
|
249
|
+
def it(label=nil, *tags, &procedure)
|
250
|
+
keys = (Hash===tags ? tags.pop : {})
|
251
|
+
|
252
|
+
settings = {
|
253
|
+
:parent => @_group,
|
254
|
+
:hooks => @_hooks,
|
255
|
+
:skips => @_skips,
|
256
|
+
:omits => @_omits,
|
257
|
+
:topic => @_topic,
|
258
|
+
:label => label,
|
259
|
+
:tags => tags,
|
260
|
+
:keys => keys
|
261
|
+
}
|
262
|
+
|
263
|
+
spec = Example.new(settings, &procedure)
|
264
|
+
|
265
|
+
@_group.specs << spec
|
266
|
+
|
267
|
+
spec
|
268
|
+
end
|
269
|
+
|
270
|
+
#
|
271
|
+
#
|
272
|
+
#
|
273
|
+
alias_method :example, :it
|
274
|
+
|
275
|
+
#
|
276
|
+
# Define before procedure.
|
277
|
+
#
|
278
|
+
# @example
|
279
|
+
# describe '#puts' do
|
280
|
+
# it "gives standard output" do
|
281
|
+
# puts "Hello"
|
282
|
+
# end
|
283
|
+
#
|
284
|
+
# before do
|
285
|
+
# $stdout = StringIO.new
|
286
|
+
# end
|
287
|
+
#
|
288
|
+
# after do
|
289
|
+
# $stdout = STDOUT
|
290
|
+
# end
|
291
|
+
# end
|
292
|
+
#
|
293
|
+
# @param [Symbol] which
|
294
|
+
# Must be either `:all` or `:each`, the later being the default.
|
295
|
+
#
|
296
|
+
# @param [Array<Symbol>] tags
|
297
|
+
# List of match critera that must be matched
|
298
|
+
# against tags to trigger the before procedure.
|
299
|
+
#
|
300
|
+
def before(which=:each, *tags, &procedure)
|
301
|
+
@_hooks.add(:before, which, *tags, &procedure)
|
302
|
+
end
|
303
|
+
|
304
|
+
#
|
305
|
+
# Define a _complex_ after procedure. The #before method allows
|
306
|
+
# before procedures to be defined that are triggered by a match
|
307
|
+
# against the unit's target method name or _aspect_ description.
|
308
|
+
# This allows groups of specs to be defined that share special
|
309
|
+
# teardown code.
|
310
|
+
#
|
311
|
+
# @example
|
312
|
+
# describe '#puts' do
|
313
|
+
# it "gives standard output (@stdout)" do
|
314
|
+
# puts "Hello"
|
315
|
+
# end
|
316
|
+
#
|
317
|
+
# before do
|
318
|
+
# $stdout = StringIO.new
|
319
|
+
# end
|
320
|
+
#
|
321
|
+
# after do
|
322
|
+
# $stdout = STDOUT
|
323
|
+
# end
|
324
|
+
# end
|
325
|
+
#
|
326
|
+
# @param [Symbol] which
|
327
|
+
# Must be either `:all` or `:each`, the later being the default.
|
328
|
+
#
|
329
|
+
# @param [Array<Symbol>] tags
|
330
|
+
# List of match critera that must be matched
|
331
|
+
# to trigger the after procedure.
|
332
|
+
#
|
333
|
+
def after(which=:each, *tags, &procedure)
|
334
|
+
@_hooks.add(:after, which, *tags, &procedure)
|
335
|
+
end
|
336
|
+
|
337
|
+
#
|
338
|
+
# Mark specs or sub-cases to be skipped.
|
339
|
+
#
|
340
|
+
# @example
|
341
|
+
# it "should do something" do
|
342
|
+
# ...
|
343
|
+
# end
|
344
|
+
# skip(/something/, "reason for skipping") if jruby?
|
345
|
+
#
|
346
|
+
def skip(reason, &block)
|
347
|
+
@_skips << [reason, block]
|
348
|
+
end
|
349
|
+
|
350
|
+
#
|
351
|
+
# Mark specs or sub-cases to be omitted. Omitting a test is different
|
352
|
+
# from skipping, in tha the later is still sent up to the test harness,
|
353
|
+
# where as omitted tests never get added at all.
|
354
|
+
#
|
355
|
+
# @example
|
356
|
+
# it "should do something" do
|
357
|
+
# ...
|
358
|
+
# end
|
359
|
+
# omit(/something/) if jruby?
|
360
|
+
#
|
361
|
+
def omit(reason=true, &block)
|
362
|
+
@_omits << [reason, block]
|
363
|
+
end
|
364
|
+
|
365
|
+
#
|
366
|
+
#
|
367
|
+
#
|
368
|
+
def let(name, &block)
|
369
|
+
define_method(name) do
|
370
|
+
#_let[name] ||= block.call
|
371
|
+
@_let.fetch(name){ |k| @_let[k] = instance_eval(&block) }
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
#
|
376
|
+
#
|
377
|
+
#
|
378
|
+
def let!(name, &block)
|
379
|
+
let(name, &block)
|
380
|
+
before { __send__(name) }
|
381
|
+
end
|
382
|
+
|
383
|
+
#
|
384
|
+
#
|
385
|
+
#
|
386
|
+
def subject(topic=nil, &block)
|
387
|
+
@_topic = topic
|
388
|
+
define_method(:subject, &block)
|
389
|
+
end
|
390
|
+
|
391
|
+
#
|
392
|
+
# Subject-oriented example.
|
393
|
+
#
|
394
|
+
# RSpec itself wraps this whole thing in another `describe(invocation)`
|
395
|
+
# clause, but that seems completely extraneous.
|
396
|
+
#
|
397
|
+
def its(invocation, &block)
|
398
|
+
case invocation
|
399
|
+
when Symbol
|
400
|
+
it(invocation.to_s) do
|
401
|
+
subject.__send__(invocation).instance_eval(&block)
|
402
|
+
end
|
403
|
+
else
|
404
|
+
it(invocation.to_s) do
|
405
|
+
#eval("subject.#{invocation}", binding).instance_eval(&block)
|
406
|
+
calls = invocation.to_s.split('.')
|
407
|
+
calls.inject(subject){ |s,m| s.__send__(invocation) }.instance_eval(&block)
|
408
|
+
end
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
#
|
413
|
+
#
|
414
|
+
#
|
415
|
+
#def shared_examples_for(label, &block)
|
416
|
+
# @_shared_examples[label] = block
|
417
|
+
#end
|
418
|
+
|
419
|
+
#
|
420
|
+
#
|
421
|
+
#
|
422
|
+
def it_behaves_like(label)
|
423
|
+
proc = Spectroscope.shared_examples[label]
|
424
|
+
module_eval(&proc)
|
425
|
+
end
|
426
|
+
|
427
|
+
end
|
428
|
+
|
429
|
+
end
|
430
|
+
|
431
|
+
end
|