formulary 0.0.2 → 0.0.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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +65 -34
  3. data/formulary.gemspec +0 -1
  4. data/lib/formulary.rb +1 -5
  5. data/lib/formulary/html_form.rb +31 -13
  6. data/lib/formulary/html_form/fields.rb +16 -0
  7. data/lib/formulary/html_form/fields/checkbox_group.rb +1 -1
  8. data/lib/formulary/html_form/fields/color_input.rb +24 -0
  9. data/lib/formulary/html_form/fields/date_input.rb +59 -0
  10. data/lib/formulary/html_form/fields/email_input.rb +11 -2
  11. data/lib/formulary/html_form/fields/field.rb +15 -3
  12. data/lib/formulary/html_form/fields/field_group.rb +3 -3
  13. data/lib/formulary/html_form/fields/input.rb +1 -1
  14. data/lib/formulary/html_form/fields/month_input.rb +15 -0
  15. data/lib/formulary/html_form/fields/number_input.rb +63 -0
  16. data/lib/formulary/html_form/fields/password_input.rb +7 -0
  17. data/lib/formulary/html_form/fields/range_input.rb +7 -0
  18. data/lib/formulary/html_form/fields/search_input.rb +7 -0
  19. data/lib/formulary/html_form/fields/select.rb +1 -1
  20. data/lib/formulary/html_form/fields/week_input.rb +15 -0
  21. data/lib/formulary/html_form/labels.rb +39 -0
  22. data/lib/formulary/version.rb +1 -1
  23. data/spec/html_form/fields/checkbox_group_spec.rb +23 -10
  24. data/spec/html_form/fields/color_input_spec.rb +58 -0
  25. data/spec/html_form/fields/date_input_spec.rb +60 -0
  26. data/spec/html_form/fields/email_input_spec.rb +16 -6
  27. data/spec/html_form/fields/field_spec.rb +40 -1
  28. data/spec/html_form/fields/hidden_input_spec.rb +3 -1
  29. data/spec/html_form/fields/month_input_spec.rb +60 -0
  30. data/spec/html_form/fields/number_input_spec.rb +67 -0
  31. data/spec/html_form/fields/password_input_spec.rb +29 -0
  32. data/spec/html_form/fields/radio_button_group_spec.rb +27 -8
  33. data/spec/html_form/fields/range_input_spec.rb +20 -0
  34. data/spec/html_form/fields/search_input_spec.rb +18 -0
  35. data/spec/html_form/fields/select_spec.rb +10 -7
  36. data/spec/html_form/fields/tel_input_spec.rb +3 -3
  37. data/spec/html_form/fields/text_input_spec.rb +3 -3
  38. data/spec/html_form/fields/textarea_spec.rb +2 -2
  39. data/spec/html_form/fields/week_input_spec.rb +60 -0
  40. data/spec/html_form_spec.rb +234 -100
  41. data/spec/support/element_helper.rb +1 -1
  42. data/spec/support/shared_examples_for_pattern.rb +4 -2
  43. data/spec/support/shared_examples_for_required.rb +4 -2
  44. metadata +114 -106
@@ -1,10 +1,49 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Formulary::HtmlForm::Fields::Field do
4
+ let(:html_form) { Formulary::HtmlForm.new(markup) }
5
+ let(:field) { Formulary::HtmlForm::Fields::Field.new(html_form, element) }
6
+
4
7
  describe "#name" do
5
- subject { Formulary::HtmlForm::Fields::Field.new(element).name }
8
+ subject { field.name }
6
9
  let(:markup) { %{<input type="text" name="field" />} }
7
10
 
8
11
  it { should eq("field") }
9
12
  end
13
+
14
+ describe "#label" do
15
+ subject { field.label }
16
+
17
+ context "when the there is no label" do
18
+ let(:markup) { %{<input type="text" name="field" />} }
19
+ it { should be_nil }
20
+ end
21
+
22
+ context "when the label is from a singular field" do
23
+ let(:markup) do
24
+ %{
25
+ <label for="field">Field</label>
26
+ <input type="text" id="field" name="field" />
27
+ }
28
+ end
29
+ it { should eql("Field") }
30
+ end
31
+
32
+ context "when the label is for a field group" do
33
+ let(:markup) do
34
+ %{
35
+ <fieldset>
36
+ <legend>Field</legend>
37
+ <label>
38
+ <input type="checkbox" name="field" value="first">
39
+ </label>
40
+ <label>
41
+ <input type="checkbox" name="field" value="second">
42
+ </label>
43
+ </fieldset>
44
+ }
45
+ end
46
+ it { should eql("Field") }
47
+ end
48
+ end
10
49
  end
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Formulary::HtmlForm::Fields::HiddenInput do
4
+ let(:html_form) { Formulary::HtmlForm.new(markup) }
5
+
4
6
  describe ".compatible_with?" do
