formulaic 0.1.1 → 0.1.2
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.
- 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
|