hat-trick 0.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/.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
|