5
7
  subject { Formulary::HtmlForm::Fields::HiddenInput.compatible_with?(element) }
6
8
  let(:markup) { %{<input type="#{type}" name="name" />} }
@@ -17,7 +19,7 @@ describe Formulary::HtmlForm::Fields::HiddenInput do
17
19
  end
18
20
 
19
21
  describe "validations" do
20
- subject(:input) { Formulary::HtmlForm::Fields::HiddenInput.new(element) }
22
+ subject(:input) { Formulary::HtmlForm::Fields::HiddenInput.new(html_form, element) }
21
23
  let(:markup) { %{<input type="hidden" name="field"></input>} }
22
24
 
23
25
  context "passed a value" do
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe Formulary::HtmlForm::Fields::MonthInput do
4
+ let(:markup_with_label) { "<label for='field'>Field</label>#{markup}" }
5
+ let(:html_form) { Formulary::HtmlForm.new(markup_with_label) }
6
+
7
+ describe ".compatible_with?" do
8
+ subject { Formulary::HtmlForm::Fields::MonthInput.compatible_with?(element) }
9
+ let(:markup) { %{<input type="#{type}" name="name" />} }
10
+
11
+ context "text type" do
12
+ let(:type) { "text" }
13
+ it { should be_false }
14
+ end
15
+
16
+ context "month type" do
17
+ let(:type) { "month" }
18
+ it { should be_true }
19
+ end
20
+ end
21
+
22
+ it_should_behave_like "a field that allows the required attribute" do
23
+ let(:markup_with_required) { %{<input type="month" id="field" name="field" required />} }
24
+ let(:markup_without_required) { %{<input type="month" id="field" name="field" />} }
25
+ let(:valid_value) { "2014-01-01" }
26
+ end
27
+
28
+ describe "validations" do
29
+ subject(:input) { Formulary::HtmlForm::Fields::MonthInput.new(html_form, element) }
30
+ let(:markup) { %{<input type="month" id="field" name="test" min="2013-11" max="2014-02" />} }
31
+
32
+ context "with a valid month" do
33
+ before { input.set_value("2014-01") }
34
+
35
+ it { should be_valid }
36
+ its(:error) { should be_blank }
37
+ end
38
+
39
+ context "with a invalid month" do
40
+ before { input.set_value("1/14") }
41
+
42
+ it { should_not be_valid }
43
+ its(:error) { should eql("'Field' is not a properly formatted month, please use YYYY-MM") }
44
+ end
45
+
46
+ context "with a month less than the min" do
47
+ before { input.set_value("2013-01-01") }
48
+
49
+ it { should_not be_valid }
50
+ its(:error) { should eql("'Field' must be a month after 2013-11") }
51
+ end
52
+
53
+ context "with a month greater than the max" do
54
+ before { input.set_value("2015-01") }
55
+
56
+ it { should_not be_valid }
57
+ its(:error) { should eql("'Field' must be a month before 2014-02") }
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe Formulary::HtmlForm::Fields::NumberInput do
4
+ let(:markup_with_label) { "<label for='field'>Field</label>#{markup}" }
5
+ let(:html_form) { Formulary::HtmlForm.new(markup_with_label) }
6
+
7
+ describe ".compatible_with?" do
8
+ subject { Formulary::HtmlForm::Fields::NumberInput.compatible_with?(element) }
9
+ let(:markup) { %{<input type="#{type}" name="name" />} }
10
+
11
+ context "number type" do
12
+ let(:type) { "number" }
13
+ it { should be_true }
14
+ end
15
+
16
+ context "email type" do
17
+ let(:type) { "email" }
18
+ it { should be_false }
19
+ end
20
+ end
21
+
22
+ describe "validations" do
23
+ subject(:input) { Formulary::HtmlForm::Fields::NumberInput.new(html_form, element) }
24
+ let(:markup) { %{<input type="number" id="field" name="name" min="2" max="10" step="2" />} }
25
+
26
+ context "with a valid number" do
27
+ before { input.set_value("8") }
28
+
29
+ it { should be_valid }
30
+ its(:error) { should be_blank }
31
+ end
32
+
33
+ context "with not a number" do
34
+ before { input.set_value("invalid!") }
35
+
36
+ it { should_not be_valid }
37
+ its(:error) { should eql("'Field' must be a valid number") }
38
+ end
39
+
40
+ context "with a number less than the min" do
41
+ before { input.set_value("0") }
42
+
43
+ it { should_not be_valid }
44
+ its(:error) { should eql("'Field' must be greater than or equal to 2") }
45
+ end
46
+
47
+ context "with a number greater than the max" do
48
+ before { input.set_value("11") }
49
+
50
+ it { should_not be_valid }
51
+ its(:error) { should eql("'Field' must be less than or equal to 10") }
52
+ end
53
+
54
+ context "with a number that does not fit the step" do
55
+ before { input.set_value("7") }
56
+
57
+ it { should_not be_valid }
58
+ its(:error) { should eql("'Field' must be a step of 2, the nearest valid values are 6 and 8") }
59
+ end
60
+ end
61
+
62
+ it_should_behave_like "a field that allows the required attribute" do
63
+ let(:markup_with_required) { %{<input type="number" id="field" name="field" required />} }
64
+ let(:markup_without_required) { %{<input type="number" id="field" name="field" />} }
65
+ let(:valid_value) { "8" }
66
+ end
67
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Formulary::HtmlForm::Fields::PasswordInput do
4
+ describe ".compatible_with?" do
5
+ subject { Formulary::HtmlForm::Fields::PasswordInput.compatible_with?(element) }
6
+ let(:markup) { %{<input type="#{type}" name="name" />} }
7
+
8
+ context "password type" do
9
+ let(:type) { "password" }
10
+ it { should be_true }
11
+ end
12
+
13
+ context "text type" do
14
+ let(:type) { "text" }
15
+ it { should be_false }
16
+ end
17
+ end
18
+
19
+ it_should_behave_like "a field that allows the required attribute" do
20
+ let(:markup_with_required) { %{<input type="password" id="field" name="field" required />} }
21
+ let(:markup_without_required) { %{<input type="password" id="field" name="field" />} }
22
+ let(:valid_value) { "test" }
23
+ end
24
+
25
+ it_should_behave_like "a field that allows the pattern attribute" do
26
+ let(:markup) { %{<input type="password" id="field" name="field" pattern="^test$" />} }
27
+ let(:valid_value) { "test" }
28
+ end
29
+ end
@@ -1,6 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Formulary::HtmlForm::Fields::RadioButtonGroup do
4
+ let(:markup_with_label) do
5
+ "<fieldset><legend>Field</legend>#{markup}</fieldset>"
6
+ end
7
+ let(:html_form) { Formulary::HtmlForm.new(markup_with_label) }
8
+
4
9
  describe ".compatible_with?" do
