hat-trick 0.1.2 → 0.1.3
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 +1 -0
- data/Changelog +17 -3
- data/README.md +44 -19
- data/app/assets/javascripts/hat-trick.js.coffee +214 -123
- data/lib/hat-trick.rb +0 -2
- data/lib/hat_trick/config.rb +10 -11
- data/lib/hat_trick/controller_helpers.rb +18 -4
- data/lib/hat_trick/controller_hooks.rb +37 -23
- data/lib/hat_trick/dsl.rb +144 -50
- data/lib/hat_trick/engine.rb +6 -0
- data/lib/hat_trick/form_helper.rb +1 -1
- data/lib/hat_trick/model_methods.rb +14 -3
- data/lib/hat_trick/step.rb +24 -11
- data/lib/hat_trick/step_definition.rb +162 -36
- data/lib/hat_trick/version.rb +1 -1
- data/lib/hat_trick/wizard.rb +105 -46
- data/lib/hat_trick/wizard_definition.rb +18 -9
- data/lib/hat_trick/wizard_steps.rb +12 -3
- data/spec/lib/hat_trick/dsl_spec.rb +11 -10
- data/spec/lib/hat_trick/step_definition_spec.rb +106 -0
- data/spec/lib/hat_trick/wizard_definition_spec.rb +18 -9
- data/spec/lib/hat_trick/wizard_spec.rb +22 -17
- data/spec/spec_helper.rb +6 -0
- data/vendor/assets/javascripts/array.filter.js +22 -0
- data/vendor/assets/javascripts/history.html4.js +658 -0
- data/vendor/assets/javascripts/history.js +1991 -0
- data/vendor/assets/javascripts/jquery.form.wizard.js +162 -145
- data/vendor/assets/javascripts/jquery.history.js +77 -1
- data/vendor/assets/javascripts/json.js +480 -0
- metadata +10 -4
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HatTrick::StepDefinition do
|
4
|
+
let(:mock_config) {
|
5
|
+
mock("HatTrick::Config").tap do |mc|
|
6
|
+
mc.stubs(:next_button_label).returns(nil)
|
7
|
+
mc.stubs(:back_button_label).returns(nil)
|
8
|
+
mc.stubs(:next_button_label_i18n_key).returns(nil)
|
9
|
+
mc.stubs(:back_button_label_i18n_key).returns(nil)
|
10
|
+
end
|
11
|
+
}
|
12
|
+
|
13
|
+
let(:mock_wizard) {
|
14
|
+
mock("HatTrick::WizardDefinition").tap do |mw|
|
15
|
+
mw.stubs(:config).returns(mock_config)
|
16
|
+
end
|
17
|
+
}
|
18
|
+
|
19
|
+
subject(:step_definition) {
|
20
|
+
HatTrick::StepDefinition.new(:wizard => mock_wizard)
|
21
|
+
}
|
22
|
+
|
23
|
+
before :each do
|
24
|
+
I18n.stubs(:t).with("wizard.buttons.next", :default => "Next").returns("Next")
|
25
|
+
I18n.stubs(:t).with("wizard.buttons.back", :default => "Back").returns("Back")
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#get_button" do
|
29
|
+
it "returns the button(s) with the requested type" do
|
30
|
+
step_definition.get_button(:next).should == { :label => 'Next', :default => true }
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns nil if no buttons of that type are found" do
|
34
|
+
step_definition.get_button(:foo).should be_nil
|
35
|
+
end
|
36
|
+
|
37
|
+
it "works with custom button types" do
|
38
|
+
custom_button = { :custom => { :label => "I'm a button!" } }
|
39
|
+
default_buttons = step_definition.buttons
|
40
|
+
step_definition.stubs(:buttons).returns(default_buttons + [custom_button])
|
41
|
+
step_definition.get_button(:custom).should == custom_button[:custom]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#delete_button" do
|
46
|
+
it "removes the button from the buttons array" do
|
47
|
+
expect {
|
48
|
+
step_definition.delete_button(:next)
|
49
|
+
}.to change { step_definition.next_button }.from(
|
50
|
+
{ :label => 'Next', :default => true }
|
51
|
+
).to(nil)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#add_button" do
|
56
|
+
it "replaces default if types match" do
|
57
|
+
expect {
|
58
|
+
step_definition.add_button(:next => {:label => 'Foo'})
|
59
|
+
}.to change { step_definition.next_button }.from(
|
60
|
+
{ :label => 'Next', :default => true }
|
61
|
+
).to({ :label => 'Foo' })
|
62
|
+
end
|
63
|
+
|
64
|
+
it "doesn't replace non-default buttons" do
|
65
|
+
expect {
|
66
|
+
step_definition.add_button(:bar => {:label => 'Bar'})
|
67
|
+
}.to change { step_definition.buttons.count }.from(2).to(3)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#buttons" do
|
72
|
+
it "has exactly 2 buttons" do
|
73
|
+
step_definition.buttons.should have(2).buttons
|
74
|
+
end
|
75
|
+
|
76
|
+
it "has a default next button" do
|
77
|
+
step_definition.buttons.should include(
|
78
|
+
{ :next => { :label => "Next", :default => true } }
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "has a default back button" do
|
83
|
+
step_definition.buttons.should include(
|
84
|
+
{ :back => { :label => "Back", :default => true } }
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "re-translates the labels every time it's called" do
|
89
|
+
expect {
|
90
|
+
I18n.stubs(:t).with("wizard.buttons.next",
|
91
|
+
{:default => "Next"}).returns("Foo")
|
92
|
+
}.to change { step_definition.next_button[:label] }.from("Next").to("Foo")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "uses configured button label" do
|
96
|
+
mock_config.stubs(:next_button_label).returns("Click me!")
|
97
|
+
step_definition.next_button[:label].should == "Click me!"
|
98
|
+
end
|
99
|
+
|
100
|
+
it "uses configured button label i18n key" do
|
101
|
+
mock_config.stubs(:next_button_label_i18n_key).returns("wizard.buttons.foo_bar")
|
102
|
+
I18n.stubs(:t).with("wizard.buttons.foo_bar").returns("FooBar")
|
103
|
+
step_definition.next_button[:label].should == "FooBar"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -1,32 +1,41 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe HatTrick::WizardDefinition do
|
4
|
-
|
4
|
+
let(:mock_config) {
|
5
|
+
mock("HatTrick::Config").tap do |mc|
|
6
|
+
mc.stubs(:next_button_label).returns(nil)
|
7
|
+
mc.stubs(:back_button_label).returns(nil)
|
8
|
+
mc.stubs(:next_button_label_i18n_key).returns(nil)
|
9
|
+
mc.stubs(:back_button_label_i18n_key).returns(nil)
|
10
|
+
end
|
11
|
+
}
|
12
|
+
|
13
|
+
subject(:wizard_definition) { HatTrick::WizardDefinition.new(mock_config) }
|
5
14
|
|
6
15
|
it { should be_empty }
|
7
16
|
|
8
17
|
describe "#add_step" do
|
9
18
|
it "should accept a symbol for the step name" do
|
10
|
-
step =
|
19
|
+
step = wizard_definition.add_step(:step1)
|
11
20
|
step.name.should == :step1
|
12
21
|
end
|
13
22
|
|
14
23
|
it "should add a step to the wizard def" do
|
15
|
-
|
16
|
-
|
24
|
+
wizard_definition.add_step(:step1)
|
25
|
+
wizard_definition.should have(1).step
|
17
26
|
end
|
18
27
|
|
19
28
|
it "should update the last_step attr" do
|
20
|
-
step =
|
21
|
-
|
29
|
+
step = wizard_definition.add_step(:step1)
|
30
|
+
wizard_definition.last_step.should == step
|
22
31
|
end
|
23
32
|
end
|
24
33
|
|
25
34
|
describe "#delete_step" do
|
26
35
|
it "should remove the step from the wizard def" do
|
27
|
-
step =
|
28
|
-
|
29
|
-
|
36
|
+
step = wizard_definition.add_step(:goner)
|
37
|
+
wizard_definition.delete_step(step)
|
38
|
+
wizard_definition.steps.should_not include(step)
|
30
39
|
end
|
31
40
|
|
32
41
|
it "should update the the links between surrounding steps" do
|
@@ -1,18 +1,28 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe HatTrick::Wizard do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
let(:mock_config) {
|
5
|
+
mock("HatTrick::Config").tap do |mc|
|
6
|
+
mc.stubs(:next_button_label).returns(nil)
|
7
|
+
mc.stubs(:back_button_label).returns(nil)
|
8
|
+
mc.stubs(:next_button_label_i18n_key).returns(nil)
|
9
|
+
mc.stubs(:back_button_label_i18n_key).returns(nil)
|
10
|
+
end
|
11
|
+
}
|
11
12
|
|
12
|
-
|
13
|
+
let(:wizard_definition) {
|
14
|
+
HatTrick::WizardDefinition.new(mock_config).tap do |wiz_def|
|
15
|
+
wiz_def.add_step(:step1)
|
16
|
+
wiz_def.add_step(:step2)
|
17
|
+
wiz_def.add_step(:step3)
|
18
|
+
wiz_def.add_step(:step4)
|
19
|
+
wiz_def.add_step(:step5)
|
20
|
+
end
|
13
21
|
}
|
14
22
|
|
15
|
-
|
23
|
+
subject(:wizard) {
|
24
|
+
HatTrick::Wizard.new(wizard_definition)
|
25
|
+
}
|
16
26
|
|
17
27
|
before :each do
|
18
28
|
wizard.start
|
@@ -41,11 +51,6 @@ describe HatTrick::Wizard do
|
|
41
51
|
end
|
42
52
|
end
|
43
53
|
|
44
|
-
describe "repeating steps" do
|
45
|
-
it "should repeat step 2 when requested" do
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
54
|
describe "setting explicit next steps" do
|
50
55
|
it "should advance to the requested next step when one is set" do
|
51
56
|
wizard.steps.first.next_step = :step4
|
@@ -56,9 +61,9 @@ describe HatTrick::Wizard do
|
|
56
61
|
|
57
62
|
describe "#previously_visited_step" do
|
58
63
|
it "should return the most recently visited step" do
|
59
|
-
wizard.steps[0].
|
60
|
-
wizard.steps[1].
|
61
|
-
wizard.steps[3].
|
64
|
+
wizard.steps[0].mark_as_visited
|
65
|
+
wizard.steps[1].mark_as_visited
|
66
|
+
wizard.steps[3].mark_as_visited
|
62
67
|
wizard.current_step = :step5
|
63
68
|
wizard.previously_visited_step.to_sym.should == :step4
|
64
69
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -13,6 +13,11 @@ module Rails
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
module ActiveRecord
|
17
|
+
class Base
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
16
21
|
require File.expand_path('../../lib/hat-trick', __FILE__)
|
17
22
|
require 'rspec/autorun'
|
18
23
|
|
@@ -22,4 +27,5 @@ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
|
22
27
|
|
23
28
|
RSpec.configure do |config|
|
24
29
|
config.mock_with :mocha
|
30
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
25
31
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
// MSIE 8 doesn't support Array.prototype.filter
|
2
|
+
// From: http://stackoverflow.com/questions/2722159/javascript-how-to-filter-object-array-based-on-attributes
|
3
|
+
// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter
|
4
|
+
|
5
|
+
if (!Array.prototype.filter) {
|
6
|
+
Array.prototype.filter = function(fun /*, thisp*/) {
|
7
|
+
var len = this.length >>> 0;
|
8
|
+
if (typeof fun != "function")
|
9
|
+
throw new TypeError();
|
10
|
+
|
11
|
+
var res = [];
|
12
|
+
var thisp = arguments[1];
|
13
|
+
for (var i = 0; i < len; i++) {
|
14
|
+
if (i in this) {
|
15
|
+
var val = this[i]; // in case fun mutates this
|
16
|
+
if (fun.call(thisp, val, i, this))
|
17
|
+
res.push(val);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
return res;
|
21
|
+
};
|
22
|
+
}
|