hat-trick 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/README.md +73 -0
- data/Rakefile +6 -0
- data/app/assets/javascripts/hat-trick.js.coffee +233 -0
- data/app/views/hat_trick/_wizard_meta.html.erb +1 -0
- data/hat-trick.gemspec +28 -0
- data/lib/hat-trick.rb +8 -0
- data/lib/hat_trick/controller_hooks.rb +118 -0
- data/lib/hat_trick/dsl.rb +123 -0
- data/lib/hat_trick/form_helper.rb +30 -0
- data/lib/hat_trick/model_methods.rb +24 -0
- data/lib/hat_trick/rails_engine.rb +13 -0
- data/lib/hat_trick/step.rb +35 -0
- data/lib/hat_trick/step_definition.rb +104 -0
- data/lib/hat_trick/version.rb +3 -0
- data/lib/hat_trick/wizard.rb +176 -0
- data/lib/hat_trick/wizard_definition.rb +22 -0
- data/lib/hat_trick/wizard_steps.rb +95 -0
- data/lib/hat_trick.rb +2 -0
- data/spec/lib/hat_trick/step_spec.rb +9 -0
- data/spec/lib/hat_trick/wizard_definition_spec.rb +39 -0
- data/spec/lib/hat_trick/wizard_spec.rb +64 -0
- data/spec/spec_helper.rb +33 -0
- data/vendor/assets/javascripts/jquery.ba-bbq.js +1137 -0
- data/vendor/assets/javascripts/jquery.form.js +1050 -0
- data/vendor/assets/javascripts/jquery.form.wizard.js +456 -0
- data/vendor/assets/javascripts/jquery.validate.js +1188 -0
- data/vendor/assets/javascripts/vendor_js.js +1 -0
- metadata +182 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'hat_trick/step_definition'
|
2
|
+
|
3
|
+
module HatTrick
|
4
|
+
class Step
|
5
|
+
attr_reader :step_def, :wizard
|
6
|
+
attr_writer :skipped
|
7
|
+
attr_accessor :next_step
|
8
|
+
|
9
|
+
delegate :name, :fieldset, :buttons, :repeat_of, :to_sym, :to_s, :as_json,
|
10
|
+
:run_after_callback, :run_before_callback, :repeat?,
|
11
|
+
:run_include_data_callback, :include_data_key, :to => :step_def
|
12
|
+
|
13
|
+
def initialize(step_def, wizard)
|
14
|
+
@step_def = step_def
|
15
|
+
@wizard = wizard
|
16
|
+
@skipped = step_def.skipped?
|
17
|
+
end
|
18
|
+
|
19
|
+
def session
|
20
|
+
wizard.session
|
21
|
+
end
|
22
|
+
|
23
|
+
def skipped?
|
24
|
+
not visited? and @skipped
|
25
|
+
end
|
26
|
+
|
27
|
+
def visited?
|
28
|
+
session["hat-trick.steps_visited"].include? self.to_sym
|
29
|
+
end
|
30
|
+
|
31
|
+
def visited=(_visited)
|
32
|
+
session["hat-trick.steps_visited"] << self.to_sym
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module HatTrick
|
2
|
+
class StepDefinition
|
3
|
+
attr_reader :callbacks, :include_data_key
|
4
|
+
attr_accessor :name, :fieldset, :buttons, :repeat_of
|
5
|
+
attr_writer :skipped
|
6
|
+
|
7
|
+
def initialize(args={})
|
8
|
+
args.each_pair do |k,v|
|
9
|
+
setter = "#{k}="
|
10
|
+
if respond_to?(setter)
|
11
|
+
send(setter,v)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
@callbacks = {}
|
15
|
+
@buttons = {}
|
16
|
+
@skipped = false
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize_copy(source)
|
20
|
+
@callbacks = source.callbacks.dup
|
21
|
+
@buttons = source.buttons.dup
|
22
|
+
@skipped = false
|
23
|
+
@repeat_of = source
|
24
|
+
end
|
25
|
+
|
26
|
+
def name=(name)
|
27
|
+
@name = name.to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
def fieldset=(fieldset)
|
31
|
+
@fieldset = fieldset.to_sym
|
32
|
+
end
|
33
|
+
|
34
|
+
def fieldset
|
35
|
+
@fieldset or name
|
36
|
+
end
|
37
|
+
|
38
|
+
def repeat?
|
39
|
+
!repeat_of.nil?
|
40
|
+
end
|
41
|
+
|
42
|
+
def skipped?
|
43
|
+
@skipped
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
str = "<HatTrick::Step:0x%08x :#{name}" % (object_id * 2)
|
48
|
+
str += " fieldset: #{fieldset}" if fieldset != name
|
49
|
+
str += ">"
|
50
|
+
str
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_sym
|
54
|
+
name.to_sym
|
55
|
+
end
|
56
|
+
|
57
|
+
def as_json(options = nil)
|
58
|
+
json = { :name => name, :fieldset => fieldset }
|
59
|
+
json[:repeatOf] = repeat_of.as_json if repeat?
|
60
|
+
json[:buttons] = buttons unless buttons.empty?
|
61
|
+
json
|
62
|
+
end
|
63
|
+
|
64
|
+
def before_callback=(blk)
|
65
|
+
callbacks[:before] = blk
|
66
|
+
end
|
67
|
+
|
68
|
+
def after_callback=(blk)
|
69
|
+
callbacks[:after] = blk
|
70
|
+
end
|
71
|
+
|
72
|
+
def include_data=(hash)
|
73
|
+
callbacks[:include_data] = hash.values.first
|
74
|
+
@include_data_key = hash.keys.first
|
75
|
+
end
|
76
|
+
|
77
|
+
def run_before_callback(context, wizard_dsl, model)
|
78
|
+
run_callback(:before, context, wizard_dsl, model)
|
79
|
+
end
|
80
|
+
|
81
|
+
def run_include_data_callback(context, wizard_dsl, model)
|
82
|
+
run_callback(:include_data, context, wizard_dsl, model)
|
83
|
+
end
|
84
|
+
|
85
|
+
def run_after_callback(context, wizard_dsl, model)
|
86
|
+
run_callback(:after, context, wizard_dsl, model)
|
87
|
+
end
|
88
|
+
|
89
|
+
protected
|
90
|
+
|
91
|
+
def run_callback(type, context, *args)
|
92
|
+
callback = callbacks[type.to_sym]
|
93
|
+
if callback && callback.is_a?(Proc)
|
94
|
+
if callback.arity > 1
|
95
|
+
context.instance_exec args[0], args[1], &callback
|
96
|
+
elsif callback.arity == 1
|
97
|
+
context.instance_exec args[0], &callback
|
98
|
+
else
|
99
|
+
context.instance_eval &callback
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require 'hat_trick/controller_hooks'
|
2
|
+
require 'hat_trick/wizard_steps'
|
3
|
+
|
4
|
+
module HatTrick
|
5
|
+
class Wizard
|
6
|
+
include WizardSteps
|
7
|
+
|
8
|
+
attr_accessor :controller, :model
|
9
|
+
attr_reader :current_step, :wizard_def, :wizard_dsl_context, :steps
|
10
|
+
|
11
|
+
def initialize(wizard_def)
|
12
|
+
@wizard_def = wizard_def
|
13
|
+
@wizard_dsl_context = DSL::WizardContext.new(@wizard_def)
|
14
|
+
@wizard_dsl_context.wizard = self
|
15
|
+
@steps = @wizard_def.steps.map { |s| HatTrick::Step.new(s, self) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def controller=(new_controller)
|
19
|
+
@controller = new_controller
|
20
|
+
end
|
21
|
+
|
22
|
+
def current_step=(_step)
|
23
|
+
raise "Don't set current_step to nil" if _step.nil?
|
24
|
+
step = find_step(_step)
|
25
|
+
raise "#{step} is not a member of this wizard" unless step
|
26
|
+
@current_step = step
|
27
|
+
end
|
28
|
+
|
29
|
+
def session
|
30
|
+
controller.session unless controller.nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
def model_created?
|
34
|
+
!(model.nil? || (model.respond_to?(:new_record?) && model.new_record?))
|
35
|
+
end
|
36
|
+
|
37
|
+
def current_form_url
|
38
|
+
model_created? ? update_url : create_url
|
39
|
+
end
|
40
|
+
|
41
|
+
def current_form_method
|
42
|
+
model_created? ? 'put' : 'post'
|
43
|
+
end
|
44
|
+
|
45
|
+
def create_url
|
46
|
+
controller.url_for(:controller => controller.controller_name,
|
47
|
+
:action => 'create', :only_path => true)
|
48
|
+
end
|
49
|
+
|
50
|
+
def update_url
|
51
|
+
if model_created?
|
52
|
+
controller.url_for(:controller => controller.controller_name,
|
53
|
+
:action => 'update', :id => model,
|
54
|
+
:only_path => true)
|
55
|
+
else
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def next_step
|
61
|
+
step = find_next_step
|
62
|
+
while step.skipped? do
|
63
|
+
step = find_step_after(step)
|
64
|
+
end
|
65
|
+
step
|
66
|
+
end
|
67
|
+
|
68
|
+
def previously_visited_step
|
69
|
+
steps_before(current_step).select { |s| s.visited? }.last
|
70
|
+
end
|
71
|
+
|
72
|
+
def skip_step(_step)
|
73
|
+
step = find_step(_step)
|
74
|
+
step.skipped = true
|
75
|
+
end
|
76
|
+
|
77
|
+
def started?
|
78
|
+
!current_step.nil?
|
79
|
+
end
|
80
|
+
|
81
|
+
def start
|
82
|
+
session["hat-trick.steps_visited"] = []
|
83
|
+
self.current_step = first_step
|
84
|
+
run_before_callback
|
85
|
+
end
|
86
|
+
|
87
|
+
def finish
|
88
|
+
# Do something here
|
89
|
+
# Such as: Force the wizard to display the "done" page
|
90
|
+
Rails.logger.info "WIZARD FINISHED!"
|
91
|
+
end
|
92
|
+
|
93
|
+
def run_before_callback(step=current_step)
|
94
|
+
step.run_before_callback(controller, wizard_dsl_context, model)
|
95
|
+
end
|
96
|
+
|
97
|
+
def run_after_callback(step=current_step)
|
98
|
+
step.run_after_callback(controller, wizard_dsl_context, model)
|
99
|
+
end
|
100
|
+
|
101
|
+
def advance_step_with_debugger
|
102
|
+
require 'ruby-debug'
|
103
|
+
debugger
|
104
|
+
advance_step
|
105
|
+
end
|
106
|
+
|
107
|
+
def advance_step(next_step_name=nil)
|
108
|
+
# clean up current step
|
109
|
+
current_step.visited = true
|
110
|
+
run_after_callback
|
111
|
+
|
112
|
+
# see if there is a requested next step
|
113
|
+
requested_next_step = find_step(next_step_name) unless next_step_name.nil?
|
114
|
+
|
115
|
+
# finish if we're on the last step
|
116
|
+
if current_step == last_step && !requested_next_step
|
117
|
+
finish
|
118
|
+
else # we're not on the last step
|
119
|
+
if requested_next_step
|
120
|
+
Rails.logger.info "Force advancing to step: #{requested_next_step}"
|
121
|
+
self.current_step = requested_next_step
|
122
|
+
run_before_callback
|
123
|
+
# if the step was explicitly requested, we ignore #skipped?
|
124
|
+
else
|
125
|
+
Rails.logger.info "Advancing to step: #{next_step}"
|
126
|
+
self.current_step = next_step
|
127
|
+
run_before_callback
|
128
|
+
# Running the before callback may have marked current_step as skipped
|
129
|
+
while current_step.skipped?
|
130
|
+
self.current_step = next_step
|
131
|
+
run_before_callback
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def include_data
|
138
|
+
return {} unless model
|
139
|
+
inc_data = current_step.run_include_data_callback(controller, wizard_dsl_context, model)
|
140
|
+
data_key = current_step.include_data_key
|
141
|
+
{ data_key.to_s.camelize(:lower) => camelize_hash_keys(inc_data) }
|
142
|
+
end
|
143
|
+
|
144
|
+
def alias_action_methods
|
145
|
+
action_methods = controller.action_methods.reject do |m|
|
146
|
+
/^render/ =~ m.to_s ||
|
147
|
+
controller.respond_to?("#{m}_with_hat_trick", :include_private)
|
148
|
+
end
|
149
|
+
HatTrick::ControllerHooks.def_action_method_aliases(action_methods)
|
150
|
+
action_methods.each do |meth|
|
151
|
+
controller.class.send(:alias_method_chain, meth, :hat_trick)
|
152
|
+
controller.class.send(:private, "#{meth}_without_hat_trick")
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def find_next_step
|
159
|
+
find_step(current_step.next_step) or find_step_after(current_step)
|
160
|
+
end
|
161
|
+
|
162
|
+
def find_step_after(step)
|
163
|
+
next_path_step = step_after step
|
164
|
+
next_path_step or find_next_active_step(step)
|
165
|
+
end
|
166
|
+
|
167
|
+
def camelize_hash_keys(_hash)
|
168
|
+
return nil if _hash.nil?
|
169
|
+
hash = {}
|
170
|
+
_hash.each do |k,v|
|
171
|
+
hash[k.to_s.camelize(:lower)] = v
|
172
|
+
end
|
173
|
+
hash
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'hat_trick/step'
|
2
|
+
require 'hat_trick/wizard_steps'
|
3
|
+
require 'hat_trick/wizard'
|
4
|
+
|
5
|
+
module HatTrick
|
6
|
+
class WizardDefinition
|
7
|
+
include WizardSteps
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@steps = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_wizard(controller)
|
14
|
+
controller.send(:ht_wizard) or (
|
15
|
+
wizard = HatTrick::Wizard.new(self)
|
16
|
+
wizard.controller = controller
|
17
|
+
wizard.alias_action_methods
|
18
|
+
wizard
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module HatTrick
|
2
|
+
module WizardSteps
|
3
|
+
include Enumerable
|
4
|
+
attr_reader :steps
|
5
|
+
|
6
|
+
delegate :each, :empty?, :first, :last, :to => :steps
|
7
|
+
|
8
|
+
alias_method :each_step, :each
|
9
|
+
alias_method :to_ary, :steps
|
10
|
+
alias_method :first_step, :first
|
11
|
+
alias_method :last_step, :last
|
12
|
+
|
13
|
+
def find_step(step)
|
14
|
+
return nil if step.nil?
|
15
|
+
if step.is_a?(HatTrick::Step) || step.is_a?(HatTrick::StepDefinition)
|
16
|
+
find { |s| s.equal? step }
|
17
|
+
else
|
18
|
+
find { |s| s.name == step.to_sym }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def step_after(_step)
|
23
|
+
steps_after(_step).first
|
24
|
+
end
|
25
|
+
|
26
|
+
def steps_after(_step)
|
27
|
+
step = find_step(_step)
|
28
|
+
return [] unless step
|
29
|
+
after_index = steps.index(step) + 1
|
30
|
+
steps[after_index .. -1]
|
31
|
+
end
|
32
|
+
|
33
|
+
def step_before(_step)
|
34
|
+
steps_before(_step).last
|
35
|
+
end
|
36
|
+
|
37
|
+
def steps_before(_step)
|
38
|
+
step = find_step(_step)
|
39
|
+
return [] unless step
|
40
|
+
before_index = steps.index(step) - 1
|
41
|
+
steps[0 .. before_index]
|
42
|
+
end
|
43
|
+
|
44
|
+
def add_step(step, args={})
|
45
|
+
if step.is_a?(HatTrick::Step) || step.is_a?(HatTrick::StepDefinition)
|
46
|
+
new_step = step
|
47
|
+
else
|
48
|
+
step_args = args.merge(:name => step)
|
49
|
+
new_step = HatTrick::StepDefinition.new(step_args)
|
50
|
+
end
|
51
|
+
|
52
|
+
steps << new_step
|
53
|
+
|
54
|
+
new_step
|
55
|
+
end
|
56
|
+
|
57
|
+
def delete_step(_step)
|
58
|
+
step = find_step(_step)
|
59
|
+
steps.delete(step)
|
60
|
+
end
|
61
|
+
|
62
|
+
def replace_step(_old_step, _new_step)
|
63
|
+
old_step = find_step(_old_step)
|
64
|
+
old_index = steps.index(old_step)
|
65
|
+
raise ArgumentError, "Couldn't find step #{_old_step}" unless old_step
|
66
|
+
new_step_in_wizard = find_step(_new_step)
|
67
|
+
if new_step_in_wizard
|
68
|
+
# new_step is already in the wizard
|
69
|
+
return move_step(new_step_in_wizard, old_index)
|
70
|
+
end
|
71
|
+
|
72
|
+
if _new_step.is_a?(HatTrick::Step) || _new_step.is_a?(HatTrick::StepDefinition)
|
73
|
+
new_step = _new_step
|
74
|
+
else
|
75
|
+
new_step = HatTrick::StepDefinition.new(:name => _new_step)
|
76
|
+
end
|
77
|
+
|
78
|
+
steps.delete_at(old_index)
|
79
|
+
steps.insert(old_index, new_step)
|
80
|
+
new_step
|
81
|
+
end
|
82
|
+
|
83
|
+
def move_step(step, index)
|
84
|
+
raise ArgumentError, "#{step} isn't in this wizard" unless steps.include?(step)
|
85
|
+
current_index = steps.index(step)
|
86
|
+
unless index < current_index
|
87
|
+
raise ArgumentError, "#{step} has index #{current_index}; must be >= #{index}"
|
88
|
+
end
|
89
|
+
|
90
|
+
while steps.index(step) > index
|
91
|
+
steps.delete_at(index)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/hat_trick.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HatTrick::WizardDefinition do
|
4
|
+
subject { HatTrick::WizardDefinition.new }
|
5
|
+
|
6
|
+
it { should be_empty }
|
7
|
+
|
8
|
+
describe "#add_step" do
|
9
|
+
it "should accept a symbol for the step name" do
|
10
|
+
step = subject.add_step(:step1)
|
11
|
+
step.name.should == :step1
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should add a step to the wizard def" do
|
15
|
+
subject.add_step(:step1)
|
16
|
+
subject.should have(1).step
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should update the last_step attr" do
|
20
|
+
step = subject.add_step(:step1)
|
21
|
+
subject.last_step.should == step
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#delete_step" do
|
26
|
+
it "should remove the step from the wizard def" do
|
27
|
+
step = subject.add_step(:goner)
|
28
|
+
subject.delete_step(step)
|
29
|
+
subject.steps.should_not include(step)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should update the the links between surrounding steps" do
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#replace_step" do
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HatTrick::Wizard do
|
4
|
+
subject {
|
5
|
+
wiz_def = HatTrick::WizardDefinition.new
|
6
|
+
wiz_def.add_step(:step1)
|
7
|
+
wiz_def.add_step(:step2)
|
8
|
+
wiz_def.add_step(:step3)
|
9
|
+
wiz_def.add_step(:step4)
|
10
|
+
wiz_def.add_step(:step5)
|
11
|
+
|
12
|
+
HatTrick::Wizard.new(wiz_def)
|
13
|
+
}
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
subject.start
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "advancing steps" do
|
20
|
+
it "should go from step1 to step2" do
|
21
|
+
subject.current_step.to_sym.should == :step1
|
22
|
+
subject.advance_step
|
23
|
+
subject.current_step.to_sym.should == :step2
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "skipping steps" do
|
28
|
+
it "should skip step2 when requested" do
|
29
|
+
subject.skip_step :step2
|
30
|
+
subject.advance_step
|
31
|
+
subject.current_step.to_sym.should == :step3
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should skip steps 2 & 3 when requested" do
|
35
|
+
subject.skip_step :step2
|
36
|
+
subject.skip_step :step3
|
37
|
+
subject.advance_step
|
38
|
+
subject.current_step.to_sym.should == :step4
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "repeating steps" do
|
43
|
+
it "should repeat step 2 when requested" do
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "setting explicit next steps" do
|
48
|
+
it "should advance to the requested next step when one is set" do
|
49
|
+
subject.steps.first.next_step = :step4
|
50
|
+
subject.advance_step
|
51
|
+
subject.current_step.to_sym.should == :step4
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#previously_visited_step" do
|
56
|
+
it "should return the most recently visited step" do
|
57
|
+
subject.steps[0].visited = true
|
58
|
+
subject.steps[1].visited = true
|
59
|
+
subject.steps[3].visited = true
|
60
|
+
subject.current_step = :step5
|
61
|
+
subject.previously_visited_step.to_sym.should == :step4
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
ENV["RAILS_ENV"] ||= 'test'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module Rails
|
6
|
+
def self.root
|
7
|
+
Pathname.new(File.expand_path('../..', __FILE__))
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.logger
|
11
|
+
@logger ||= ::Logger.new(STDOUT).tap { |l| l.level = ::Logger::ERROR }
|
12
|
+
end
|
13
|
+
|
14
|
+
class Engine
|
15
|
+
def self.initializer(*args, &block); end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module ActionController
|
20
|
+
class Base
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require File.expand_path('../../lib/hat-trick', __FILE__)
|
25
|
+
require 'rspec/autorun'
|
26
|
+
|
27
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
28
|
+
# in spec/support/ and its subdirectories.
|
29
|
+
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
30
|
+
|
31
|
+
RSpec.configure do |config|
|
32
|
+
config.mock_with :mocha
|
33
|
+
end
|