formulaic 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.
- checksums.yaml +4 -4
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CONTRIBUTING.md +39 -0
- data/Gemfile +1 -1
- data/{LICENSE.txt → LICENSE} +1 -1
- data/README.md +115 -17
- data/Rakefile +1 -1
- data/formulaic.gemspec +23 -14
- data/lib/formulaic.rb +10 -0
- data/lib/formulaic/dsl.rb +11 -0
- data/lib/formulaic/form.rb +45 -0
- data/lib/formulaic/inputs.rb +5 -0
- data/lib/formulaic/inputs/array_input.rb +9 -0
- data/lib/formulaic/inputs/boolean_input.rb +13 -0
- data/lib/formulaic/inputs/date_input.rb +18 -0
- data/lib/formulaic/inputs/input.rb +24 -0
- data/lib/formulaic/inputs/string_input.rb +19 -0
- data/lib/formulaic/label.rb +51 -0
- data/lib/formulaic/version.rb +3 -0
- data/spec/features/fill_in_user_form_spec.rb +62 -0
- data/spec/fixtures/user_form.html +171 -0
- data/spec/formulaic/dsl_spec.rb +17 -0
- data/spec/formulaic/form_spec.rb +7 -0
- data/spec/formulaic/label_spec.rb +31 -0
- data/spec/spec_helper.rb +38 -0
- metadata +107 -10
- data/lib/formualic.rb +0 -5
- data/lib/formualic/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6bef13aba12616219a2a8e5f254c3298ec6c00c8
|
4
|
+
data.tar.gz: c1eb43ca79ac45e3b9121f402dc1b74ff99ca809
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16362b7ff583f4a85b68608d21eb77b605045a28b3305ba01fe8b0bc84e74155498991ca1d6d6a9b03a507929a59d7f4a0fa401d9c8064446a33c5ad5de8c032
|
7
|
+
data.tar.gz: 756dcffdc59c4219e50f717b08f0f41a5e70930e50cb4cc6d094c020909f64776ace0638c7ebafc1b7b15560ef8e4d36e94edb1b99c40202b90f666845cfec94
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
formulaic
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.0.0-p195
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
We love pull requests. Here's a quick guide:
|
4
|
+
|
5
|
+
1. Fork the repo.
|
6
|
+
2. Run the tests. We only take pull requests with passing tests, and it's great
|
7
|
+
to know that you have a clean slate: `bundle && rake`
|
8
|
+
3. Add a test for your change. Only refactoring and documentation changes
|
9
|
+
require no new tests. If you are adding functionality or fixing a bug, we need
|
10
|
+
a test!
|
11
|
+
4. Make the test pass.
|
12
|
+
5. Make sure your changes adhere to the [thoughtbot Style
|
13
|
+
Guide](https://github.com/thoughtbot/guides/tree/master/style)
|
14
|
+
6. Push to your fork and submit a pull request.
|
15
|
+
7. At this point you're waiting on us. We like to at least comment on, if not
|
16
|
+
accept, pull requests within three business days (and, typically, one business
|
17
|
+
day). [We may suggest some changes or improvements or
|
18
|
+
alternatives](https://github.com/thoughtbot/guides/tree/master/code-review).
|
19
|
+
|
20
|
+
## Increase your chances of getting merged
|
21
|
+
|
22
|
+
Some things that will increase the chance that your pull request is accepted,
|
23
|
+
taken straight from the Ruby on Rails guide:
|
24
|
+
|
25
|
+
* Use Rails idioms and helpers
|
26
|
+
* Include tests that fail without your code, and pass with it
|
27
|
+
* Update the documentation: that surrounding your change, examples elsewhere,
|
28
|
+
guides, and whatever else is affected by your contribution
|
29
|
+
* Syntax:
|
30
|
+
* Two spaces, no tabs.
|
31
|
+
* No trailing whitespace. Blank lines should not have any space.
|
32
|
+
* Make sure your [source files end with newline
|
33
|
+
characters](http://stackoverflow.com/questions/729692/why-should-files-end-with-a-newline#answer-729725).
|
34
|
+
* Prefer `&&`/`||` over `and`/`or`.
|
35
|
+
* `MyClass.my_method(my_arg)` not `my_method( my_arg )` or
|
36
|
+
`my_method my_arg`.
|
37
|
+
* `a = b` and not `a=b`.
|
38
|
+
* Follow the conventions you see used in the source already.
|
39
|
+
* And in case we didn't emphasize it enough: *We love tests!*
|
data/Gemfile
CHANGED
data/{LICENSE.txt → LICENSE}
RENAMED
data/README.md
CHANGED
@@ -1,29 +1,127 @@
|
|
1
|
-
#
|
1
|
+
# Formulaic
|
2
2
|
|
3
|
-
|
3
|
+
Remove the tedium of formulaic form filling with Capybara.
|
4
4
|
|
5
|
-
|
5
|
+
Formulaic allows you to specify a hash of attributes to be input rather than
|
6
|
+
procedurally calling Capybara’s DSL methods.
|
6
7
|
|
7
|
-
|
8
|
+
## Usage
|
8
9
|
|
9
|
-
|
10
|
+
```ruby
|
11
|
+
feature 'New user registration' do
|
12
|
+
scenario 'succesfull sign up' do
|
13
|
+
visit sign_in_path
|
10
14
|
|
11
|
-
|
15
|
+
fill_form(:user, { name: 'Caleb', email: 'caleb@thoughtbot.com', 'Terms of Service': true })
|
16
|
+
click_on submit(:user)
|
12
17
|
|
13
|
-
|
18
|
+
expect(page).to have_content t('user.create.success')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
```
|
14
22
|
|
15
|
-
Or install it yourself as:
|
16
23
|
|
17
|
-
|
24
|
+
### `fill_form`
|
18
25
|
|
19
|
-
|
26
|
+
```ruby
|
27
|
+
fill_form(model_name, attributes)
|
28
|
+
```
|
29
|
+
|
30
|
+
`fill_form` provides an interface to completely filling out a form. Provide the
|
31
|
+
`model_name` as a symbol and `attributes` as a hash of
|
32
|
+
`column name => database value` or `label string => database value`.
|
33
|
+
|
34
|
+
If an `attributes` key is a `String`, it will be used as the literal label.
|
35
|
+
For `Symbol` we will attempt to translate, fall back to `human_attribute_name`
|
36
|
+
if available, then call `to_s`.
|
37
|
+
|
38
|
+
### `input`
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
input(model_name, field)
|
42
|
+
```
|
43
|
+
|
44
|
+
`input` gives an easy way to find the translated text of an input. It is
|
45
|
+
primarily used internally to fill `<input>`s, but is provided in the public API
|
46
|
+
as it could be useful.
|
47
|
+
|
48
|
+
### `submit`
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
submit(model_name, action = :create)
|
52
|
+
```
|
53
|
+
|
54
|
+
`submit` functions like [`input`](#input), but finds the translation for the
|
55
|
+
submit button of the form. `model_name` should be the same as what you provide
|
56
|
+
to [`fill_form`](#fill\_form). Typically, the return value of `submit` will be
|
57
|
+
passed directly to Capybara’s `click_on` method.
|
58
|
+
|
59
|
+
If you are submitting a form that is not for the `create` action, you may need
|
60
|
+
to pass the `action`:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
submit(:user, :update)
|
64
|
+
```
|
65
|
+
|
66
|
+
The `model_name` and `action` should match up to the
|
67
|
+
`helpers.submit.<model_name>.<action>` translations.
|
68
|
+
|
69
|
+
### Integration with RSpec:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
# spec/spec_helper.rb
|
73
|
+
|
74
|
+
RSpec.configure do |config|
|
75
|
+
config.include Formulaic::Dsl
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
### Integration with [FactoryGirl](https://github.com/thoughtbot/factory_girl)
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
fill_form(:user, attributes_for(:user))
|
83
|
+
```
|
84
|
+
|
85
|
+
You may have attributes included in your `User` factory that don’t pretain to
|
86
|
+
sign up:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
fill_form(:user, attributes_for(:user).slice(sign_up_attributes))
|
90
|
+
|
91
|
+
# ...
|
92
|
+
def sign_up_attributes
|
93
|
+
[:name, :email, :terms_of_service]
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
97
|
+
## Known Limitations
|
98
|
+
|
99
|
+
* Formulaic currently supports the following mappings from the `#class` of the
|
100
|
+
attribute values to Capybara method calls:
|
101
|
+
|
102
|
+
| Classes | Formulaic’s action |
|
103
|
+
| --------------------------------------|-------------------------------|
|
104
|
+
| `String` | `fill_in` |
|
105
|
+
| `Date`, `ActiveSupport::TimeWithZone` | `select` year, month, and day |
|
106
|
+
| `TrueClass` | `check` |
|
107
|
+
| `FalseClass` | `uncheck` |
|
108
|
+
| `Array` | `check` each array member, which should all be strings |
|
109
|
+
|
110
|
+
* Formulaic is currently tied to `simple_form` translations and field structure.
|
111
|
+
If you pass a string for the attribute, we’ll try to fill the input that
|
112
|
+
relates to that label. We would be happy to work with you to add support for
|
113
|
+
other form builders.
|
114
|
+
* Formulaic currently does not support forms with duplicate labels, as it is
|
115
|
+
designed to be as similar as possible to a user completing a form—it looks at
|
116
|
+
the labels to determine where to fill what data.
|
117
|
+
* Formulaic can’t figure out how to fill fields with HTML labels:
|
118
|
+
`page.fill_in('<strong>Text</strong> here', with: 'something')` doesn’t work
|
119
|
+
with Capybara. The usual workaround is to pass a CSS selector.
|
20
120
|
|
21
|
-
|
121
|
+
## About
|
22
122
|
|
23
|
-
|
123
|
+
Formulaic is maintained by [Caleb Thompson](http://github.com/calebthompson).
|
124
|
+
It was written by [thoughtbot](http://thoughtbot.com) with the help of our
|
125
|
+
[contributors](http://github.com/thoughtbot/formulaic/contributors).
|
24
126
|
|
25
|
-
|
26
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
-
5. Create new Pull Request
|
127
|
+
[](http://thoughtbot.com)
|
data/Rakefile
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
data/formulaic.gemspec
CHANGED
@@ -1,23 +1,32 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require '
|
4
|
+
require 'formulaic/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
-
spec.version =
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.
|
12
|
-
spec.
|
13
|
-
|
14
|
-
|
7
|
+
spec.name = 'formulaic'
|
8
|
+
spec.version = Formulaic::VERSION
|
9
|
+
spec.authors = ['Caleb Thompson']
|
10
|
+
spec.email = ['caleb@calebthompson.io']
|
11
|
+
spec.summary = 'Simplify form filling with Capybara'
|
12
|
+
spec.description = <<-DESCRIPTION.sub(/^ +/, '')
|
13
|
+
Removes the tedium of formulaic form filling with Capybara by allowing you
|
14
|
+
to specify a hash of attributes to be input rather than procedurally calling
|
15
|
+
Capybara’s DSL methods.
|
16
|
+
DESCRIPTION
|
17
|
+
spec.homepage = 'https://github.com/thoughtbot/formulaic'
|
18
|
+
spec.license = 'MIT'
|
15
19
|
|
16
20
|
spec.files = `git ls-files`.split($/)
|
17
|
-
spec.
|
18
|
-
spec.
|
19
|
-
spec.require_paths = ["lib"]
|
21
|
+
spec.test_files = spec.files.grep(%r{^spec/})
|
22
|
+
spec.require_paths = ['lib']
|
20
23
|
|
21
|
-
spec.
|
22
|
-
spec.
|
24
|
+
spec.add_dependency 'capybara'
|
25
|
+
spec.add_dependency 'i18n'
|
26
|
+
spec.add_dependency 'activesupport'
|
27
|
+
|
28
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
29
|
+
spec.add_development_dependency 'rake'
|
30
|
+
spec.add_development_dependency 'rspec'
|
31
|
+
spec.add_development_dependency 'pry'
|
23
32
|
end
|
data/lib/formulaic.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'active_support/time_with_zone'
|
2
|
+
|
3
|
+
module Formulaic
|
4
|
+
class Form
|
5
|
+
ATTRIBUTE_INPUT_MAP = {
|
6
|
+
ActiveSupport::TimeWithZone => Formulaic::Inputs::DateInput,
|
7
|
+
Date => Formulaic::Inputs::DateInput,
|
8
|
+
Array => Formulaic::Inputs::ArrayInput,
|
9
|
+
String => Formulaic::Inputs::StringInput,
|
10
|
+
TrueClass => Formulaic::Inputs::BooleanInput,
|
11
|
+
FalseClass => Formulaic::Inputs::BooleanInput,
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
def initialize(model_name, attributes)
|
15
|
+
@inputs = build_inputs(model_name, attributes)
|
16
|
+
@session = session
|
17
|
+
end
|
18
|
+
|
19
|
+
def fill
|
20
|
+
@inputs.each { |input| input.fill }
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :session, :model_name, :inputs
|
26
|
+
|
27
|
+
def build_inputs(model_name, attributes)
|
28
|
+
attributes.map do |field, value|
|
29
|
+
build_input(model_name, field, value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def build_input(model_name, field, value)
|
34
|
+
input_class_for(value).new(model_name, field, value)
|
35
|
+
end
|
36
|
+
|
37
|
+
def input_class_for(value)
|
38
|
+
ATTRIBUTE_INPUT_MAP.fetch(value.class) do
|
39
|
+
raise InvalidAttributeTypeError.new("Formulaic does not know how to fill in a #{value.class} value")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class InvalidAttributeTypeError < StandardError; end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Formulaic
|
2
|
+
module Inputs
|
3
|
+
class DateInput < Input
|
4
|
+
def fill
|
5
|
+
select_date(value, from: input(model_name, field))
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def select_date(date, options)
|
11
|
+
field = find_field(options[:from].to_s)["id"].gsub(/_1i/, "")
|
12
|
+
select date.year.to_s, from: "#{field}_1i"
|
13
|
+
select Date::MONTHNAMES[date.month], from: "#{field}_2i"
|
14
|
+
select date.day.to_s, from: "#{field}_3i"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
require 'capybara/dsl'
|
3
|
+
|
4
|
+
module Formulaic
|
5
|
+
module Inputs
|
6
|
+
class Input
|
7
|
+
include Capybara::DSL
|
8
|
+
|
9
|
+
def initialize(model_name, field, value)
|
10
|
+
@model_name = model_name
|
11
|
+
@field = field
|
12
|
+
@value = value
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def input(model_name, field, action = :create)
|
18
|
+
Label.new(model_name, field, action).to_str
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :model_name, :field, :value
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Formulaic
|
2
|
+
module Inputs
|
3
|
+
class StringInput < Input
|
4
|
+
def fill
|
5
|
+
if %w(text email password textarea).any? { |type| page.has_field?(input_text, type: type) }
|
6
|
+
fill_in(input_text, with: value)
|
7
|
+
elsif page.has_field?(input_text, type: 'radio')
|
8
|
+
choose(value)
|
9
|
+
else
|
10
|
+
select(value, from: input_text)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def input_text
|
15
|
+
@input_text ||= input(model_name, field)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Formulaic
|
2
|
+
class Label
|
3
|
+
def initialize(model_name, attribute, action = :create)
|
4
|
+
@model_name = model_name
|
5
|
+
@attribute = attribute
|
6
|
+
@action = action
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_str
|
10
|
+
if attribute.is_a?(String)
|
11
|
+
attribute
|
12
|
+
else
|
13
|
+
translate || human_attribute_name || attribute.to_s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
alias_method :to_s, :to_str
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :model_name, :attribute, :action
|
21
|
+
|
22
|
+
def translate
|
23
|
+
I18n.t(lookup_paths.first, scope: :'simple_form.labels', default: lookup_paths).presence
|
24
|
+
end
|
25
|
+
|
26
|
+
def human_attribute_name
|
27
|
+
if class_exists?(model_name.to_s.classify)
|
28
|
+
model_class = model_name.to_s.classify.constantize
|
29
|
+
if model_class.respond_to?(:human_attribute_name)
|
30
|
+
model_class.human_attribute_name(attribute.to_s)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def lookup_paths
|
36
|
+
[
|
37
|
+
:"#{model_name}.#{action}.#{attribute}",
|
38
|
+
:"#{model_name}.#{attribute}",
|
39
|
+
:"defaults.#{action}.#{attribute}",
|
40
|
+
:"defaults.#{attribute}",
|
41
|
+
'',
|
42
|
+
]
|
43
|
+
end
|
44
|
+
|
45
|
+
def class_exists?(class_name)
|
46
|
+
Object.const_defined?(model_name.to_s.classify)
|
47
|
+
rescue NameError
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Fill in user form' do
|
4
|
+
|
5
|
+
before(:all) { load_translations }
|
6
|
+
|
7
|
+
it 'finds and fills text fields' do
|
8
|
+
visit 'user_form'
|
9
|
+
form = Formulaic::Form.new(:user, name: 'George')
|
10
|
+
|
11
|
+
form.fill
|
12
|
+
|
13
|
+
expect(input(:user, :name).value).to eq 'George'
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'finds and fills a password field' do
|
17
|
+
visit 'user_form'
|
18
|
+
form = Formulaic::Form.new(:user, password: 'supersecr3t')
|
19
|
+
|
20
|
+
form.fill
|
21
|
+
|
22
|
+
expect(input(:user, :password).value).to eq 'supersecr3t'
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'finds and fills a textarea' do
|
26
|
+
visit 'user_form'
|
27
|
+
form = Formulaic::Form.new(:user, bio: 'blah blah blah')
|
28
|
+
|
29
|
+
form.fill
|
30
|
+
|
31
|
+
expect(input(:user, :bio).value).to eq 'blah blah blah'
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'finds and fills a date field' do
|
35
|
+
visit 'user_form'
|
36
|
+
form = Formulaic::Form.new(:user, date_of_birth: Date.new(1980, 1, 2))
|
37
|
+
|
38
|
+
form.fill
|
39
|
+
|
40
|
+
expect(page.find('#user_date_of_birth_1i').value).to eq('1980')
|
41
|
+
expect(page.find('#user_date_of_birth_2i').value).to eq('1')
|
42
|
+
expect(page.find('#user_date_of_birth_3i').value).to eq('2')
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'finds and checks a boolean field' do
|
46
|
+
visit 'user_form'
|
47
|
+
form = Formulaic::Form.new(:user, terms_of_service: true)
|
48
|
+
|
49
|
+
form.fill
|
50
|
+
|
51
|
+
expect(input(:user, :terms_of_service)).to be_checked
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'selects a string if there is no input' do
|
55
|
+
visit 'user_form'
|
56
|
+
form = Formulaic::Form.new(:user, awesome: 'Yes')
|
57
|
+
|
58
|
+
form.fill
|
59
|
+
|
60
|
+
expect(page).to have_select('user_awesome', selected: 'Yes')
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
<form accept-charset="UTF-8" action="/users" class="simple_form new_user" id="new_user" method="post" novalidate="novalidate">
|
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" for="user_name"><abbr title="required">*</abbr> Display name</label><input class="string required" id="user_name" maxlength="255" name="user[name]" size="50" type="text"></div>
|
4
|
+
<div class="input email required user_email"><label class="email required" for="user_email"><abbr title="required">*</abbr> Email</label><input class="string email required" id="user_email" maxlength="255" name="user[email]" size="50" type="email"></div>
|
5
|
+
<div class="input password optional user_password"><label class="password optional" for="user_password">Password</label><input class="password optional" id="user_password" name="user[password]" size="50" type="password"></div>
|
6
|
+
<div class="input select required user_awesome">
|
7
|
+
<label class="select required" for="user_awesome"><abbr title="required">*</abbr> Are you awesome?</label>
|
8
|
+
<select class="select required" id="user_awesome" name="user[awesome]">
|
9
|
+
<option value=""></option>
|
10
|
+
<option value="true">Yes</option>
|
11
|
+
<option value="false">No</option>
|
12
|
+
</select>
|
13
|
+
</div>
|
14
|
+
<div class="input text required user_bio"><label class="text required" for="user_bio"><abbr title="required">*</abbr> 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>
|
15
|
+
<div class="input date required user_date_of_birth">
|
16
|
+
<label class="date required" for="user_date_of_birth_1i"><abbr title="required">*</abbr> Date of birth</label>
|
17
|
+
<select class="date required" id="user_date_of_birth_1i" name="user[date_of_birth(1i)]">
|
18
|
+
<option value="2001">2001</option>
|
19
|
+
<option value="2000">2000</option>
|
20
|
+
<option value="1999">1999</option>
|
21
|
+
<option value="1998">1998</option>
|
22
|
+
<option value="1997">1997</option>
|
23
|
+
<option value="1996">1996</option>
|
24
|
+
<option value="1995">1995</option>
|
25
|
+
<option value="1994">1994</option>
|
26
|
+
<option value="1993">1993</option>
|
27
|
+
<option value="1992">1992</option>
|
28
|
+
<option value="1991">1991</option>
|
29
|
+
<option value="1990">1990</option>
|
30
|
+
<option value="1989">1989</option>
|
31
|
+
<option value="1988">1988</option>
|
32
|
+
<option value="1987">1987</option>
|
33
|
+
<option value="1986">1986</option>
|
34
|
+
<option value="1985">1985</option>
|
35
|
+
<option value="1984">1984</option>
|
36
|
+
<option value="1983">1983</option>
|
37
|
+
<option value="1982">1982</option>
|
38
|
+
<option value="1981">1981</option>
|
39
|
+
<option value="1980">1980</option>
|
40
|
+
<option value="1979">1979</option>
|
41
|
+
<option value="1978">1978</option>
|
42
|
+
<option value="1977">1977</option>
|
43
|
+
<option value="1976">1976</option>
|
44
|
+
<option value="1975">1975</option>
|
45
|
+
<option value="1974">1974</option>
|
46
|
+
<option value="1973">1973</option>
|
47
|
+
<option value="1972">1972</option>
|
48
|
+
<option value="1971">1971</option>
|
49
|
+
<option value="1970">1970</option>
|
50
|
+
<option value="1969">1969</option>
|
51
|
+
<option value="1968">1968</option>
|
52
|
+
<option value="1967">1967</option>
|
53
|
+
<option value="1966">1966</option>
|
54
|
+
<option value="1965">1965</option>
|
55
|
+
<option value="1964">1964</option>
|
56
|
+
<option value="1963">1963</option>
|
57
|
+
<option value="1962">1962</option>
|
58
|
+
<option value="1961">1961</option>
|
59
|
+
<option value="1960">1960</option>
|
60
|
+
<option value="1959">1959</option>
|
61
|
+
<option value="1958">1958</option>
|
62
|
+
<option value="1957">1957</option>
|
63
|
+
<option value="1956">1956</option>
|
64
|
+
<option value="1955">1955</option>
|
65
|
+
<option value="1954">1954</option>
|
66
|
+
<option value="1953">1953</option>
|
67
|
+
<option value="1952">1952</option>
|
68
|
+
<option value="1951">1951</option>
|
69
|
+
<option value="1950">1950</option>
|
70
|
+
<option value="1949">1949</option>
|
71
|
+
<option value="1948">1948</option>
|
72
|
+
<option value="1947">1947</option>
|
73
|
+
<option value="1946">1946</option>
|
74
|
+
<option value="1945">1945</option>
|
75
|
+
<option value="1944">1944</option>
|
76
|
+
<option value="1943">1943</option>
|
77
|
+
<option value="1942">1942</option>
|
78
|
+
<option value="1941">1941</option>
|
79
|
+
<option value="1940">1940</option>
|
80
|
+
<option value="1939">1939</option>
|
81
|
+
<option value="1938">1938</option>
|
82
|
+
<option value="1937">1937</option>
|
83
|
+
<option value="1936">1936</option>
|
84
|
+
<option value="1935">1935</option>
|
85
|
+
<option value="1934">1934</option>
|
86
|
+
<option value="1933">1933</option>
|
87
|
+
<option value="1932">1932</option>
|
88
|
+
<option value="1931">1931</option>
|
89
|
+
<option value="1930">1930</option>
|
90
|
+
<option value="1929">1929</option>
|
91
|
+
<option value="1928">1928</option>
|
92
|
+
<option value="1927">1927</option>
|
93
|
+
<option value="1926">1926</option>
|
94
|
+
<option value="1925">1925</option>
|
95
|
+
<option value="1924">1924</option>
|
96
|
+
<option value="1923">1923</option>
|
97
|
+
<option value="1922">1922</option>
|
98
|
+
<option value="1921">1921</option>
|
99
|
+
<option value="1920">1920</option>
|
100
|
+
<option value="1919">1919</option>
|
101
|
+
<option value="1918">1918</option>
|
102
|
+
<option value="1917">1917</option>
|
103
|
+
<option value="1916">1916</option>
|
104
|
+
<option value="1915">1915</option>
|
105
|
+
<option value="1914">1914</option>
|
106
|
+
<option value="1913">1913</option>
|
107
|
+
<option value="1912">1912</option>
|
108
|
+
<option value="1911">1911</option>
|
109
|
+
<option value="1910">1910</option>
|
110
|
+
<option value="1909">1909</option>
|
111
|
+
<option value="1908">1908</option>
|
112
|
+
<option value="1907">1907</option>
|
113
|
+
<option value="1906">1906</option>
|
114
|
+
<option value="1905">1905</option>
|
115
|
+
<option value="1904">1904</option>
|
116
|
+
<option value="1903">1903</option>
|
117
|
+
<option value="1902">1902</option>
|
118
|
+
<option value="1901">1901</option>
|
119
|
+
<option value="1900">1900</option>
|
120
|
+
</select>
|
121
|
+
<select class="date required" id="user_date_of_birth_2i" name="user[date_of_birth(2i)]">
|
122
|
+
<option value="1">January</option>
|
123
|
+
<option value="2">February</option>
|
124
|
+
<option value="3">March</option>
|
125
|
+
<option value="4">April</option>
|
126
|
+
<option value="5">May</option>
|
127
|
+
<option selected="selected" value="6">June</option>
|
128
|
+
<option value="7">July</option>
|
129
|
+
<option value="8">August</option>
|
130
|
+
<option value="9">September</option>
|
131
|
+
<option value="10">October</option>
|
132
|
+
<option value="11">November</option>
|
133
|
+
<option value="12">December</option>
|
134
|
+
</select>
|
135
|
+
<select class="date required" id="user_date_of_birth_3i" name="user[date_of_birth(3i)]">
|
136
|
+
<option value="1">1</option>
|
137
|
+
<option value="2">2</option>
|
138
|
+
<option value="3">3</option>
|
139
|
+
<option value="4">4</option>
|
140
|
+
<option value="5">5</option>
|
141
|
+
<option value="6">6</option>
|
142
|
+
<option selected="selected" value="7">7</option>
|
143
|
+
<option value="8">8</option>
|
144
|
+
<option value="9">9</option>
|
145
|
+
<option value="10">10</option>
|
146
|
+
<option value="11">11</option>
|
147
|
+
<option value="12">12</option>
|
148
|
+
<option value="13">13</option>
|
149
|
+
<option value="14">14</option>
|
150
|
+
<option value="15">15</option>
|
151
|
+
<option value="16">16</option>
|
152
|
+
<option value="17">17</option>
|
153
|
+
<option value="18">18</option>
|
154
|
+
<option value="19">19</option>
|
155
|
+
<option value="20">20</option>
|
156
|
+
<option value="21">21</option>
|
157
|
+
<option value="22">22</option>
|
158
|
+
<option value="23">23</option>
|
159
|
+
<option value="24">24</option>
|
160
|
+
<option value="25">25</option>
|
161
|
+
<option value="26">26</option>
|
162
|
+
<option value="27">27</option>
|
163
|
+
<option value="28">28</option>
|
164
|
+
<option value="29">29</option>
|
165
|
+
<option value="30">30</option>
|
166
|
+
<option value="31">31</option>
|
167
|
+
</select>
|
168
|
+
</div>
|
169
|
+
<div class="input boolean required user_terms_of_service"><input name="user[terms_of_service]" type="hidden" value="0"><input class="boolean required" id="user_terms_of_service" name="user[terms_of_service]" type="checkbox" value="1"><label class="boolean required" for="user_terms_of_service"><abbr title="required">*</abbr> I agree to the Terms of Service</label></div>
|
170
|
+
<input name="commit" type="submit" value="Register">
|
171
|
+
</form>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Formulaic::Dsl do
|
4
|
+
it 'responds to input' do
|
5
|
+
expect(object_with_dsl).to respond_to(:input)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'responds to fill_form' do
|
9
|
+
expect(object_with_dsl).to respond_to(:fill_form)
|
10
|
+
end
|
11
|
+
|
12
|
+
def object_with_dsl
|
13
|
+
@object_with_dsl ||= Class.new do
|
14
|
+
include Formulaic::Dsl
|
15
|
+
end.new
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Formulaic::Label do
|
4
|
+
it 'returns the string if there are no translations and it can not human_attribute_name the class' do
|
5
|
+
expect(label(nil, 'My label')).to eq 'My label'
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'returns human_attribute_name if available' do
|
9
|
+
expect(label(:user, :attribute)).to eq 'Human Attribute Name'
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'uses a translation if available' do
|
13
|
+
I18n.backend.store_translations(:en, { simple_form: { labels: { user: { name: 'Translated' } } } } )
|
14
|
+
|
15
|
+
expect(label(:user, :name)).to eq('Translated')
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should leave cases alone' do
|
19
|
+
expect(label(:user, 'Work URL')).to eq 'Work URL'
|
20
|
+
end
|
21
|
+
|
22
|
+
def label(model_name, attribute, action = :create)
|
23
|
+
Formulaic::Label.new(model_name, attribute, action).to_str
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class User
|
28
|
+
def self.human_attribute_name(*)
|
29
|
+
'Human Attribute Name'
|
30
|
+
end
|
31
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'formulaic'
|
2
|
+
require 'pry'
|
3
|
+
|
4
|
+
module SpecHelper
|
5
|
+
def input(model, field)
|
6
|
+
page.find("##{model}_#{field}")
|
7
|
+
end
|
8
|
+
|
9
|
+
def visit(page_name)
|
10
|
+
page.visit("/#{page_name}.html")
|
11
|
+
end
|
12
|
+
|
13
|
+
def page
|
14
|
+
@page ||= begin
|
15
|
+
Capybara.app = Rack::File.new(File.expand_path('../fixtures', __FILE__))
|
16
|
+
Capybara.current_session
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_translations
|
21
|
+
I18n.backend.store_translations(:en, YAML.load(<<-TRANSLATIONS))
|
22
|
+
simple_form:
|
23
|
+
labels:
|
24
|
+
user:
|
25
|
+
name: Display name
|
26
|
+
email: Email
|
27
|
+
password: Password
|
28
|
+
date_of_birth: Date of birth
|
29
|
+
terms_of_service: I agree to the Terms of Service
|
30
|
+
awesome: Are you awesome?
|
31
|
+
bio: Biography
|
32
|
+
TRANSLATIONS
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
RSpec.configure do |c|
|
37
|
+
c.include SpecHelper
|
38
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formulaic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Caleb Thompson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: capybara
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: i18n
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
13
55
|
- !ruby/object:Gem::Dependency
|
14
56
|
name: bundler
|
15
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,22 +80,71 @@ dependencies:
|
|
38
80
|
- - '>='
|
39
81
|
- !ruby/object:Gem::Version
|
40
82
|
version: '0'
|
41
|
-
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: |
|
112
|
+
Removes the tedium of formulaic form filling with Capybara by allowing you
|
113
|
+
to specify a hash of attributes to be input rather than procedurally calling
|
114
|
+
Capybara’s DSL methods.
|
42
115
|
email:
|
43
|
-
-
|
116
|
+
- caleb@calebthompson.io
|
44
117
|
executables: []
|
45
118
|
extensions: []
|
46
119
|
extra_rdoc_files: []
|
47
120
|
files:
|
48
121
|
- .gitignore
|
122
|
+
- .ruby-gemset
|
123
|
+
- .ruby-version
|
124
|
+
- CONTRIBUTING.md
|
49
125
|
- Gemfile
|
50
|
-
- LICENSE
|
126
|
+
- LICENSE
|
51
127
|
- README.md
|
52
128
|
- Rakefile
|
53
129
|
- formulaic.gemspec
|
54
|
-
- lib/
|
55
|
-
- lib/
|
56
|
-
|
130
|
+
- lib/formulaic.rb
|
131
|
+
- lib/formulaic/dsl.rb
|
132
|
+
- lib/formulaic/form.rb
|
133
|
+
- lib/formulaic/inputs.rb
|
134
|
+
- lib/formulaic/inputs/array_input.rb
|
135
|
+
- lib/formulaic/inputs/boolean_input.rb
|
136
|
+
- lib/formulaic/inputs/date_input.rb
|
137
|
+
- lib/formulaic/inputs/input.rb
|
138
|
+
- lib/formulaic/inputs/string_input.rb
|
139
|
+
- lib/formulaic/label.rb
|
140
|
+
- lib/formulaic/version.rb
|
141
|
+
- spec/features/fill_in_user_form_spec.rb
|
142
|
+
- spec/fixtures/user_form.html
|
143
|
+
- spec/formulaic/dsl_spec.rb
|
144
|
+
- spec/formulaic/form_spec.rb
|
145
|
+
- spec/formulaic/label_spec.rb
|
146
|
+
- spec/spec_helper.rb
|
147
|
+
homepage: https://github.com/thoughtbot/formulaic
|
57
148
|
licenses:
|
58
149
|
- MIT
|
59
150
|
metadata: {}
|
@@ -76,5 +167,11 @@ rubyforge_project:
|
|
76
167
|
rubygems_version: 2.0.3
|
77
168
|
signing_key:
|
78
169
|
specification_version: 4
|
79
|
-
summary:
|
80
|
-
test_files:
|
170
|
+
summary: Simplify form filling with Capybara
|
171
|
+
test_files:
|
172
|
+
- spec/features/fill_in_user_form_spec.rb
|
173
|
+
- spec/fixtures/user_form.html
|
174
|
+
- spec/formulaic/dsl_spec.rb
|
175
|
+
- spec/formulaic/form_spec.rb
|
176
|
+
- spec/formulaic/label_spec.rb
|
177
|
+
- spec/spec_helper.rb
|
data/lib/formualic.rb
DELETED
data/lib/formualic/version.rb
DELETED