formulaic 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/formulaic/inputs/array_input.rb +32 -1
- data/lib/formulaic/inputs/checkbox_input.rb +36 -0
- data/lib/formulaic/inputs/select_input.rb +37 -0
- data/lib/formulaic/label.rb +2 -2
- data/lib/formulaic/version.rb +1 -1
- data/spec/features/fill_in_user_form_spec.rb +52 -0
- data/spec/fixtures/user_form.html +37 -7
- data/spec/spec_helper.rb +8 -6
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46041f49475675c4e48824b44f5a4825f1e0a2c6
|
4
|
+
data.tar.gz: 5ff5c7da932bbad514632342cf19f84a45778b38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07e7b143f6ef68deedac88596f213d42dee31ce1b84079dc1855ee33c8eb554babae2742ee3fc65be8f85996c9a8b310bcc628a3385b529ef4fbdc09d53f44d3
|
7
|
+
data.tar.gz: f0efb3b62c2580f2fcad9618b1d59e77fd2872ce22f7884d0fbd7b283b9e9732f3f4b2ab43d27cfcf934aef0e42133f3c129bf190262124df582144833aa1451
|
data/README.md
CHANGED
@@ -150,7 +150,7 @@ around `I18n.t`.
|
|
150
150
|
| `Date`, `ActiveSupport::TimeWithZone` | `select` year, month, and day |
|
151
151
|
| `TrueClass` | `check` |
|
152
152
|
| `FalseClass` | `uncheck` |
|
153
|
-
| `Array` | `check` each array member, which should all be strings
|
153
|
+
| `Array` | `check` or `select` each array member, which should all be strings. If not all items can be selected or checked, an error will be thrown.|
|
154
154
|
| `File` | `attach_file` with `File#path` |
|
155
155
|
|
156
156
|
* Formulaic is currently tied to `simple_form` translations and field structure.
|
@@ -1,9 +1,40 @@
|
|
1
1
|
module Formulaic
|
2
2
|
module Inputs
|
3
3
|
class ArrayInput < Input
|
4
|
+
def initialize(label, value)
|
5
|
+
@label = label
|
6
|
+
@value = value
|
7
|
+
end
|
8
|
+
|
4
9
|
def fill
|
5
|
-
|
10
|
+
attempt_to_fill_selects ||
|
11
|
+
attempt_to_fill_checkboxes ||
|
12
|
+
raise_input_error
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def attempt_to_fill_selects
|
18
|
+
SelectInput.new(label, value).fill
|
19
|
+
end
|
20
|
+
|
21
|
+
def attempt_to_fill_checkboxes
|
22
|
+
CheckboxInput.new(label, value).fill
|
23
|
+
end
|
24
|
+
|
25
|
+
def contains_all_options?(nodes)
|
26
|
+
nodes.map(&:text).to_set.superset?(value.to_set)
|
27
|
+
end
|
28
|
+
|
29
|
+
def raise_input_error
|
30
|
+
raise(
|
31
|
+
InputNotFound,
|
32
|
+
%[Unable to find checkboxes or select[multiple] "#{label}" containing all options #{value.inspect}.]
|
33
|
+
)
|
6
34
|
end
|
7
35
|
end
|
8
36
|
end
|
9
37
|
end
|
38
|
+
|
39
|
+
require 'formulaic/inputs/checkbox_input'
|
40
|
+
require 'formulaic/inputs/select_input'
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Formulaic
|
2
|
+
module Inputs
|
3
|
+
class CheckboxInput < ArrayInput
|
4
|
+
def fill
|
5
|
+
if has_check_boxes?
|
6
|
+
check_boxes
|
7
|
+
true
|
8
|
+
else
|
9
|
+
false
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def has_check_boxes?
|
16
|
+
contains_all_options?(checkbox_labels)
|
17
|
+
end
|
18
|
+
|
19
|
+
def check_boxes
|
20
|
+
value.each { |checkbox| check checkbox }
|
21
|
+
end
|
22
|
+
|
23
|
+
def checkbox_labels
|
24
|
+
all(checkbox_labels_selector)
|
25
|
+
end
|
26
|
+
|
27
|
+
def checkbox_name_selector
|
28
|
+
"input[type='checkbox'][name='#{label.model_name}[#{label.attribute}][]']"
|
29
|
+
end
|
30
|
+
|
31
|
+
def checkbox_labels_selector
|
32
|
+
"#{checkbox_name_selector} ~ label,label:has(#{checkbox_name_selector})"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Formulaic
|
2
|
+
module Inputs
|
3
|
+
class SelectInput < ArrayInput
|
4
|
+
def fill
|
5
|
+
if has_multiple_select?
|
6
|
+
select_options
|
7
|
+
true
|
8
|
+
else
|
9
|
+
false
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def select_options
|
16
|
+
value.each { |option| select option, from: label.to_str }
|
17
|
+
end
|
18
|
+
|
19
|
+
def has_multiple_select?
|
20
|
+
has_select? && select_is_multiple?
|
21
|
+
end
|
22
|
+
|
23
|
+
def has_select?
|
24
|
+
has_field?(label, type: "select")
|
25
|
+
end
|
26
|
+
|
27
|
+
def select_is_multiple?
|
28
|
+
select_element[:multiple].present? &&
|
29
|
+
contains_all_options?(select_element.all("option"))
|
30
|
+
end
|
31
|
+
|
32
|
+
def select_element
|
33
|
+
@select_element ||= find_field(label, type: "select")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/formulaic/label.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Formulaic
|
2
2
|
class Label
|
3
|
+
attr_reader :model_name, :attribute, :action
|
4
|
+
|
3
5
|
def initialize(model_name, attribute, action)
|
4
6
|
@model_name = model_name
|
5
7
|
@attribute = attribute
|
@@ -17,8 +19,6 @@ module Formulaic
|
|
17
19
|
|
18
20
|
private
|
19
21
|
|
20
|
-
attr_reader :model_name, :attribute, :action
|
21
|
-
|
22
22
|
def translate
|
23
23
|
I18n.t(lookup_paths.first, scope: :'simple_form.labels', default: lookup_paths).presence
|
24
24
|
end
|
data/lib/formulaic/version.rb
CHANGED
@@ -88,6 +88,58 @@ describe 'Fill in user form' do
|
|
88
88
|
expect(input(:user, :age).value).to eq '10'
|
89
89
|
end
|
90
90
|
|
91
|
+
it 'raises a useful error if selecting multiple from a normal select' do
|
92
|
+
visit 'user_form'
|
93
|
+
form = Formulaic::Form.new(:user, :new, awesome: ['Yes', 'No'])
|
94
|
+
|
95
|
+
expect { form.fill }
|
96
|
+
.to raise_error(
|
97
|
+
Formulaic::InputNotFound,
|
98
|
+
'Unable to find checkboxes or select[multiple] "Are you awesome?" containing all options ["Yes", "No"].'
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'raises a useful error if not all select options are present' do
|
103
|
+
visit 'user_form'
|
104
|
+
form = Formulaic::Form.new(:user, :new, likes: ['Ruby', 'Perl'])
|
105
|
+
|
106
|
+
expect { form.fill }
|
107
|
+
.to raise_error(
|
108
|
+
Formulaic::InputNotFound,
|
109
|
+
'Unable to find checkboxes or select[multiple] "Your Likes" containing all options ["Ruby", "Perl"].'
|
110
|
+
)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'selects an array of strings' do
|
114
|
+
visit 'user_form'
|
115
|
+
form = Formulaic::Form.new(:user, :new, likes: ['Ruby', 'Rails'])
|
116
|
+
|
117
|
+
form.fill
|
118
|
+
|
119
|
+
expect(input(:user, :likes).value).to eq ['ruby', 'rails']
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'raises a useful error if not all checkboxes are present' do
|
123
|
+
visit 'user_form'
|
124
|
+
form = Formulaic::Form.new(:user, :new, dislikes: ['Java', 'Go'])
|
125
|
+
|
126
|
+
expect { form.fill }
|
127
|
+
.to raise_error(
|
128
|
+
Formulaic::InputNotFound,
|
129
|
+
'Unable to find checkboxes or select[multiple] "Your Dislikes" containing all options ["Java", "Go"].'
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'selects an array of checkboxes' do
|
134
|
+
visit 'user_form'
|
135
|
+
form = Formulaic::Form.new(:user, :new, dislikes: ['Java', 'PHP'])
|
136
|
+
|
137
|
+
form.fill
|
138
|
+
|
139
|
+
expect(page).to have_checked_field "Java"
|
140
|
+
expect(page).to have_checked_field "PHP"
|
141
|
+
end
|
142
|
+
|
91
143
|
it 'selects a string if there is no input' do
|
92
144
|
visit 'user_form'
|
93
145
|
form = Formulaic::Form.new(:user, :new, awesome: 'Yes')
|
@@ -1,12 +1,17 @@
|
|
1
1
|
<form accept-charset="UTF-8" action="/users" class="simple_form new_user" id="new_user" method="post" novalidate="novalidate">
|
2
2
|
<div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"><input name="authenticity_token" type="hidden" value="O6ORla31JvEaWroCuiA7bArM15ztDotMfPAbNW0v61g="></div>
|
3
|
-
<div class="input string required user_name"><label class="string required"
|
4
|
-
|
3
|
+
<div class="input string required user_name"><label class="string required"
|
4
|
+
for="user_name"><abbr title="required">*</abbr> Your Display name</label><input class="string required" id="user_name" maxlength="255" name="user[name]" size="50" type="text"></div>
|
5
|
+
<div class="input email required user_email"><label class="email required"
|
6
|
+
for="user_email"><abbr title="required">*</abbr> Your Email</label><input class="string email required" id="user_email" maxlength="255" name="user[email]" size="50" type="email"></div>
|
5
7
|
<div class="input tel required user_phone"><label class="tel required" for="user_phone"><abbr title="required">*</abbr> Phone Number</label><input class="string phone required" id="user_phone" maxlength="255" name="user[phone]" size="50" type="tel"></div>
|
6
|
-
<div class="input integer required user_age"><label class="integer required"
|
8
|
+
<div class="input integer required user_age"><label class="integer required"
|
9
|
+
for="user_age"><abbr title="required">*</abbr> Your Age</label><input class="numeric integer age required" id="user_age" maxlength="255" name="user[age]" size="50" type="number"></div>
|
7
10
|
<div class="input url required user_url"><label class="tel required" for="user_url"><abbr title="required">*</abbr> Website</label><input class="string url required" id="user_url" maxlength="255" name="user[url]" size="50" type="url"></div>
|
8
|
-
<div class="input file optional user_avatar"><label class="file optional"
|
9
|
-
|
11
|
+
<div class="input file optional user_avatar"><label class="file optional"
|
12
|
+
for="user_avatar">Your Avatar</label><input class="file optional" id="user_avatar" name="user[avatar]" type="file" /></div>
|
13
|
+
<div class="input password optional user_password"><label class="password
|
14
|
+
optional" for="user_password">Your Password</label><input class="password optional" id="user_password" name="user[password]" size="50" type="password"></div>
|
10
15
|
<div class="input select required user_awesome">
|
11
16
|
<label class="select required" for="user_awesome"><abbr title="required">*</abbr> Are you awesome?</label>
|
12
17
|
<select class="select required" id="user_awesome" name="user[awesome]">
|
@@ -15,9 +20,34 @@
|
|
15
20
|
<option value="false">No</option>
|
16
21
|
</select>
|
17
22
|
</div>
|
18
|
-
<div class="input
|
23
|
+
<div class="input select user_likes">
|
24
|
+
<label class="select" for="user_likes">Your Likes</label>
|
25
|
+
<select class="select" id="user_likes" name="user[likes][]" multiple>
|
26
|
+
<option value=""></option>
|
27
|
+
<option value="ruby">Ruby</option>
|
28
|
+
<option value="rails">Rails</option>
|
29
|
+
<option value="git">Git</option>
|
30
|
+
</select>
|
31
|
+
</div>
|
32
|
+
<div class="input check_boxes optional user_dislikes">
|
33
|
+
<label class="check_boxes optional">Your Dislikes</label>
|
34
|
+
<span class="checkbox">
|
35
|
+
<input class="check_boxes optional" id="user_dislikes_1" name="user[dislikes][]" type="checkbox" value="java">
|
36
|
+
<label class="collection_check_boxes" for="user_dislikes_1">Java</label>
|
37
|
+
</span>
|
38
|
+
<span class="checkbox">
|
39
|
+
<label class="collection_check_boxes" for="user_dislikes_2">
|
40
|
+
PHP
|
41
|
+
<input class="check_boxes optional" id="user_dislikes_2" name="user[dislikes][]" type="checkbox" value="php">
|
42
|
+
</label>
|
43
|
+
</span>
|
44
|
+
<input name="user[dislikes][]" type="hidden" value="">
|
45
|
+
</div>
|
46
|
+
<div class="input text required user_bio"><label class="text required"
|
47
|
+
for="user_bio"><abbr title="required">*</abbr> Your Biography</label><textarea class="text required" cols="40" id="user_bio" name="user[bio]" rows="20" style="overflow: hidden; word-wrap: break-word; resize: horizontal; height: 464px;"></textarea></div>
|
19
48
|
<div class="input date required user_date_of_birth">
|
20
|
-
<label class="date required" for="user_date_of_birth_1i"><abbr
|
49
|
+
<label class="date required" for="user_date_of_birth_1i"><abbr
|
50
|
+
title="required">*</abbr> Your Date of birth</label>
|
21
51
|
<select class="date required" id="user_date_of_birth_1i" name="user[date_of_birth(1i)]">
|
22
52
|
<option value="2001">2001</option>
|
23
53
|
<option value="2000">2000</option>
|
data/spec/spec_helper.rb
CHANGED
@@ -21,15 +21,17 @@ module SpecHelper
|
|
21
21
|
simple_form:
|
22
22
|
labels:
|
23
23
|
user:
|
24
|
-
age: Age
|
25
|
-
avatar: Avatar
|
24
|
+
age: Your Age
|
25
|
+
avatar: Your Avatar
|
26
26
|
awesome: Are you awesome?
|
27
27
|
bio: Biography
|
28
|
-
date_of_birth: Date of birth
|
29
|
-
|
30
|
-
|
28
|
+
date_of_birth: Your Date of birth
|
29
|
+
likes: Your Likes
|
30
|
+
dislikes: Your Dislikes
|
31
|
+
email: Your Email
|
32
|
+
name: Your Display name
|
31
33
|
new:
|
32
|
-
password: Password
|
34
|
+
password: Your Password
|
33
35
|
phone: Phone Number
|
34
36
|
terms_of_service: I agree to the Terms of Service
|
35
37
|
url: Website
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formulaic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Caleb Thompson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capybara
|
@@ -136,9 +136,11 @@ files:
|
|
136
136
|
- lib/formulaic/inputs.rb
|
137
137
|
- lib/formulaic/inputs/array_input.rb
|
138
138
|
- lib/formulaic/inputs/boolean_input.rb
|
139
|
+
- lib/formulaic/inputs/checkbox_input.rb
|
139
140
|
- lib/formulaic/inputs/date_input.rb
|
140
141
|
- lib/formulaic/inputs/file_input.rb
|
141
142
|
- lib/formulaic/inputs/input.rb
|
143
|
+
- lib/formulaic/inputs/select_input.rb
|
142
144
|
- lib/formulaic/inputs/string_input.rb
|
143
145
|
- lib/formulaic/label.rb
|
144
146
|
- lib/formulaic/version.rb
|