formulaic 0.0.6 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2bddf9295abcf67c8f465f0cf868233fec7998cc
4
- data.tar.gz: a5b5c6bf0604458bfac05486835a8a53e02547b3
3
+ metadata.gz: 0088b91d76fbea5e19d5ed4686b97ec33d61f715
4
+ data.tar.gz: 1cda22db0d57d6b7546ba194ced8b4b0a5fdb4ff
5
5
  SHA512:
6
- metadata.gz: 1b37abbe416ec93dc90fb814ccef4df969a087d82c33baa247b92b499719cf325baf481f80aabfd11c0f06a47535c64ad64ca1e8ba3f363dfe901031cba3e587
7
- data.tar.gz: 78d46b03a053535978e7ec32c9ce9eb437f06b4bbafeccb07bec18c01043c60c03352ba16cce0c4c6e99b5fb749bbc0f3f46655f170c71cf23a3ccb4e501e0ef
6
+ metadata.gz: 819cb9b9db1691670db98579f4cf4a866b0ea5bfa989b16ef1c3f5ffb674d520f1bb1c4e762bac7455a6b6a0f1126155db5bff98cd6bef0e2cd9b44f88370efc
7
+ data.tar.gz: 4371252fb0c97d45bb35caeb94111d30d1b74de4bf97e9d810fb6f68443ad57a6f63ac7a2be8b2b6219f5cb895e567a85f12b9207df8791dc421eaa5045ef423
@@ -1 +1 @@
1
- ruby-2.1.0
1
+ 2.1.2
@@ -1,6 +1,7 @@
1
1
  rvm:
2
2
  - "2.0.0"
3
+ - "2.1.0"
3
4
  - "2.1.1"
4
- - "2.1-head"
5
+ - "2.1.2"
5
6
  notifications:
6
7
  email: false
