Exspec 1.0.1
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/bin/exspec +34 -0
- data/lib/exspec/context_manager.rb +75 -0
- data/lib/exspec/execute_callbacks.rb +24 -0
- data/lib/exspec/executor.rb +227 -0
- data/lib/exspec/extensions/extension.rb +70 -0
- data/lib/exspec/extensions/mocking.rb +125 -0
- data/lib/exspec/extensions/rails.rb +78 -0
- data/lib/exspec/helpers.rb +10 -0
- data/lib/exspec/irb/irb_context_manager.rb +35 -0
- data/lib/exspec/irb/irb_exspec.rb +40 -0
- data/lib/exspec/irb/irb_patch.rb +51 -0
- data/lib/exspec/logger.rb +71 -0
- data/lib/exspec/regression_test_reporter.rb +93 -0
- data/lib/exspec/reporter.rb +29 -0
- data/lib/exspec/spec.rb +107 -0
- data/lib/exspec/spec_manager.rb +93 -0
- data/lib/exspec/spec_runner.rb +55 -0
- data/lib/exspec.rb +217 -0
- metadata +80 -0
data/bin/exspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "exspec"
|
4
|
+
|
5
|
+
if ARGV.empty?
|
6
|
+
started = Exspec::Extension.start_exspec
|
7
|
+
Exspec::IrbExspec.start_irb unless started
|
8
|
+
else
|
9
|
+
exspec = Exspec::Exspec.new
|
10
|
+
|
11
|
+
spec_arg = ARGV.join " "
|
12
|
+
spec = exspec.spec spec_arg
|
13
|
+
|
14
|
+
reporter = Exspec::REGRESSION_TEST_REPORTER.new
|
15
|
+
if !spec.nil? && spec.exist?
|
16
|
+
exspec.report_to(reporter) { exspec.run_stack spec }
|
17
|
+
else
|
18
|
+
specs = exspec.specs spec_arg, true
|
19
|
+
specs.each do |spec|
|
20
|
+
spec.stack.each do |parent|
|
21
|
+
if parent != spec
|
22
|
+
specs.delete(parent)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
exspec.report_to(reporter) { exspec.run_specs specs }
|
27
|
+
end
|
28
|
+
|
29
|
+
failed = reporter.failed
|
30
|
+
puts "#{failed.length} of #{reporter.specs.length} specs failed" + (failed.empty? ? "!" : ":")
|
31
|
+
reporter.failed.each do |spec|
|
32
|
+
puts "- #{spec.full_description}"
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Exspec
|
2
|
+
class ContextManager
|
3
|
+
def initialize(exspec)
|
4
|
+
@exspec = exspec
|
5
|
+
@global_context = context
|
6
|
+
setup_global_context
|
7
|
+
setup_exspec_context
|
8
|
+
start_new_context
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :exspec, :last_value
|
12
|
+
attr_accessor :last_exspec_value
|
13
|
+
|
14
|
+
def start_new_context
|
15
|
+
context = global_eval "lambda { binding }.call"
|
16
|
+
self.context = context
|
17
|
+
Extension.setup_context self
|
18
|
+
context
|
19
|
+
end
|
20
|
+
|
21
|
+
def context
|
22
|
+
@binding ||= Object.new.instance_eval "binding"
|
23
|
+
end
|
24
|
+
|
25
|
+
def context=(value)
|
26
|
+
@binding = value
|
27
|
+
end
|
28
|
+
|
29
|
+
def last_value=(value)
|
30
|
+
@last_value=value
|
31
|
+
global_eval "_ = exspec.last_value"
|
32
|
+
value
|
33
|
+
end
|
34
|
+
|
35
|
+
def last_exspec_value
|
36
|
+
@last_exspec_value
|
37
|
+
end
|
38
|
+
|
39
|
+
def last_exspec_value=(value)
|
40
|
+
@last_exspec_value = value
|
41
|
+
exspec_eval "_ = exspec.last_exspec_value"
|
42
|
+
end
|
43
|
+
|
44
|
+
def eval(statement)
|
45
|
+
self.last_value = raw_eval statement
|
46
|
+
end
|
47
|
+
|
48
|
+
def raw_eval(statement)
|
49
|
+
context.eval statement
|
50
|
+
end
|
51
|
+
|
52
|
+
def global_eval(statement)
|
53
|
+
@global_context.eval statement
|
54
|
+
end
|
55
|
+
|
56
|
+
def exspec_eval(statement)
|
57
|
+
@exspec_context.eval statement
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def setup_global_context
|
63
|
+
global_instance = global_eval "self"
|
64
|
+
global_instance.instance_variable_set :@exspec, @exspec
|
65
|
+
global_instance.class.send :attr_reader, :exspec
|
66
|
+
global_eval "_ = nil"
|
67
|
+
Extension.setup_global_context self
|
68
|
+
end
|
69
|
+
|
70
|
+
def setup_exspec_context
|
71
|
+
@exspec_context = global_eval "lambda { |_| binding }.call nil"
|
72
|
+
Extension.setup_exspec_context self
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Exspec
|
2
|
+
class ExecuteCallbacks
|
3
|
+
def initialize
|
4
|
+
@before = []
|
5
|
+
@after = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def before(command=nil, params=nil, &block)
|
9
|
+
if block_given?
|
10
|
+
@before << block
|
11
|
+
else
|
12
|
+
@before.each { |proc| proc.call(command, params) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def after(command=nil, params=nil, value=nil, &block)
|
17
|
+
if block_given?
|
18
|
+
@after << block
|
19
|
+
else
|
20
|
+
@after.each { |proc| proc.call(command, params, value) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
require_relative "execute_callbacks"
|
2
|
+
|
3
|
+
module Exspec
|
4
|
+
class Executor
|
5
|
+
def initialize(exspec)
|
6
|
+
@exspec = exspec
|
7
|
+
end
|
8
|
+
|
9
|
+
delegate :puts, :print, :return_spec, :context, :to => :@exspec
|
10
|
+
attr_reader :exspec
|
11
|
+
|
12
|
+
def eval(instruction, &callback_block)
|
13
|
+
callbacks = ExecuteCallbacks.new
|
14
|
+
Extension.set_execute_callbacks callbacks
|
15
|
+
callback_block.call callbacks if block_given?
|
16
|
+
instruction.strip!
|
17
|
+
eval = true
|
18
|
+
val = nil
|
19
|
+
if instruction.start_with? COMMAND_PREFIX
|
20
|
+
parts = instruction.split " "
|
21
|
+
command = parts[0][1..-1]
|
22
|
+
param_string = parts[1..-1].join " "
|
23
|
+
eval = false
|
24
|
+
val = Extension.execute_command self, command, param_string, callbacks
|
25
|
+
if val.nil?
|
26
|
+
val = case command
|
27
|
+
when ""
|
28
|
+
execute(command, parameters(param_string), callbacks) do
|
29
|
+
exspec.exspec_eval param_string
|
30
|
+
end
|
31
|
+
when "_"
|
32
|
+
execute(command, parameters(param_string), callbacks) do
|
33
|
+
exspec.last_exspec_value
|
34
|
+
end
|
35
|
+
when "inspect"
|
36
|
+
execute(command, callbacks) do
|
37
|
+
exspec.inspect_last_value
|
38
|
+
end
|
39
|
+
when "redo"
|
40
|
+
execute(command, callbacks) do
|
41
|
+
exspec.redo
|
42
|
+
end
|
43
|
+
when "retry", "rerun", "again"
|
44
|
+
execute(command, callbacks) do
|
45
|
+
exspec.retry
|
46
|
+
end
|
47
|
+
when "save"
|
48
|
+
execute(command, parameters(param_string, COMMENT_SIGN), callbacks) do |params|
|
49
|
+
exspec.save *params
|
50
|
+
end
|
51
|
+
when "include", "call", "include_segment", "call_segment"
|
52
|
+
execute(command, parameters(param_string), callbacks) do |params|
|
53
|
+
exspec.include *params
|
54
|
+
end
|
55
|
+
when "run", "run_spec", "run_segment"
|
56
|
+
execute(command, parameters(param_string), callbacks) do |params|
|
57
|
+
exspec.run *params
|
58
|
+
end
|
59
|
+
when "run_stack"
|
60
|
+
execute(command, parameters(param_string), callbacks) do |params|
|
61
|
+
exspec.run_stack *params
|
62
|
+
end
|
63
|
+
when "load"
|
64
|
+
execute(command, parameters(param_string), callbacks) do |params|
|
65
|
+
exspec.load *params
|
66
|
+
end
|
67
|
+
when "comment", "#"
|
68
|
+
execute(command, parameters(param_string), callbacks) do |params|
|
69
|
+
exspec.comment *params
|
70
|
+
end
|
71
|
+
when "assert"
|
72
|
+
execute(command, parameters(param_string, COMMENT_SIGN), callbacks) do |params|
|
73
|
+
exspec.assert *params
|
74
|
+
end
|
75
|
+
when "expect"
|
76
|
+
execute(command, parameters(param_string, COMMENT_SIGN), callbacks) do |params|
|
77
|
+
exspec.expect *params
|
78
|
+
end
|
79
|
+
when "expect_inspect"
|
80
|
+
execute(command, parameters(param_string, COMMENT_SIGN), callbacks) do |params|
|
81
|
+
exspec.expect_inspect *params
|
82
|
+
end
|
83
|
+
when "skip"
|
84
|
+
execute(command, callbacks) do
|
85
|
+
SkipSignal
|
86
|
+
end
|
87
|
+
when "load_current", "reload_current", "discard"
|
88
|
+
execute(command, callbacks) do
|
89
|
+
exspec.load exspec.current_spec
|
90
|
+
end
|
91
|
+
when "load_parent", "up", "independent"
|
92
|
+
execute(command, callbacks) do
|
93
|
+
spec = exspec.current_spec
|
94
|
+
spec = spec.parent unless spec.nil?
|
95
|
+
exspec.load spec
|
96
|
+
end
|
97
|
+
when "load#"
|
98
|
+
execute(command, parameters(param_string), callbacks) do |params|
|
99
|
+
menu_action(params, Spec) { |spec| spec.load }
|
100
|
+
end
|
101
|
+
when "run#", "run_spec#", "run_segment#"
|
102
|
+
execute(command, parameters(param_string), callbacks) do |params|
|
103
|
+
menu_action(params, Spec) { |spec| spec.run }
|
104
|
+
end
|
105
|
+
when "run_stack#"
|
106
|
+
execute(command, parameters(param_string), callbacks) do |params|
|
107
|
+
menu_action(params, Spec) { |spec| spec.run_stack }
|
108
|
+
end
|
109
|
+
when "include#", "include_segment#", "call#", "call_segment#"
|
110
|
+
execute(command, parameters(param_string), callbacks) do |params|
|
111
|
+
menu_action(params, Spec) { |spec| spec.include }
|
112
|
+
end
|
113
|
+
when "ignore", "erase", "delete"
|
114
|
+
execute(command, callbacks) do
|
115
|
+
exspec.erase_last_instruction
|
116
|
+
return_spec exspec.logger.last_value
|
117
|
+
end
|
118
|
+
when "ignore#", "erase#", "delete#"
|
119
|
+
execute(command, parameters(param_string), callbacks) do |params|
|
120
|
+
menu_action(params) do |entry|
|
121
|
+
exspec.logger.entries.delete entry
|
122
|
+
end
|
123
|
+
return_spec exspec.logger.last_value
|
124
|
+
end
|
125
|
+
when "reset", "clear"
|
126
|
+
execute(command, callbacks) do
|
127
|
+
exspec.reset
|
128
|
+
end
|
129
|
+
when "log", "instructions", "history"
|
130
|
+
execute(command, callbacks) do
|
131
|
+
menu(exspec.logger.entries) { |entry| entry[:instruction] }
|
132
|
+
end
|
133
|
+
when "stack"
|
134
|
+
execute(command, callbacks) do
|
135
|
+
menu(exspec.current_spec && exspec.current_spec.stack) do |spec|
|
136
|
+
spec.name
|
137
|
+
end
|
138
|
+
end
|
139
|
+
when "specs", "tests"
|
140
|
+
execute(command, parameters(param_string), callbacks) do |params|
|
141
|
+
menu(exspec.specs *params) { |spec| spec.name }
|
142
|
+
end
|
143
|
+
when "specs#", "tests#"
|
144
|
+
execute(command, parameters(param_string), callbacks) do |params|
|
145
|
+
menu_action(params, Spec) do |spec|
|
146
|
+
menu(spec.children) { |spec| spec.name }
|
147
|
+
end
|
148
|
+
end
|
149
|
+
when "no_log", "without_logging", "silent"
|
150
|
+
val = exspec.without_logging { exspec.execute param_string }
|
151
|
+
return_spec exspec.logger.last_value
|
152
|
+
val
|
153
|
+
when "log_off", "disable_log"
|
154
|
+
execute(command, callbacks) do
|
155
|
+
exspec.logger.enabled = false
|
156
|
+
exspec.last_value
|
157
|
+
end
|
158
|
+
when "log_on", "enable_log"
|
159
|
+
execute(command, callbacks) do
|
160
|
+
exspec.logger.enabled = true
|
161
|
+
return_spec exspec.logger.last_value
|
162
|
+
end
|
163
|
+
else
|
164
|
+
eval = true
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
if eval
|
169
|
+
val = execute(callbacks) do
|
170
|
+
exspec.eval instruction
|
171
|
+
end
|
172
|
+
end
|
173
|
+
val
|
174
|
+
end
|
175
|
+
|
176
|
+
private
|
177
|
+
|
178
|
+
def menu(options=nil)
|
179
|
+
return @menu || [] unless options.is_a?(Array)
|
180
|
+
@menu = options
|
181
|
+
puts '====================================='
|
182
|
+
@menu.each.with_index do |option, index|
|
183
|
+
puts "#{index}. #{block_given? ? yield(option) : option}"
|
184
|
+
end
|
185
|
+
puts '====================================='
|
186
|
+
@menu
|
187
|
+
end
|
188
|
+
|
189
|
+
def menu_action(params, type=nil)
|
190
|
+
index = params.is_a?(Array) ? params[0] : nil
|
191
|
+
return nil if index.nil?
|
192
|
+
index = index.to_i
|
193
|
+
element = menu[index]
|
194
|
+
return element unless type.nil? || element.is_a?(type)
|
195
|
+
yield element, index
|
196
|
+
end
|
197
|
+
|
198
|
+
def execute(command=nil, params=nil, callbacks, &execute)
|
199
|
+
val = nil
|
200
|
+
callbacks.before command, params
|
201
|
+
begin
|
202
|
+
val = execute.call params
|
203
|
+
rescue Exception => e
|
204
|
+
val = e
|
205
|
+
raise
|
206
|
+
ensure
|
207
|
+
callbacks.after command, params, val
|
208
|
+
end
|
209
|
+
val
|
210
|
+
end
|
211
|
+
|
212
|
+
def parameters(param_string, *separators)
|
213
|
+
param_string.strip!
|
214
|
+
params = []
|
215
|
+
separators.each do |separator|
|
216
|
+
parts = " #{param_string}".split separator
|
217
|
+
if parts.length > 1
|
218
|
+
param = parts[0].strip
|
219
|
+
params << (param.empty? ? nil : param)
|
220
|
+
param_string = parts[1..-1].join(separator).strip
|
221
|
+
end
|
222
|
+
end
|
223
|
+
params << (param_string.empty? ? nil : param_string)
|
224
|
+
params.reverse.drop_while(&:nil?).reverse
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Exspec::Extension
|
2
|
+
@@module = self
|
3
|
+
@@extensions = {}
|
4
|
+
|
5
|
+
def self.loaded
|
6
|
+
apply :loaded
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.config(config)
|
10
|
+
apply :config, nil, false, config
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.start_exspec
|
14
|
+
apply :start_exspec, nil, true
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.set_execute_callbacks(options)
|
18
|
+
apply :set_execute_callbacks, nil, false, options
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.initialize_exspec(exspec, components)
|
22
|
+
apply :initialize_exspec, exspec, false, components
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.execute_command(executor, command, param_string, options)
|
26
|
+
apply :execute_command, executor, true, command, param_string, options
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.setup_context(context_manager)
|
30
|
+
apply :setup_context, context_manager
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.setup_global_context(context_manager)
|
34
|
+
apply :setup_global_context, context_manager
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.setup_exspec_context(context_manager)
|
38
|
+
apply :setup_exspec_context, context_manager
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.apply(extension_point, extended_instance=nil, return_first=false, *args)
|
42
|
+
extensions(extension_point).each do |extension|
|
43
|
+
val = if extended_instance
|
44
|
+
extended_instance.instance_exec *args, &extension
|
45
|
+
else
|
46
|
+
extension.call *args
|
47
|
+
end
|
48
|
+
return val if return_first && !val.nil?
|
49
|
+
end
|
50
|
+
return nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.extensions(extension_point)
|
54
|
+
extension_point = extension_point.to_sym
|
55
|
+
extensions = (@@extensions[extension_point] = []) unless extensions = @@extensions[extension_point]
|
56
|
+
extensions
|
57
|
+
end
|
58
|
+
|
59
|
+
def method_missing(method, *args, &block)
|
60
|
+
def_extension method, block
|
61
|
+
end
|
62
|
+
|
63
|
+
def extensions(extension_point)
|
64
|
+
@@module.extensions extension_point
|
65
|
+
end
|
66
|
+
|
67
|
+
def def_extension(extension_point, block)
|
68
|
+
extensions(extension_point.to_sym) << block
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Exspec::Mocking
|
2
|
+
extend Exspec::Extension
|
3
|
+
|
4
|
+
execute_command do |command, param_string, options|
|
5
|
+
case command
|
6
|
+
when "mock", "stub"
|
7
|
+
execute(command, parameters(param_string), options) do |params|
|
8
|
+
if params.empty?
|
9
|
+
exspec.commit "#{Exspec::COMMAND_PREFIX}mock", Mock.new
|
10
|
+
else
|
11
|
+
mock_var = params[0]
|
12
|
+
exspec.commit "#{Exspec::COMMAND_PREFIX}mock #{mock_var}"
|
13
|
+
puts "assigning #{command} to #{mock_var}"
|
14
|
+
context.raw_eval "#{mock_var} = #{Mock.name}.new"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Mock < BasicObject
|
21
|
+
def initialize
|
22
|
+
@methods = {}
|
23
|
+
@attributes = {}
|
24
|
+
@children = {}
|
25
|
+
@method_calls = []
|
26
|
+
end
|
27
|
+
|
28
|
+
def new(*args, &block)
|
29
|
+
_log_call :new, args, block
|
30
|
+
_defined?(:new) ? _call(:new, *args, &block) : self
|
31
|
+
end
|
32
|
+
|
33
|
+
def ==(*args, &block)
|
34
|
+
_log_call :==, args, block
|
35
|
+
_defined?(:==) ? _call(:==, *args, &block) : false
|
36
|
+
end
|
37
|
+
|
38
|
+
def inspect(*args, &block)
|
39
|
+
_log_call :inspect, args, block
|
40
|
+
_defined?(:inspect) ? _call(:inspect, *args, &block) : "#<Exspec Mock>"
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s(*args, &block)
|
44
|
+
_log_call :to_s, args, block
|
45
|
+
_defined?(:to_s) ? _call(:to_s, *args, &block) : "Exspec Mock"
|
46
|
+
end
|
47
|
+
|
48
|
+
def nil?(*args, &block)
|
49
|
+
_log_call :nil?, args, block
|
50
|
+
_defined?(:nil?) ? _call(:nil?, *args, &block) : false
|
51
|
+
end
|
52
|
+
|
53
|
+
def _def(method, &body)
|
54
|
+
@methods[method.to_sym] = body
|
55
|
+
end
|
56
|
+
|
57
|
+
def _defined?(method)
|
58
|
+
@methods.include? method.to_sym
|
59
|
+
end
|
60
|
+
|
61
|
+
def _method_calls(method=nil)
|
62
|
+
if method.nil?
|
63
|
+
@method_calls
|
64
|
+
else
|
65
|
+
@method_calls.select { |call| call[:method] == method.to_sym }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def _have_been_called?(method)
|
70
|
+
@method_calls.any? { |call| call[:method] == method.to_sym }
|
71
|
+
end
|
72
|
+
|
73
|
+
def _times_called(method)
|
74
|
+
@method_calls.count { |call| call[:method] == method.to_sym }
|
75
|
+
end
|
76
|
+
|
77
|
+
def _first_call(method)
|
78
|
+
@method_calls.find { |call| call[:method] == method.to_sym }
|
79
|
+
end
|
80
|
+
|
81
|
+
def _last_call(method)
|
82
|
+
@method_calls.reverse.find { |call| call[:method] == method.to_sym }
|
83
|
+
end
|
84
|
+
|
85
|
+
def _log_call(method, args, block)
|
86
|
+
@method_calls << { :method => method.to_sym, :args => args, :block => block }
|
87
|
+
end
|
88
|
+
|
89
|
+
def _attribute_set?(attribute)
|
90
|
+
@attributes.include? attribute.to_sym
|
91
|
+
end
|
92
|
+
|
93
|
+
def _attribute(attribute)
|
94
|
+
@attributes[attribute.to_sym]
|
95
|
+
end
|
96
|
+
|
97
|
+
def _set_attribute(attribute, value)
|
98
|
+
@attributes[attribute.to_sym] = value
|
99
|
+
end
|
100
|
+
|
101
|
+
def _child(name)
|
102
|
+
name = name.to_sym
|
103
|
+
if @children.include? name
|
104
|
+
@attributes[name]
|
105
|
+
else
|
106
|
+
@attributes[name] = Mock.new
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def _call(method, *args, &block)
|
111
|
+
return @methods[method.to_sym].call (args + [block]) if _defined? method
|
112
|
+
if method.to_s.end_with?("=") && !args.empty?
|
113
|
+
return _set_attribute(method.to_s.chop, args[0])
|
114
|
+
elsif _attribute_set?(method)
|
115
|
+
return _attribute(method)
|
116
|
+
end
|
117
|
+
_child(method)
|
118
|
+
end
|
119
|
+
|
120
|
+
def method_missing(method, *args, &block)
|
121
|
+
_log_call method, args, block
|
122
|
+
_call(method, *args, &block)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Exspec::Rails
|
2
|
+
extend Exspec::Extension
|
3
|
+
|
4
|
+
@@rails = self
|
5
|
+
@@app_path = nil
|
6
|
+
@@enabled = true
|
7
|
+
|
8
|
+
def self.enabled=(value)
|
9
|
+
@@enabled = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.is_available?
|
13
|
+
return @@enabled && !!app_path
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.app_path
|
17
|
+
return @@app_path if @@app_path
|
18
|
+
parent_dirs do |path|
|
19
|
+
if File.file?(File.expand_path("config/boot.rb", path)) && File.file?(File.expand_path("config/application.rb", path))
|
20
|
+
@@app_path = path
|
21
|
+
return @@app_path
|
22
|
+
end
|
23
|
+
end
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.start_console
|
28
|
+
if is_available?
|
29
|
+
begin
|
30
|
+
require_environment
|
31
|
+
::Rails::Console.start(::Rails.application)
|
32
|
+
return true
|
33
|
+
rescue Exception => e
|
34
|
+
@@enabled = false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.require_environment
|
41
|
+
if is_available?
|
42
|
+
begin
|
43
|
+
require "rails"
|
44
|
+
require "rails/commands/console"
|
45
|
+
require File.expand_path("config/boot", app_path)
|
46
|
+
require File.expand_path("config/application", app_path)
|
47
|
+
::Rails.application.require_environment!
|
48
|
+
rescue Exception => e
|
49
|
+
@@enabled = false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
config do |config|
|
55
|
+
if is_available?
|
56
|
+
config[:test_dir] = File.expand_path(config[:test_dir], app_path)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
setup_global_context do
|
61
|
+
@@rails.require_environment
|
62
|
+
end
|
63
|
+
|
64
|
+
setup_context do
|
65
|
+
if @@rails.is_available?
|
66
|
+
begin
|
67
|
+
::ActionDispatch::Reloader.cleanup!
|
68
|
+
::ActionDispatch::Reloader.prepare!
|
69
|
+
rescue Exception => e
|
70
|
+
@@enabled = false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
start_irb do
|
76
|
+
start_console
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative "../context_manager"
|
2
|
+
|
3
|
+
module Exspec
|
4
|
+
class IrbContextManager < ContextManager
|
5
|
+
delegate :irb_workspace, :irb_context, :to => :exspec
|
6
|
+
|
7
|
+
def context
|
8
|
+
irb_workspace.binding
|
9
|
+
end
|
10
|
+
|
11
|
+
def context=(value)
|
12
|
+
irb_workspace.instance_variable_set(:@binding, value)
|
13
|
+
end
|
14
|
+
|
15
|
+
def last_output
|
16
|
+
irb_context.inspect_last_value
|
17
|
+
end
|
18
|
+
|
19
|
+
def last_value
|
20
|
+
irb_context.last_value
|
21
|
+
end
|
22
|
+
|
23
|
+
def last_value=(value)
|
24
|
+
irb_context.set_last_value(value)
|
25
|
+
end
|
26
|
+
|
27
|
+
def define_eval(&eval)
|
28
|
+
@eval = eval
|
29
|
+
end
|
30
|
+
|
31
|
+
def eval(instruction)
|
32
|
+
@eval.call instruction
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|