5
10
  subject { Formulary::HtmlForm::Fields::RadioButtonGroup.compatible_with?(elements) }
6
11
 
@@ -39,12 +44,20 @@ describe Formulary::HtmlForm::Fields::RadioButtonGroup do
39
44
  end
40
45
 
41
46
  describe "validations" do
42
- subject(:radio_group) { Formulary::HtmlForm::Fields::RadioButtonGroup.new("food", elements) }
47
+ subject(:radio_group) do
48
+ Formulary::HtmlForm::Fields::RadioButtonGroup.new(html_form, "food", elements)
49
+ end
43
50
 
44
51
  context "when one of the items in the group is required" do
45
52
  let(:markup) do
46
- %{<input type="radio" name="food" value="bacon" required />
47
- <input type="radio" name="food" value="butter" /> }
53
+ %{
54
+ <label>
55
+ Bacon<input type="radio" name="food" value="bacon" required />
56
+ </label>
57
+ <label>
58
+ Butter<input type="radio" name="food" value="butter" />
59
+ </label>
60
+ }
48
61
  end
49
62
 
50
63
  context "with a valid submission" do
@@ -56,26 +69,32 @@ describe Formulary::HtmlForm::Fields::RadioButtonGroup do
56
69
  context "with a value that isn't expected" do
57
70
  before { radio_group.set_value("eggplant") }
58
71
  it { should_not be_valid }
59
- its(:error) { should include("choose") }
72
+ its(:error) { should eql("'Field' must be chosen from the available options") }
60
73
  end
61
74
 
62
75
  context "with no value" do
63
76
  before { radio_group.set_value("") }
64
77
  it { should_not be_valid }
65
- its(:error) { should include("required") }
78
+ its(:error) { should eql("'Field' is required") }
66
79
  end
67
80
  end
68
81
 
69
82
  context "when none are required" do
70
83
  let(:markup) do