data/NEWS.md CHANGED
@@ -1,5 +1,18 @@
1
+ v0.1.0
2
+ ------
3
+
4
+ * Add `fill_form_and_submit` shortcut [48f9bc2](https://github.com/thoughtbot/formulaic/commit/48f9bc257d6c2b26c859388ab01da8963b818a85)
5
+
6
+ *Caleb Thompson*
7
+ * Allow action to be specified in DSL [ad4bb54](https://github.com/thoughtbot/formulaic/commit/ad4bb5402d68131038e53f67e2e981f6aa1d5fa9)
8
+
9
+ *Caleb Thompson*
10
+ * Add support for File attachments [f4e4bae](https://github.com/thoughtbot/formulaic/commit/f4e4bae978ab32fde017ae8344f862076a9ef31a)
11
+
12
+ *Dan Collis-Puro and Sean Doyle*
13
+
1
14
  v0.0.6
2
15
  ------
3
16
 
4
17
  * Treat integers as String inputs (which allows them to fill
5
- `input[type="numeric"]`. (f7a8353)
18
+ `input[type="numeric"]`). [Pull Request](https://github.com/thoughtbot/formulaic/pull/21)
data/README.md CHANGED
@@ -27,7 +27,7 @@ end
27
27
  ### `fill_form`
28
28
 
29
29
  ```ruby
30
- fill_form(model_name, attributes)
30
+ fill_form(model_name, action = :new, attributes)
31
31
  ```
32
32
 
33
33
  `fill_form` provides an interface to completely filling out a form. Provide the
@@ -69,13 +69,32 @@ submit(:user, :update)
69
69
  The `model_name` and `action` should match up to the
70
70
  `helpers.submit.<model_name>.<action>` translations.
71
71
 
72
+ ### `fill_form_and_submit`
73
+
74
+ ```ruby
75
+ fill_form_and_submit(:user, action = :new, attributes)
76
+ ```
77
+
78
+ Effectively a `fill_form` followed by `click_on submit`, but smart enough to
79
+ `fill_form` with `:new` and `submit` with `:create` and the edit/update cousin.
80
+
81
+ ### Nested Forms
82
+
83
+ If you have nested forms, through `fields_for` (or any variant), you are able to
84
+ fill them with an extra call to `fill_form`.
85
+
86
+ ```ruby
87
+ fill_form(main_model_name, main_model_attributes)
88
+ fill_form(nested_model_name, nested_model_attributes)
89
+ ```
90
+
72
91
  ### Integration with RSpec:
73
92
 
74
93
  ```ruby
75
94
  # spec/spec_helper.rb
76
95
 
77
96
  RSpec.configure do |config|
78
- config.include Formulaic::Dsl
97
+ config.include Formulaic::Dsl, type: :feature
79
98
  end
80
99
  ```
81
100
 
@@ -132,6 +151,7 @@ around `I18n.t`.
132
151
  | `TrueClass` | `check` |
133
152
  | `FalseClass` | `uncheck` |
134
153
  | `Array` | `check` each array member, which should all be strings |
154
+ | `File` | `attach_file` with `File#path` |
135
155
 
136
156
  * Formulaic is currently tied to `simple_form` translations and field structure.
137
157
  If you pass a string for the attribute, we’ll try to fill the input that
@@ -142,7 +162,9 @@ around `I18n.t`.
142
162
  the labels to determine where to fill what data.
143
163
  * Formulaic can’t figure out how to fill fields with HTML labels:
144
164
  `page.fill_in('<strong>Text</strong> here', with: 'something')` doesn’t work
145
- with Capybara. The usual workaround is to pass a CSS selector.
165
+ with Capybara. The usual workaround is to pass a CSS selector (which you can
166
+ do by passing a string as the attribute key).
167
+ * Formulaic can't handle multiple file attachments on the same input.
146
168
 
147
169
  ## About
148
170
 
@@ -1,10 +1,17 @@
1
1
  module Formulaic
2
2
  module Dsl
3
- def fill_form(model_name, attributes)
4
- Form.new(model_name, attributes).fill
3
+ def fill_form(model_name, action = :new, attributes)
4
+ Form.new(model_name, action, attributes).fill
5
5
  end
6
6
 
7
- def input(model_name, field, action = :create)
7
+ def fill_form_and_submit(model_name, action = :new, attributes)
8
+ form_action_to_submit_action = { new: :create, edit: :update }
9
+ fill_form(model_name, action, attributes)
10
+ submit_action = form_action_to_submit_action[action] || action
11
+ click_on submit(model_name, submit_action)
12
+ end
13
+
14
+ def input(model_name, field, action = :new)
8
15
  Label.new(model_name, field, action).to_str
9
16
  end
10
17
 
@@ -10,11 +10,12 @@ module Formulaic
10
10
  Fixnum => Formulaic::Inputs::StringInput,
11
11
  TrueClass => Formulaic::Inputs::BooleanInput,
12
12
  FalseClass => Formulaic::Inputs::BooleanInput,
13
+ File => Formulaic::Inputs::FileInput,
13
14
  }.freeze
14
15
 
15
- def initialize(model_name, attributes)
16
+ def initialize(model_name, action, attributes)
17
+ @action = action
16
18
  @inputs = build_inputs(model_name, attributes)
17
- @session = session
18
19
  end
19
20
 
20
21
  def fill
@@ -23,7 +24,7 @@ module Formulaic
23
24
 
24
25
  private
25
26
 
26
- attr_reader :session, :model_name, :inputs
27
+ attr_reader :model_name, :inputs, :action
27
28
 
28
29
  def build_inputs(model_name, attributes)
29
30
  attributes.map do |field, value|
@@ -32,7 +33,8 @@ module Formulaic
32
33
  end
33
34
 
34
35
  def build_input(model_name, field, value)
35
- input_class_for(value).new(model_name, field, value)
36
+ label = Label.new(model_name, field, action)
37
+ input_class_for(value).new(label, value)
36
38
  end
37
39
 
38
40
  def input_class_for(value)
@@ -3,3 +3,4 @@ require 'formulaic/inputs/array_input'
3
3
  require 'formulaic/inputs/boolean_input'
4
4
  require 'formulaic/inputs/date_input'
5
5
  require 'formulaic/inputs/string_input'
6
+ require 'formulaic/inputs/file_input'
@@ -3,9 +3,9 @@ module Formulaic
3
3
  class BooleanInput < Input
4
4
  def fill
5
5
  if value
6
- check(input(model_name, field))
6
+ check(label)
7
7
  else
8
- uncheck(input(model_name, field))
8
+ uncheck(label)
9
9
  end
10
10
  end
11
11
  end
@@ -2,7 +2,7 @@ module Formulaic
2
2
  module Inputs
3
3
  class DateInput < Input
4
4
  def fill
5
- select_date(value, from: input(model_name, field))
5
+ select_date(value, from: label)
6
6
  end
7
7
 
8
8
  private
@@ -0,0 +1,9 @@
1
+ module Formulaic
2
+ module Inputs
3
+ class FileInput < Input
4
+ def fill
5
+ attach_file(label, value.path)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -6,19 +6,14 @@ module Formulaic
6
6
  class Input
7
7
  include Capybara::DSL
8
8
 
9
- def initialize(model_name, field, value)
10
- @model_name = model_name
11
- @field = field
9
+ def initialize(label, value)
10
+ @label = label.to_str
12
11
  @value = value
13
12
  end
14
13
 
15
14
  private
16
15
 
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
16
+ attr_accessor :label, :value
22
17
  end
23
18
  end
24
19
  end
@@ -2,21 +2,17 @@ module Formulaic
2
2
  module Inputs
3
3
  class StringInput < Input
4
4
  def fill
5
- if page.has_selector?(:fillable_field, input_text)
6
- fill_in(input_text, with: value)
7
- elsif page.has_selector?(:radio_button, input_text)
5
+ if page.has_selector?(:fillable_field, label)
6
+ fill_in(label, with: value)
7
+ elsif page.has_selector?(:radio_button, label)
8
8
  choose(value)
9
- elsif has_option_in_select?(value, input_text)
10
- select(value, from: input_text)
9
+ elsif has_option_in_select?(value, label)
10
+ select(value, from: label)
11
11
  else
12
- raise Formulaic::InputNotFound.new(%[Unable to find input "#{input_text}".])
12
+ raise Formulaic::InputNotFound.new(%[Unable to find input "#{label}".])
13
13
  end
14
14
  end
15
15
 
16
- def input_text
17
- @input_text ||= input(model_name, field)
18
- end
19
-
20
16
  def has_option_in_select?(option, select)
21
17
  find(:select, select).has_selector?(:option, option)
22
18
  rescue Capybara::ElementNotFound
@@ -1,6 +1,6 @@
1
1
  module Formulaic
2
2
  class Label
3
- def initialize(model_name, attribute, action = :create)
3
+ def initialize(model_name, attribute, action)
4
4
  @model_name = model_name
5
5
  @attribute = attribute
6
6
  @action = action
@@ -1,3 +1,3 @@
1
1
  module Formulaic
2
- VERSION = '0.0.6'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'pathname'
2
3
 
3
4
  describe 'Fill in user form' do
4
5
 
@@ -6,7 +7,7 @@ describe 'Fill in user form' do
6
7
 
7
8
  it 'finds and fills text fields' do
8
9
  visit 'user_form'
9
- form = Formulaic::Form.new(:user, name: 'George')
10
+ form = Formulaic::Form.new(:user, :new, name: 'George')
10
11
 
11
12
  form.fill
12
13
 
@@ -15,7 +16,7 @@ describe 'Fill in user form' do
15
16
 
16
17
  it 'finds and fills a password field' do
17
18
  visit 'user_form'
18
- form = Formulaic::Form.new(:user, password: 'supersecr3t')
19
+ form = Formulaic::Form.new(:user, :new, password: 'supersecr3t')
19
20
 
20
21
  form.fill
21
22
 
@@ -24,7 +25,7 @@ describe 'Fill in user form' do
24
25
 
25
26
  it 'finds and fills a email field' do
26
27
  visit 'user_form'
27
- form = Formulaic::Form.new(:user, email: 'caleb@example.com')
28
+ form = Formulaic::Form.new(:user, :new, email: 'caleb@example.com')
28
29
 
29
30
  form.fill
30
31
 
@@ -33,7 +34,7 @@ describe 'Fill in user form' do
33
34
 
34
35
  it 'finds and fills a tel field' do
35
36
  visit 'user_form'
36
- form = Formulaic::Form.new(:user, phone: '123-555-1234')
37
+ form = Formulaic::Form.new(:user, :new, phone: '123-555-1234')
37
38
 
38
39
  form.fill
39
40
 
@@ -42,7 +43,7 @@ describe 'Fill in user form' do
42
43
 
43
44
  it 'finds and fills a url field' do
44
45
  visit 'user_form'
45
- form = Formulaic::Form.new(:user, url: 'https://github.com')
46
+ form = Formulaic::Form.new(:user, :new, url: 'https://github.com')
46
47
 
47
48
  form.fill
48
49
 
@@ -51,7 +52,7 @@ describe 'Fill in user form' do
51
52
 
52
53
  it 'finds and fills a textarea' do
53
54
  visit 'user_form'
54
- form = Formulaic::Form.new(:user, bio: 'blah blah blah')
55
+ form = Formulaic::Form.new(:user, :new, bio: 'blah blah blah')
55
56
 
56
57
  form.fill
57
58
 
@@ -60,7 +61,7 @@ describe 'Fill in user form' do
60
61
 
61
62
  it 'finds and fills a date field' do
62
63
  visit 'user_form'
63
- form = Formulaic::Form.new(:user, date_of_birth: Date.new(1980, 1, 2))
64
+ form = Formulaic::Form.new(:user, :new, date_of_birth: Date.new(1980, 1, 2))
64
65
 
65
66
  form.fill
66
67
 
@@ -71,7 +72,7 @@ describe 'Fill in user form' do
71
72
 
72
73
  it 'finds and checks a boolean field' do
73
74
  visit 'user_form'
74
- form = Formulaic::Form.new(:user, terms_of_service: true)
75
+ form = Formulaic::Form.new(:user, :new, terms_of_service: true)
75
76
 
76
77
  form.fill
77
78
 
@@ -80,7 +81,7 @@ describe 'Fill in user form' do
80
81
 
81
82
  it 'finds and fills in a number field' do
82
83
  visit 'user_form'
83
- form = Formulaic::Form.new(:user, age: 10)
84
+ form = Formulaic::Form.new(:user, :new, age: 10)
84
85
 
85
86
  form.fill
86
87
 
@@ -89,10 +90,20 @@ describe 'Fill in user form' do
89
90
 
90
91
  it 'selects a string if there is no input' do
91
92
  visit 'user_form'
92
- form = Formulaic::Form.new(:user, awesome: 'Yes')
93
+ form = Formulaic::Form.new(:user, :new, awesome: 'Yes')
93
94
 
94
95
  form.fill
95
96
 
96
97
  expect(page).to have_select('user_awesome', selected: 'Yes')
97
98
  end
99
+
100
+ it 'attaches a file to a file field' do
101
+ visit 'user_form'
102
+ file = File.open('spec/fixtures/file.txt')
103
+ form = Formulaic::Form.new(:user, :new, avatar: file)
104
+
105
+ form.fill
106
+
107
+ expect(input(:user, :avatar).value).to eq file.path
108
+ end
98
109
  end
File without changes
@@ -5,6 +5,7 @@
5
5
  <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
6
  <div class="input integer required user_age"><label class="integer required" for="user_age"><abbr title="required">*</abbr> Age</label><input class="numeric integer age required" id="user_age" maxlength="255" name="user[age]" size="50" type="number"></div>
7
7
  <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" for="user_avatar">Avatar</label><input class="file optional" id="user_avatar" name="user[avatar]" type="file" /></div>
8
9
  <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>
9
10
  <div class="input select required user_awesome">
10
11
  <label class="select required" for="user_awesome"><abbr title="required">*</abbr> Are you awesome?</label>
@@ -1,18 +1,73 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Formulaic::Dsl do
4
- it 'responds to input' do
5
- expect(object_with_dsl).to respond_to(:input)
4
+ describe 'input' do
5
+ it 'builds a label' do
6
+ label = instance_double('Formulaic::Label')
7
+ allow(label).to receive(:to_str)
8
+ allow(Formulaic::Label).to receive(:new).and_return(label)
9
+
10
+ object_with_dsl.input :model, :attribute, :action
11
+
12
+ expect(Formulaic::Label).to have_received(:new)
13
+ .with(:model, :attribute, :action)
14
+ expect(label).to have_received(:to_str)
15
+ end
16
+
17
+ it 'defaults action to :new' do
18
+ allow(Formulaic::Label).to receive(:new).and_return(double(to_str: nil))
19
+
20
+ object_with_dsl.input :model, :attribute
21
+
22
+ expect(Formulaic::Label).to have_received(:new)
23
+ .with(:model, :attribute, :new)
24
+ end
25
+
6
26
  end
7
27
 
8
- it 'responds to fill_form' do
9
- expect(object_with_dsl).to respond_to(:fill_form)
28
+ describe 'fill_form' do
29
+ it 'creates a form and fills it' do
30
+ form = instance_double('Formulaic::Form')
31
+ allow(form).to receive(:fill)
32
+ allow(Formulaic::Form).to receive(:new).and_return(form)
33
+
34
+ object_with_dsl.fill_form :model, :action, attributes: :values
35
+
36
+ expect(Formulaic::Form).to have_received(:new)
37
+ .with(:model, :action, attributes: :values)
38
+ expect(form).to have_received(:fill)
39
+ end
40
+
41
+ it 'assumes that action = :new' do
42
+ allow(Formulaic::Form).to receive(:new).and_return(double(fill: nil))
43
+
44
+ object_with_dsl.fill_form :model, attributes: :values
45
+
46
+ expect(Formulaic::Form).to have_received(:new)
47
+ .with(:model, :new, attributes: :values)
48
+ end
10
49
  end
11
50
 
12
- it 'finds a submit label' do
13
- I18n.backend.store_translations(:en, { helpers: { submit: { user: { create: 'Create user' } } } })
51
+ describe 'submit' do
52
+ it 'finds a submit label' do
53
+ I18n.backend.store_translations(:en, { helpers: { submit: { user: { create: 'Create user' } } } })
54
+
55
+ expect(object_with_dsl.submit(:user)).to eq 'Create user'
56
+ end
57
+ end
58
+
59
+ describe 'fill_form_and_submit' do
60
+ it 'fills a form and submits it' do
61
+ I18n.backend.store_translations(:en, { helpers: { submit: { model: { create: 'Create model' } } } })
62
+ allow(Formulaic::Form).to receive(:new).and_return(double(fill: nil))
63
+ allow(object_with_dsl).to receive(:click_on)
64
+
65
+ object_with_dsl.fill_form_and_submit :model, attributes: :values
14
66
 
15
- expect(object_with_dsl.submit(:user)).to eq 'Create user'
67
+ expect(Formulaic::Form).to have_received(:new)
68
+ .with(:model, :new, attributes: :values)
69
+ expect(object_with_dsl).to have_received(:click_on).with('Create model')
70
+ end
16
71
  end
17
72
 
18
73
  def object_with_dsl
@@ -2,6 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe Formulaic::Form do
4
4
  it 'throws an error if it does not know how to fill an attribute type' do
5
- expect { Formulaic::Form.new(nil, { invalid: nil }) }.to raise_error(Formulaic::Form::InvalidAttributeTypeError)
5
+ expect { Formulaic::Form.new(nil, nil, { invalid: nil }) }.to raise_error(Formulaic::Form::InvalidAttributeTypeError)
6
6
  end
7
7
  end
@@ -1,6 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Formulaic::Label do
4
+ before(:each) do
5
+ class_double("User").as_stubbed_const
6
+ allow(User).to receive(:human_attribute_name).and_return("Human Attribute Name")
7
+ end
8
+
4
9
  it 'returns the string if there are no translations and it can not human_attribute_name the class' do
5
10
  expect(label(nil, 'My label')).to eq 'My label'
6
11
  end
@@ -19,13 +24,7 @@ describe Formulaic::Label do
19
24
  expect(label(:user, 'Work URL')).to eq 'Work URL'
20
25
  end
21
26
 
22
- def label(model_name, attribute, action = :create)
27
+ def label(model_name, attribute, action = :new)
23
28
  Formulaic::Label.new(model_name, attribute, action).to_str
24
29
  end
25
30
  end
26
-
27
- class User
28
- def self.human_attribute_name(*)
29
- 'Human Attribute Name'
30
- end
31
- end
@@ -1,5 +1,4 @@
1
1
  require 'formulaic'
2
- require 'pry'
3
2
 
4
3
  module SpecHelper
5
4
  def input(model, field)
@@ -23,15 +22,17 @@ module SpecHelper
23
22
  labels:
24
23
  user:
25
24
  age: Age
26
- name: Display name
27
- email: Email
28
- phone: Phone Number
29
- url: Website
30
- password: Password
31
- date_of_birth: Date of birth
32
- terms_of_service: I agree to the Terms of Service
25
+ avatar: Avatar
33
26
  awesome: Are you awesome?
34
27
  bio: Biography
28
+ date_of_birth: Date of birth
29
+ email: Email
30
+ name: Display name
31
+ new:
32
+ password: Password
33
+ phone: Phone Number
34
+ terms_of_service: I agree to the Terms of Service
35
+ url: Website
35
36
  TRANSLATIONS
36
37
  end
37
38
  end
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.0.6
4
+ version: 0.1.0
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-03-26 00:00:00.000000000 Z
11
+ date: 2014-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capybara
@@ -137,11 +137,13 @@ files:
137
137
  - lib/formulaic/inputs/array_input.rb
138
138
  - lib/formulaic/inputs/boolean_input.rb
139
139
  - lib/formulaic/inputs/date_input.rb
140
+ - lib/formulaic/inputs/file_input.rb
140
141
  - lib/formulaic/inputs/input.rb
141
142
  - lib/formulaic/inputs/string_input.rb
142
143
  - lib/formulaic/label.rb
143
144
  - lib/formulaic/version.rb
144
145
  - spec/features/fill_in_user_form_spec.rb
146
+ - spec/fixtures/file.txt
145
147
  - spec/fixtures/user_form.html
146
148
  - spec/formulaic/dsl_spec.rb
147
149
  - spec/formulaic/form_spec.rb
@@ -173,6 +175,7 @@ specification_version: 4
173
175
  summary: Simplify form filling with Capybara
174
176
  test_files:
175
177
  - spec/features/fill_in_user_form_spec.rb
178
+ - spec/fixtures/file.txt
176
179
  - spec/fixtures/user_form.html
177
180
  - spec/formulaic/dsl_spec.rb
178
181
  - spec/formulaic/form_spec.rb