two-step 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bbcd87fc9e0ece6a20bedfe6664901250297a175
4
+ data.tar.gz: 2beecdace7f917e4773d529b0e96377c6d9ef938
5
+ SHA512:
6
+ metadata.gz: 03775343f6f5fb263872e1cfcc2ae48e008e7693f0e3e4373eec8b41827ad4018bd51563a0adcb0cb90e09689aa491f8c877c8fa0259e39ae9d404be008ed3fa
7
+ data.tar.gz: cba2e257f83704719a484584f257e64df337dd2585aa93dcbbdbb3c62cfc5556ce699176db2950c6a68d3dbc183e7d02fc408cb52fa82aeda198542d80041b0c
@@ -0,0 +1,116 @@
1
+ # Two Step
2
+ ## ( or: why would I want to relearn how to write specs? )
3
+
4
+ Two-Step allows you to chain examples into a series of steps that run
5
+ in sequence and which stop when a step fails. It's often incredibly
6
+ useful to be able to aseemble a series of tests that should all pass,
7
+ but where completely isolating them is less than sensible.
8
+
9
+ ( Two Step is the RSpec 2 compatible version of RSpec Steps - which can be
10
+ found here: https://github.com/LRDesign/rspec-steps )
11
+
12
+ One excellent example is web site integration tests. With RSpec steps you can
13
+ do:
14
+
15
+ steps "Login and change password" do
16
+ it "should show the login form" do
17
+ visit root
18
+ page.should have_text "Login"
19
+ end
20
+
21
+ it "should successfully log in" do
22
+ fill_in :name, "Johnny User"
23
+ click "Login"
24
+ page.should have_text "Welcome, Johnny!"
25
+ end
26
+
27
+ it "should load the password change form" do
28
+ click "My Settings"
29
+ click "Update Password"
30
+ page.should have_selector("form#update_password")
31
+ end
32
+
33
+ it "should change the user's password successfully" do
34
+ fill_in :password, "foobar"
35
+ fill_in :password_confirmation, "foobar"
36
+ click "Change Password"
37
+ page.should have_text "Password changed successfully!"
38
+ User.find_by_name("Johnny User").valid_password?("foobar").should be_true
39
+ end
40
+
41
+ end
42
+
43
+ The examples above will be run in order. State is preserved between examples
44
+ inside a "steps" block: any DB transactions will not roll back until the entire
45
+ sequence has been complete.
46
+
47
+ If any example inside the "steps" block fails, all remaining steps will be marked
48
+ pending and therefore skipped.
49
+
50
+ ## Rationale
51
+
52
+ RSpec's philosophy is that all examples should be completely independent. This
53
+ is a great philosophy for most purposes, and we recommend you stick to it in
54
+ almost all cases. BUT, that complete separation of examples really sucks when
55
+ you're trying to write long stories involving many requests. You are usually
56
+ stuck with three choices:
57
+
58
+ 1. Write a sequence of examples, each of which repeats the behavior of all previous examples. Downside: horrendously inefficient.
59
+ 2. Write a single huge example which performs the entire story. Downside: only one description, no independent reporting of the steps of the story.
60
+ 3. Use Cucumber. Downside: We agree totally with this guy: http://bit.ly/dmXqnY
61
+
62
+ Two-Step intentionally breaks RSpec's "independent" philosophy to let us get the
63
+ only thing we really want from Cucumber - the ability to execute some examples in sequence,
64
+ and skip subsequent steps after a failure.
65
+
66
+ ## Caveats and cautions
67
+
68
+ Don't call "describe" inside of "steps". The behavior is undefined and probably bad. It's
69
+ hard to imagine what this should actually mean in any case. Future versions of rspec-steps
70
+ will consider this an error.
71
+
72
+ Any call to "before" inside a steps block is treated like before(:all) and is run only
73
+ once before the first step. Or perhaps more accurately, any call to before() is treated
74
+ like before(:each) ... but for these purposes the entire steps block is treated like a
75
+ single example.
76
+
77
+ ## Advanced stuff: shared steps
78
+
79
+ If you have (for example) two user stories that share the same first N steps but then
80
+ diverge, you can DRY your code out with shared_steps blocks, like so:
81
+
82
+ shared_steps "For a logged-in user" do
83
+ it "should have login form"
84
+ visit root
85
+ page.should have_selector "form#login"
86
+ end
87
+
88
+ it "should log the user in" do
89
+ fill_in :name, "Johnny User"
90
+ page.should have_text "Welcome, Johnny!"
91
+ end
92
+ end
93
+
94
+ steps "updating password" do
95
+ perform_steps "For a logged-in user"
96
+
97
+ it "should update the password" do
98
+ ...
99
+ end
100
+ end
101
+
102
+ steps "uploading a profile picture" do
103
+ perform_steps "For a logged-in user"
104
+
105
+ it "should upload a picture" do
106
+ ...
107
+ end
108
+ end
109
+
110
+ ## Versions and Dependencies
111
+
112
+ The goal (sadly unfulfilled) is to try to be compatible with as many versions
113
+ of RSpec 2.x as possible. Frankly, Two-Step is more than a little bit of a
114
+ hack, and intrudes wholesale on RSpec's private interfaces. We make good use of
115
+ Travis to check compatibility, however. You can check what versions of RSpec
116
+ and Ruby Two-Step works with here: https://travis-ci.org/LRDesign/two-step
@@ -0,0 +1,17 @@
1
+
2
+ RSpec::Core::ExampleGroup defined as stepwise
3
+ ::steps
4
+ should create an ExampleGroup that includes RSpec::Stepwise
5
+ with Stepwise included
6
+ should retain instance variables between steps
7
+ should mark later examples as pending if one fails
8
+ should allow nested steps
9
+ should not allow nested normal contexts (PENDING: A correct approach - in the meantime, this behavior is undefined)
10
+
11
+ Pending:
12
+ RSpec::Core::ExampleGroup defined as stepwise with Stepwise included should not allow nested normal contexts
13
+ # A correct approach - in the meantime, this behavior is undefined
14
+ # ./spec/example_group.rb:63
15
+
16
+ Finished in 0.10849 seconds
17
+ 5 examples, 0 failures, 1 pending
@@ -0,0 +1,3 @@
1
+ require 'two-step/duckpunch/object-extensions'
2
+ require 'two-step/duckpunch/example-group'
3
+ require 'two-step/duckpunch/example'
@@ -0,0 +1,27 @@
1
+ require 'rspec/core'
2
+ require 'two-step/stepwise'
3
+
4
+ module TwoStep
5
+ module DSL
6
+ def steps(*args, &block)
7
+ options =
8
+ if args.last.is_a?(Hash)
9
+ args.pop
10
+ else
11
+ {}
12
+ end
13
+ options[:stepwise] = true
14
+ options[:caller] ||= caller
15
+ args.push(options)
16
+
17
+ describe(*args, &block)
18
+ end
19
+ end
20
+ end
21
+
22
+ RSpec::Core::ExampleGroup.extend TwoStep::DSL
23
+
24
+ extend TwoStep::DSL
25
+ Module::send(:include, TwoStep::DSL)
26
+
27
+ RSpec::configuration.include(RSpecStepwise, :stepwise => true)
@@ -0,0 +1,5 @@
1
+ RSpec::Core::Example.class_eval do
2
+ def exception
3
+ @exception
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ require 'two-step/duckpunch/example-group'
2
+ require 'two-step/stepwise'
3
+ require 'rspec/core/shared_example_group'
4
+
5
+ module RSpec::Core::SharedExampleGroup
6
+ alias :shared_steps :share_examples_for
7
+ alias :steps_shared_as :share_as
8
+ end
@@ -0,0 +1,219 @@
1
+ module RSpecStepwise
2
+ class ApatheticReporter < ::RSpec::Core::Reporter
3
+ def notify(*args)
4
+ #noop
5
+ end
6
+ end
7
+
8
+ class WholeListExample < RSpec::Core::Example
9
+ def initialize(example_group_class, descriptions, metadata)
10
+ super
11
+ @reporter = ApatheticReporter.new
12
+ build_example_block
13
+ end
14
+
15
+ def start(reporter)
16
+ super(@reporter)
17
+ end
18
+
19
+ def finish(reporter)
20
+ super(@reporter)
21
+ end
22
+
23
+ def build_example_block
24
+ #variables of concern: reporter, instance
25
+ @example_block = proc do
26
+ begin
27
+ self.class.filtered_examples.inject(true) do |success, example|
28
+ break if RSpec.wants_to_quit
29
+ example.extend StepExample
30
+ unless success
31
+ example.metadata[:pending] = true
32
+ example.metadata[:execution_result][:pending_message] = "Previous step failed"
33
+ end
34
+ succeeded = with_indelible_ivars do
35
+ example.run(self, reporter)
36
+ end
37
+ RSpec.wants_to_quit = true if self.class.fail_fast? && !succeeded
38
+ success && succeeded
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ module StepExample
46
+ def run_before_each
47
+ @example_group_class.run_before_step(self)
48
+ rescue Object => ex
49
+ puts "\n#{__FILE__}:#{__LINE__} => #{[ex, ex.backtrace].pretty_inspect}"
50
+ end
51
+
52
+ def run_after_each
53
+ @example_group_class.run_after_step(self)
54
+ end
55
+
56
+ def with_around_hooks
57
+ yield
58
+ end
59
+ end
60
+
61
+ module ClassMethods
62
+ #This is hacky and needs a more general solution
63
+ #Something like cloning the current conf and having RSpec::Stepwise::config ?
64
+ def suspend_transactional_fixtures
65
+ if self.respond_to? :use_transactional_fixtures
66
+ begin
67
+ old_val = self.use_transactional_fixtures
68
+ self.use_transactional_fixtures = false
69
+
70
+ yield
71
+ ensure
72
+ self.use_transactional_fixtures = old_val
73
+ end
74
+ else
75
+ yield
76
+ end
77
+ end
78
+
79
+ def build_before_hook(options, &block)
80
+ if defined? RSpec::Core::Hooks::BeforeHookExtension
81
+ block.extend(RSpec::Core::Hooks::BeforeHookExtension).with(options)
82
+ else
83
+ RSpec::Core::Hooks::BeforeHook.new(block, options)
84
+ end
85
+ end
86
+
87
+ def build_after_hook(options, &block)
88
+ if defined? RSpec::Core::Hooks::AfterHookExtension
89
+ block.extend(RSpec::Core::Hooks::AfterHookExtension).with(options)
90
+ else
91
+ RSpec::Core::Hooks::AfterHook.new(block, options)
92
+ end
93
+ end
94
+
95
+
96
+ def before(*args, &block)
97
+ if args.first == :step
98
+ args.shift
99
+ options = build_metadata_hash_from(args)
100
+ return ((hooks[:before][:step] ||= []) << build_before_hook(options, &block))
101
+ end
102
+ if args.first == :each
103
+ puts "before blocks declared for steps are always treated as :all scope"
104
+ end
105
+ super
106
+ end
107
+
108
+ def after(*args, &block)
109
+ if args.first == :step
110
+ args.shift
111
+ options = build_metadata_hash_from(args)
112
+ hooks[:after][:step] ||= []
113
+ return (hooks[:after][:step].unshift build_after_hook(options, &block))
114
+ end
115
+ if args.first == :each
116
+ puts "after blocks declared for steps are always treated as :all scope"
117
+ end
118
+ super
119
+ end
120
+
121
+ def around(*args, &block)
122
+ if args.first == :each
123
+ puts "around :each blocks declared for steps are treated as :all scope"
124
+ end
125
+ super
126
+ end
127
+
128
+ def example_synonym(named, desc=nil, *args, &block)
129
+ unless desc.nil?
130
+ desc = [named, desc].join(" ")
131
+ end
132
+ it(desc, *args, &block)
133
+ end
134
+
135
+ def when(*args, &block); example_synonym("when", *args, &block); end
136
+ def then(*args, &block); example_synonym("then", *args, &block); end
137
+ def next(*args, &block); example_synonym("next", *args, &block); end
138
+ def step(*args, &block); example_synonym("step", *args, &block); end
139
+
140
+ def run_step(example, hook, &sorting)
141
+ groups = if respond_to?(:parent_groups)
142
+ parent_groups
143
+ else
144
+ ancestors
145
+ end
146
+
147
+ if block_given?
148
+ groups = yield groups
149
+ end
150
+
151
+ RSpec::Core::Hooks::HookCollection.new(groups.map {|a| a.hooks[hook][:step]}.flatten.compact).for(example).run
152
+ end
153
+
154
+ def run_before_step(example)
155
+ run_step(example, :before)
156
+ end
157
+
158
+ def run_after_step(example)
159
+ run_step(example, :after) do |groups|
160
+ groups.reverse
161
+ end
162
+ end
163
+
164
+ def perform_steps(name, *args, &customization_block)
165
+ shared_block = nil
166
+ if world.respond_to? :shared_example_groups
167
+ shared_block = world.shared_example_groups[name]
168
+ else
169
+ shared_block = shared_example_groups[name]
170
+ end
171
+ raise "Could not find shared example group named #{name.inspect}" unless shared_block
172
+
173
+ module_eval_with_args(*args, &shared_block)
174
+ module_eval(&customization_block) if customization_block
175
+ end
176
+
177
+ def run_examples(reporter)
178
+ whole_list_example = WholeListExample.new(self, "step list", {})
179
+
180
+ instance = new
181
+ set_ivars(instance, before_all_ivars)
182
+ instance.example = whole_list_example
183
+ instance.reporter = reporter
184
+
185
+ result = suspend_transactional_fixtures do
186
+ whole_list_example.run(instance, reporter)
187
+ end
188
+
189
+ unless whole_list_example.exception.nil?
190
+ RSpec.wants_to_quit = true if fail_fast?
191
+ fail_filtered_examples(whole_list_example.exception, reporter)
192
+ end
193
+
194
+ result
195
+ end
196
+ end
197
+
198
+ attr_accessor :reporter
199
+
200
+ def with_indelible_ivars
201
+ old_value, @ivars_indelible = @ivars_indelible, true
202
+ result = yield
203
+ @ivars_indelible = old_value
204
+ result
205
+ rescue Object
206
+ @ivars_indelible = old_value
207
+ raise
208
+ end
209
+
210
+ def instance_variable_set(name, value)
211
+ if !@ivars_indelible
212
+ super
213
+ end
214
+ end
215
+
216
+ def self.included(base)
217
+ base.extend(ClassMethods)
218
+ end
219
+ end
@@ -0,0 +1,164 @@
1
+ require 'two-step'
2
+ require 'rspec-sandbox'
3
+
4
+ describe RSpec::Core::ExampleGroup do
5
+ describe "::steps" do
6
+ it "should create an ExampleGroup that includes RSpec::Stepwise" do
7
+ group = nil
8
+ sandboxed do
9
+ group = RSpec.steps "Test Steps" do
10
+ end
11
+ end
12
+ (class << group; self; end).included_modules.should include(RSpecStepwise::ClassMethods)
13
+ end
14
+ end
15
+
16
+ describe "with Stepwise included" do
17
+ it "should retain instance variables between steps" do
18
+ group = nil
19
+ sandboxed do
20
+ group = RSpec.steps "Test Steps" do
21
+ it("sets @a"){ @a = 1 }
22
+ it("reads @a"){ @a.should == 1}
23
+ end
24
+ group.run
25
+ end
26
+
27
+ group.examples.each do |example|
28
+ example.metadata[:execution_result][:status].should == 'passed'
29
+ end
30
+ end
31
+
32
+ it "should work with shared_steps/perform steps" do
33
+ group = nil
34
+ sandboxed do
35
+ group = RSpec.steps "Test Steps" do
36
+ shared_steps "add one" do
37
+ it("adds one to @a"){ @a += 1 }
38
+ end
39
+ it("sets @a"){ @a = 1 }
40
+ perform_steps "add one"
41
+ perform_steps "add one"
42
+ perform_steps "add one"
43
+ it("reads @a"){ @a.should == 4 }
44
+ end
45
+ group.run
46
+ end
47
+
48
+ group.examples.each do |example|
49
+ example.metadata[:execution_result][:status].should == 'passed'
50
+ end
51
+ end
52
+
53
+ it "should run each_step hooks" do
54
+ group = nil
55
+ afters = []
56
+ befores = []
57
+
58
+ sandboxed do
59
+ group = RSpec.steps "Test Each Step" do
60
+ before :each do
61
+ befores << :each
62
+ end
63
+ after :each do
64
+ afters << :each
65
+ end
66
+
67
+ before :all do
68
+ befores << :all
69
+ end
70
+ after :all do
71
+ afters << :all
72
+ end
73
+
74
+ before :step do
75
+ befores << :step
76
+ end
77
+ after :step do
78
+ afters << :step
79
+ end
80
+
81
+ it "should 1" do
82
+ 1.should == 1
83
+ end
84
+ it "should 2" do
85
+ 2.should == 2
86
+ end
87
+ it "should 3" do
88
+ 3.should == 3
89
+ end
90
+ end
91
+ group.run
92
+ end
93
+
94
+ befores.find_all{|item| item == :all}.length.should == 1
95
+ befores.find_all{|item| item == :each}.length.should == 1
96
+ befores.find_all{|item| item == :step}.length.should == 3
97
+ afters.find_all{|item| item == :all}.length.should == 1
98
+ afters.find_all{|item| item == :each}.length.should == 1
99
+ afters.find_all{|item| item == :step}.length.should == 3
100
+ end
101
+
102
+ it "should mark later examples as failed if a before hook fails" do
103
+ group = nil
104
+ exception = Exception.new "Testing Error"
105
+
106
+ sandboxed do
107
+ group = RSpec.steps "Test Steps" do
108
+ before { raise exception }
109
+ it { 1.should == 1 }
110
+ it { 1.should == 1 }
111
+ end
112
+ group.run
113
+ end
114
+
115
+ group.examples.each do |example|
116
+ example.metadata[:execution_result][:status].should == 'failed'
117
+ example.metadata[:execution_result][:exception].should == exception
118
+ end
119
+ end
120
+
121
+ it "should mark later examples as pending if one fails" do
122
+ group = nil
123
+ sandboxed do
124
+ group = RSpec.steps "Test Steps" do
125
+ it { fail "All others fail" }
126
+ it { 1.should == 1 }
127
+ end
128
+ group.run
129
+ end
130
+
131
+ group.examples[1].metadata[:pending].should == true
132
+ end
133
+
134
+ it "should allow nested steps", :pending => "Not really" do
135
+ group = nil
136
+ sandboxed do
137
+ group = RSpec.steps "Test Steps" do
138
+ steps "Nested" do
139
+ it { @a = 1 }
140
+ it { @a.should == 1}
141
+ end
142
+ end
143
+ group.run
144
+ end
145
+
146
+ group.children[0].examples.each do |example|
147
+ example.metadata[:execution_result][:status].should == 'passed'
148
+ end
149
+ group.children[0].should have(2).examples
150
+ end
151
+
152
+ it "should not allow nested normal contexts" do
153
+ pending "A correct approach - in the meantime, this behavior is undefined"
154
+ expect {
155
+ sandboxed do
156
+ RSpec.steps "Basic" do
157
+ describe "Not allowed" do
158
+ end
159
+ end
160
+ end
161
+ }.to raise_error
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,164 @@
1
+ require 'ftools'
2
+ require 'fileutils'
3
+
4
+ module FileSandbox
5
+ def self.included(spec)
6
+ return unless spec.respond_to? :before
7
+
8
+ spec.before do
9
+ setup_sandbox
10
+ end
11
+
12
+ spec.after do
13
+ teardown_sandbox
14
+ end
15
+ end
16
+
17
+ class HaveContents
18
+ def initialize(contents)
19
+ @contents = contents
20
+ end
21
+
22
+ def matches?(target)
23
+ case @contents
24
+ when Regexp
25
+ @contents =~ target.contents
26
+ when String
27
+ @contents == target.contents
28
+ end
29
+ end
30
+ end
31
+
32
+ def have_contents(expected)
33
+ HaveContents.new(expected)
34
+ end
35
+
36
+ attr_reader :sandbox
37
+
38
+ def in_sandbox(&block)
39
+ raise "I expected to create a sandbox as you passed in a block to me" if !block_given?
40
+
41
+ setup_sandbox
42
+ original_error = nil
43
+
44
+ begin
45
+ yield @sandbox
46
+ rescue => e
47
+ original_error = e
48
+ raise
49
+ ensure
50
+ begin
51
+ teardown_sandbox
52
+ rescue
53
+ if original_error
54
+ STDERR.puts "ALERT: a test raised an error and failed to release some lock(s) in the sandbox directory"
55
+ raise(original_error)
56
+ else
57
+ raise
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ def setup_sandbox(path = '__sandbox')
64
+ unless @sandbox
65
+ @sandbox = Sandbox.new(path)
66
+ @__old_path_for_sandbox = Dir.pwd
67
+ Dir.chdir(@sandbox.root)
68
+ end
69
+ end
70
+
71
+ def teardown_sandbox
72
+ if @sandbox
73
+ Dir.chdir(@__old_path_for_sandbox)
74
+ @sandbox.clean_up
75
+ @sandbox = nil
76
+ end
77
+ end
78
+
79
+ class Sandbox
80
+ attr_reader :root
81
+
82
+ def initialize(path = '__sandbox')
83
+ @root = File.expand_path(path)
84
+ clean_up
85
+ FileUtils.mkdir_p @root
86
+ end
87
+
88
+ def [](name)
89
+ SandboxFile.new(File.join(@root, name), name)
90
+ end
91
+
92
+ # usage new :file=>'my file.rb', :with_contents=>'some stuff'
93
+ def new(options)
94
+ if options.has_key? :directory
95
+ dir = self[options.delete(:directory)]
96
+ FileUtils.mkdir_p dir.path
97
+ else
98
+ file = self[options.delete(:file)]
99
+ if (binary_content = options.delete(:with_binary_content) || options.delete(:with_binary_contents))
100
+ file.binary_content = binary_content
101
+ else
102
+ file.content = (options.delete(:with_content) || options.delete(:with_contents) || '')
103
+ end
104
+ end
105
+
106
+ raise "unexpected keys '#{options.keys.join(', ')}'" unless options.empty?
107
+
108
+ dir || file
109
+ end
110
+
111
+ def remove(options)
112
+ name = File.join(@root, options[:file])
113
+ FileUtils.remove_file name
114
+ end
115
+
116
+ def clean_up
117
+ FileUtils.rm_rf @root
118
+ if File.exists? @root
119
+ raise "Could not remove directory #{@root.inspect}, something is probably still holding a lock on it"
120
+ end
121
+ end
122
+ end
123
+
124
+
125
+ class SandboxFile
126
+ attr_reader :path
127
+
128
+ def initialize(path, sandbox_path)
129
+ @path = path
130
+ @sandbox_path = sandbox_path
131
+ end
132
+
133
+ def inspect
134
+ "SandboxFile: #@sandbox_path"
135
+ end
136
+
137
+ def exist?
138
+ File.exist? path
139
+ end
140
+
141
+ def content
142
+ File.read path
143
+ end
144
+
145
+ def content=(content)
146
+ FileUtils.mkdir_p File.dirname(@path)
147
+ File.open(@path, "w") {|f| f << content}
148
+ end
149
+
150
+ def binary_content=(content)
151
+ FileUtils.mkdir_p File.dirname(@path)
152
+ File.open(@path, "wb") {|f| f << content}
153
+ end
154
+
155
+ def create
156
+ self.content = ''
157
+ end
158
+
159
+ alias exists? exist?
160
+ alias contents content
161
+ alias contents= content=
162
+ alias binary_contents= binary_content=
163
+ end
164
+ end
@@ -0,0 +1,17 @@
1
+ puts Dir::pwd
2
+ require 'test/unit'
3
+ begin
4
+ require 'spec'
5
+ rescue LoadError
6
+ false
7
+ end
8
+
9
+ class RSpecTest < Test::Unit::TestCase
10
+ def test_that_rspec_is_available
11
+ assert_nothing_raised("\n\n * RSpec isn't available - please run: gem install rspec *\n\n"){ ::Spec }
12
+ end
13
+
14
+ def test_that_specs_pass
15
+ assert(system(*%w{spec -f e -p **/*.rb spec}),"\n\n * Specs failed *\n\n")
16
+ end
17
+ end
@@ -0,0 +1,46 @@
1
+ require 'rspec/core'
2
+
3
+ class NullObject
4
+ private
5
+ def method_missing(method, *args, &block)
6
+ # ignore
7
+ end
8
+ end
9
+
10
+ def sandboxed(&block)
11
+ @orig_config = RSpec.configuration
12
+ @orig_world = RSpec.world
13
+ new_config = RSpec::Core::Configuration.new
14
+ new_world = RSpec::Core::World.new(new_config)
15
+ RSpec.instance_variable_set(:@configuration, new_config)
16
+ RSpec.instance_variable_set(:@world, new_world)
17
+
18
+ load 'two-step/duckpunch/example-group.rb'
19
+
20
+ object = Object.new
21
+ object.extend(RSpec::Core::SharedExampleGroup)
22
+ object.extend(TwoStep::DSL)
23
+ object.extend(RSpec::Core::DSL)
24
+
25
+ (class << RSpec::Core::ExampleGroup; self; end).class_eval do
26
+ alias_method :orig_run, :run
27
+ def run(reporter=nil)
28
+ @orig_mock_space = RSpec::Mocks::space
29
+ RSpec::Mocks::space = RSpec::Mocks::Space.new
30
+ orig_run(reporter || NullObject.new)
31
+ ensure
32
+ RSpec::Mocks::space = @orig_mock_space
33
+ end
34
+ end
35
+
36
+ object.instance_eval(&block)
37
+ ensure
38
+ (class << RSpec::Core::ExampleGroup; self; end).class_eval do
39
+ remove_method :run
40
+ alias_method :run, :orig_run
41
+ remove_method :orig_run
42
+ end
43
+
44
+ RSpec.instance_variable_set(:@configuration, @orig_config)
45
+ RSpec.instance_variable_set(:@world, @orig_world)
46
+ end
@@ -0,0 +1,3 @@
1
+ require 'rspec'
2
+
3
+ #Ungemmer::ungem_gemspec
@@ -0,0 +1,36 @@
1
+ class Ungemmer
2
+ def self.ungem(*names)
3
+ deps = names.map do |name|
4
+ Gem::Dependency.new(name, nil)
5
+ end
6
+
7
+ deps.each do |dep|
8
+ Gem.source_index.search(dep).each do |gemspec|
9
+ puts " ** Ungemming #{gemspec.full_name} **"
10
+ Gem.source_index.remove_spec(gemspec.full_name)
11
+ end
12
+ end
13
+
14
+ Gem.instance_eval do
15
+ if defined? Gem::MUTEX
16
+ Gem::MUTEX.synchronize do
17
+ @searcher = nil
18
+ end
19
+ else
20
+ @searcher = nil
21
+ end
22
+ end
23
+ end
24
+
25
+ def self.ungem_gemspec
26
+ Dir[File::expand_path(__FILE__ + "../../../*.gemspec")].each do |gemspec_path|
27
+ puts "Ungemming based on #{gemspec_path}"
28
+ begin
29
+ spec = Gem::Specification::load(gemspec_path)
30
+ Ungemmer::ungem(spec)
31
+ rescue LoadError
32
+ puts "Couldn't load #{gemspec_path}"
33
+ end
34
+ end
35
+ end
36
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: two-step
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Judson Lester
8
+ - Evan Dorn
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-11-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: corundum
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: 0.4.0
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: 0.4.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: metric_fu
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 4.11.1
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: 4.11.1
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '2.6'
49
+ - - <
50
+ - !ruby/object:Gem::Version
51
+ version: '3'
52
+ type: :runtime
53
+ prerelease: false
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '2.6'
59
+ - - <
60
+ - !ruby/object:Gem::Version
61
+ version: '3'
62
+ description: |2
63
+ I don't like Cucumber. I don't need plain text stories. My clients either
64
+ read code or don't read any test documents, so Cucumber is mostly useless to me.
65
+ But often, especially in full integration tests, it would be nice to have
66
+ steps in a test.
67
+ email:
68
+ - judson@lrdesign.com
69
+ - evan@lrdesign.com
70
+ executables: []
71
+ extensions: []
72
+ extra_rdoc_files:
73
+ - doc/README
74
+ - doc/Specifications
75
+ files:
76
+ - lib/two-step.rb
77
+ - lib/two-step/stepwise.rb
78
+ - lib/two-step/duckpunch/example-group.rb
79
+ - lib/two-step/duckpunch/example.rb
80
+ - lib/two-step/duckpunch/object-extensions.rb
81
+ - doc/README
82
+ - doc/Specifications
83
+ - spec/example_group_spec.rb
84
+ - spec_help/spec_helper.rb
85
+ - spec_help/gem_test_suite.rb
86
+ - spec_help/rspec-sandbox.rb
87
+ - spec_help/ungemmer.rb
88
+ - spec_help/file-sandbox.rb
89
+ homepage: https://github.com/LRDesign/two-step
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options:
95
+ - --inline-source
96
+ - --main
97
+ - doc/README
98
+ - --title
99
+ - two-step-1.0 RDoc
100
+ require_paths:
101
+ - lib/
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project: two-step
114
+ rubygems_version: 2.0.14
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: I want steps in RSpec 2.x
118
+ test_files:
119
+ - spec_help/gem_test_suite.rb