71
- %{<input type="radio" name="food" value="bacon" />
72
- <input type="radio" name="food" value="butter" /> }
84
+ %{
85
+ <label>
86
+ <input type="radio" name="food" value="bacon" />
87
+ </label>
88
+ <label>
89
+ <input type="radio" name="food" value="butter" />
90
+ </label>
91
+ }
73
92
  end
74
93
 
75
94
  context "with a value that isn't expected" do
76
95
  before { radio_group.set_value("eggplant") }
77
96
  it { should_not be_valid }
78
- its(:error) { should include("choose") }
97
+ its(:error) { should eql("'Field' must be chosen from the available options") }
79
98
  end
80
99
 
81
100
  context "with no value" do
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Formulary::HtmlForm::Fields::RangeInput do
4
+ let(:html_form) { Formulary::HtmlForm.new(markup) }
5
+
6
+ describe ".compatible_with?" do
7
+ subject { Formulary::HtmlForm::Fields::RangeInput.compatible_with?(element) }
8
+ let(:markup) { %{<input type="#{type}" name="name" />} }
9
+
10
+ context "range type" do
11
+ let(:type) { "range" }
12
+ it { should be_true }
13
+ end
14
+
15
+ context "email type" do
16
+ let(:type) { "email" }
17
+ it { should be_false }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Formulary::HtmlForm::Fields::SearchInput do
4
+ describe ".compatible_with?" do
5
+ subject { Formulary::HtmlForm::Fields::SearchInput.compatible_with?(element) }
6
+ let(:markup) { %{<input type="#{type}" name="name" />} }
7
+
8
+ context "search type" do
9
+ let(:type) { "search" }
10
+ it { should be_true }
11
+ end
12
+
13
+ context "text type" do
14
+ let(:type) { "text" }
15
+ it { should be_false }
16
+ end
17
+ end
18
+ end
@@ -1,30 +1,33 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Formulary::HtmlForm::Fields::Select do
4
+ let(:markup_with_label) { "<label for='field'>Field</label>#{markup}" }
5
+ let(:html_form) { Formulary::HtmlForm.new(markup_with_label) }
6
+
4
7
  describe ".compatible_with?" do
5
8
  subject { Formulary::HtmlForm::Fields::Select.compatible_with?(element) }
6
9
 
7
10
  context "with a select" do
8
- let(:markup) { %{<select name="name"></select>} }
11
+ let(:markup) { %{<select name="field"></select>} }
9
12
  it { should be_true }
10
13
  end
11
14
 
12
15
  context "with a textarea" do
13
- let(:markup) { %{<textarea name="name"></textarea>} }
16
+ let(:markup) { %{<textarea name="field"></textarea>} }
14
17
  it { should be_false }
15
18
  end
16
19
 
17
20
  context "with an input type" do
18
- let(:markup) { %{<input type="text" name="name" />} }
21
+ let(:markup) { %{<input type="text" name="field" />} }
19
22
  it { should be_false }
20
23
  end
21
24
  end
22
25
 
23
26
  describe "validations" do
24
- subject(:input) { Formulary::HtmlForm::Fields::Select.new(element) }
27
+ subject(:input) { Formulary::HtmlForm::Fields::Select.new(html_form, element) }
25
28
  let(:markup) do
26
29
  <<-EOS
27
- <select name="name">
30
+ <select id="field" name="field">
28
31
  <option>First Text</option>
29
32
  <option value="second_value">Second Text</option>
30
33
  </select>
@@ -49,14 +52,14 @@ describe Formulary::HtmlForm::Fields::Select do
49
52
  before { input.set_value("Second Text") }
50
53
 
51
54
  it { should_not be_valid }
52
- its(:error) { should include("choose") }
55
+ its(:error) { should eql("'Field' must be chosen from the available options") }
53
56
  end
54
57
 
55
58
  context "passed a value that is not in the options" do
56
59
  before { input.set_value("unknown") }
57
60
 
58
61
  it { should_not be_valid }
59
- its(:error) { should include("choose") }
62
+ its(:error) { should eql("'Field' must be chosen from the available options") }
60
63
  end
61
64
  end
62
65
  end
@@ -17,13 +17,13 @@ describe Formulary::HtmlForm::Fields::TelInput do
17
17
  end
18
18
 
19
19
  it_should_behave_like "a field that allows the required attribute" do
20
- let(:markup_with_required) { %{<input type="tel" name="field" required />} }
21
- let(:markup_without_required) { %{<input type="tel" name="field" />} }
20
+ let(:markup_with_required) { %{<input type="tel" id="field" name="field" required />} }
21
+ let(:markup_without_required) { %{<input type="tel" id="field" name="field" />} }
22
22
  let(:valid_value) { "123-123-1234" }
23
23
  end
24
24
 
25
25
  it_should_behave_like "a field that allows the pattern attribute" do
26
- let(:markup) { '<input type="tel" name="field" pattern="\d{3}-\d{3}-\d{4}" />' }
26
+ let(:markup) { '<input type="tel" id="field" name="field" pattern="\d{3}-\d{3}-\d{4}" />' }
27
27
  let(:valid_value) { "123-123-1234" }
28
28
  end
29
29
  end
@@ -17,13 +17,13 @@ describe Formulary::HtmlForm::Fields::TextInput do
17
17
  end
18
18
 
19
19
  it_should_behave_like "a field that allows the required attribute" do
20
- let(:markup_with_required) { %{<input type="text" name="field" required />} }
21
- let(:markup_without_required) { %{<input type="text" name="field" />} }
20
+ let(:markup_with_required) { %{<input type="text" id="field" name="field" required />} }
21
+ let(:markup_without_required) { %{<input type="text" id="field" name="field" />} }
22
22
  let(:valid_value) { "test" }
23
23
  end
24
24
 
25
25
  it_should_behave_like "a field that allows the pattern attribute" do
26
- let(:markup) { %{<input type="text" name="field" pattern="^test$" />} }
26
+ let(:markup) { %{<input type="text" id="field" name="field" pattern="^test$" />} }
27
27
  let(:valid_value) { "test" }
28
28
  end
29
29
  end
@@ -21,8 +21,8 @@ describe Formulary::HtmlForm::Fields::Textarea do
21
21
  end
22
22
 
23
23
  it_should_behave_like "a field that allows the required attribute" do
24
- let(:markup_with_required) { %{<textarea name="field" required></textarea>} }
25
- let(:markup_without_required) { %{<textarea name="field"></textarea>} }
24
+ let(:markup_with_required) { %{<textarea id="field" name="field" required></textarea>} }
25
+ let(:markup_without_required) { %{<textarea id="field" name="field"></textarea>} }
26
26
  let(:valid_value) { "test" }
27
27
  end
28
28
  end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe Formulary::HtmlForm::Fields::WeekInput do
4
+ let(:markup_with_label) { "<label for='field'>Field</label>#{markup}" }
5
+ let(:html_form) { Formulary::HtmlForm.new(markup_with_label) }
6
+
7
+ describe ".compatible_with?" do
8
+ subject { Formulary::HtmlForm::Fields::WeekInput.compatible_with?(element) }
9
+ let(:markup) { %{<input type="#{type}" name="name" />} }
10
+
11
+ context "text type" do
12
+ let(:type) { "text" }
13
+ it { should be_false }
14
+ end
15
+
16
+ context "week type" do
17
+ let(:type) { "week" }
18
+ it { should be_true }
19
+ end
20
+ end
21
+
22
+ it_should_behave_like "a field that allows the required attribute" do
23
+ let(:markup_with_required) { %{<input type="week" id="field" name="field" required />} }
24
+ let(:markup_without_required) { %{<input type="week" id="field" name="field" />} }
25
+ let(:valid_value) { "2014-W01" }
26
+ end
27
+
28
+ describe "validations" do
29
+ subject(:input) { Formulary::HtmlForm::Fields::WeekInput.new(html_form, element) }
30
+ let(:markup) { %{<input type="week" id="field" name="test" min="2013-W01" max="2014-W52" />} }
31
+
32
+ context "with a valid week" do
33
+ before { input.set_value("2014-W01") }
34
+
35
+ it { should be_valid }
36
+ its(:error) { should be_blank }
37
+ end
38
+
39
+ context "with a invalid week" do
40
+ before { input.set_value("1/44") }
41
+
42
+ it { should_not be_valid }
43
+ its(:error) { should eql("'Field' is not a properly formatted week, please use YYYY-W##") }
44
+ end
45
+
46
+ context "with a week less than the min" do
47
+ before { input.set_value("2012-W01") }
48
+
49
+ it { should_not be_valid }
50
+ its(:error) { should eql("'Field' must be a week after 2013-W01") }
51
+ end
52
+
53
+ context "with a week greater than the max" do
54
+ before { input.set_value("2015-W01") }
55
+
56
+ it { should_not be_valid }
57
+ its(:error) { should eql("'Field' must be a week before 2014-W52") }
58
+ end
59
+ end
60
+ end