super_form 0.0.1 → 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 +4 -4
- data/lib/field.rb +15 -9
- data/lib/field/bare.rb +3 -0
- data/lib/field/base.rb +54 -15
- data/lib/field/cnpj.rb +5 -7
- data/lib/field/cpf.rb +6 -8
- data/lib/field/email.rb +4 -4
- data/lib/field/float.rb +7 -0
- data/lib/field/form.rb +30 -0
- data/lib/field/form_array.rb +32 -0
- data/lib/field/form_proxy.rb +16 -0
- data/lib/field/password.rb +6 -10
- data/lib/field/person_type.rb +0 -4
- data/lib/field/telephone.rb +2 -7
- data/lib/person_type.rb +2 -8
- data/lib/presenter.rb +90 -0
- data/lib/presenter/cnpj.rb +9 -0
- data/lib/presenter/cpf.rb +9 -0
- data/lib/presenter/form.rb +20 -0
- data/lib/presenter/password.rb +7 -0
- data/lib/presenter/person_type.rb +9 -0
- data/lib/presenter/telephone.rb +9 -0
- data/lib/super_form.rb +21 -156
- data/lib/super_form/fieldable.rb +78 -0
- data/lib/super_form/fieldset.rb +32 -0
- data/lib/super_form/version.rb +1 -1
- data/spec/lib/field/form_array.rb +71 -0
- data/spec/lib/field/form_array_spec.rb +71 -0
- data/spec/lib/field/form_spec.rb +68 -0
- data/spec/lib/field_spec.rb +13 -0
- data/spec/lib/person_type_spec.rb +66 -0
- data/spec/lib/presenter/cnpj_spec.rb +9 -0
- data/spec/lib/presenter/cpf_spec.rb +9 -0
- data/spec/lib/presenter/form_spec.rb +39 -0
- data/spec/lib/presenter/password_spec.rb +8 -0
- data/spec/lib/presenter/person_type_spec.rb +8 -0
- data/spec/lib/presenter/telephone_spec.rb +9 -0
- data/spec/lib/presenter_spec.rb +166 -0
- data/spec/lib/super_form/fieldable_spec.rb +82 -0
- data/spec/lib/super_form_spec.rb +120 -65
- data/spec/lib/telephone_spec.rb +32 -0
- data/spec/spec_helper.rb +4 -11
- data/spec/support/presenter_name.rb +28 -0
- data/super_form.gemspec +1 -0
- metadata +60 -2
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'super_form/fieldable'
|
3
|
+
require 'field/bare'
|
4
|
+
|
5
|
+
describe SuperForm::Fieldable do
|
6
|
+
context 'when no fieldset is defined' do
|
7
|
+
it 'returns no fieldsets' do
|
8
|
+
expect(class_with_no_fields.fieldsets).to eq({})
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when fields and fieldsets are defined' do
|
13
|
+
let(:dummy) { class_with_fields }
|
14
|
+
|
15
|
+
it 'has the right number of fields' do
|
16
|
+
expect(dummy.fields.length).to eq 5
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'has field values which are the same as the form attributes' do
|
20
|
+
dummy.name = 'Thiago'
|
21
|
+
dummy.ball = "Let's have it"
|
22
|
+
dummy.car = "Let's drive it"
|
23
|
+
dummy.email = "findme@athome.com"
|
24
|
+
dummy.phone = '12345'
|
25
|
+
|
26
|
+
expect(dummy.field(:name).value).to eq dummy.name
|
27
|
+
expect(dummy.field(:ball).value).to eq dummy.ball
|
28
|
+
expect(dummy.field(:car).value).to eq dummy.car
|
29
|
+
expect(dummy.field(:email).value).to eq dummy.email
|
30
|
+
expect(dummy.field(:phone).value).to eq dummy.phone
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'defines fieldsets which contain form fields' do
|
34
|
+
general = dummy.fieldset(:general)
|
35
|
+
expect(general.fields).to eq({
|
36
|
+
name: dummy.field(:name)
|
37
|
+
})
|
38
|
+
|
39
|
+
toys = dummy.fieldset(:toys)
|
40
|
+
expect(toys.fields).to eq ({
|
41
|
+
ball: dummy.field(:ball),
|
42
|
+
car: dummy.field(:car)
|
43
|
+
})
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'uses :default fieldset for fields defined outside a fieldset' do
|
47
|
+
default = dummy.fieldset(:default)
|
48
|
+
expect(default.fields).to eq ({
|
49
|
+
email: dummy.field(:email),
|
50
|
+
phone: dummy.field(:phone)
|
51
|
+
})
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def class_with_fields(&block)
|
57
|
+
Class.new do
|
58
|
+
include SuperForm::Fieldable
|
59
|
+
|
60
|
+
attr_accessor :name, :ball, :car, :email, :phone
|
61
|
+
|
62
|
+
fieldset :general do
|
63
|
+
field :name, Field::Text, presence: true
|
64
|
+
end
|
65
|
+
|
66
|
+
fieldset :toys do
|
67
|
+
field :ball, Field::Bare
|
68
|
+
field :car, Field::Text
|
69
|
+
end
|
70
|
+
|
71
|
+
field :email, Field::Text
|
72
|
+
field :phone, Field::Text, length: { minimum: 4 }
|
73
|
+
|
74
|
+
instance_eval(&block) if block_given?
|
75
|
+
end.new
|
76
|
+
end
|
77
|
+
|
78
|
+
def class_with_no_fields
|
79
|
+
Class.new do
|
80
|
+
include SuperForm::Fieldable
|
81
|
+
end
|
82
|
+
end
|
data/spec/lib/super_form_spec.rb
CHANGED
@@ -1,98 +1,153 @@
|
|
1
|
-
require 'spec_helper'
|
2
1
|
require 'super_form'
|
3
|
-
require '
|
2
|
+
require 'field/bare'
|
3
|
+
require 'spec_helper'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
describe SuperForm do
|
6
|
+
it 'includes the Fieldable module' do
|
7
|
+
form = Class.new { include SuperForm }
|
8
|
+
expect(form.ancestors).to include SuperForm::Fieldable
|
9
|
+
end
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
it 'runs the setup method when instantiated' do
|
12
|
+
form = Class.new do
|
13
|
+
include SuperForm
|
14
|
+
attr_reader :test_setup
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
setup { @test_setup = 'it worked' }
|
17
|
+
end
|
18
|
+
|
19
|
+
expect(form.new.test_setup).to eq('it worked')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'is never persisted' do
|
23
|
+
form = form_with_fields
|
24
|
+
form.name = 'Thiago'
|
25
|
+
form.save
|
26
|
+
|
27
|
+
expect(form.persisted?).to be_false
|
28
|
+
expect(form_with_no_fields.persisted?).to be_false
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'ActiveModel naming' do
|
32
|
+
context 'when the class name method returns nil' do
|
33
|
+
it 'relies on to_s to guess the model name' do
|
34
|
+
form = Class.new { include SuperForm }
|
35
|
+
|
36
|
+
expect(form).to receive(:name)
|
37
|
+
expect(form).to receive(:to_s)
|
38
|
+
|
39
|
+
form.model_name
|
18
40
|
end
|
19
41
|
|
20
|
-
|
21
|
-
|
22
|
-
|
42
|
+
it 'returns the correct model name' do
|
43
|
+
form = Class.new { include SuperForm }
|
44
|
+
form.stub(:to_s).and_return('InexistentForm')
|
45
|
+
|
46
|
+
expect(form.model_name.name).to eq 'Inexistent'
|
23
47
|
end
|
24
48
|
end
|
25
49
|
|
26
|
-
|
27
|
-
|
50
|
+
context 'when the class name method returns the class name' do
|
51
|
+
it 'uses the name method to guess the model name' do
|
52
|
+
form = Class.new { include SuperForm }
|
53
|
+
form.stub(:name).and_return 'InexistentForm'
|
28
54
|
|
29
|
-
|
30
|
-
before(:all) { @fields = DummyForm.fields }
|
31
|
-
|
32
|
-
it 'stores the basic field objects at class level' do
|
33
|
-
expect(@fields.fetch(:name)).to be_instance_of Field::Text
|
34
|
-
expect(@fields.fetch(:ball)).to be_instance_of Field::Null
|
35
|
-
expect(@fields.fetch(:car)).to be_instance_of Field::Text
|
36
|
-
end
|
55
|
+
expect(form).to receive(:name)
|
37
56
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
57
|
+
form.model_name
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'returns the correct model name' do
|
61
|
+
form = Class.new { include SuperForm }
|
62
|
+
form.stub(:name).and_return('InexistentForm')
|
63
|
+
|
64
|
+
expect(form.model_name.name).to eq 'Inexistent'
|
65
|
+
end
|
42
66
|
end
|
43
67
|
end
|
44
68
|
|
45
|
-
context 'when
|
46
|
-
|
69
|
+
context 'when fields and fieldsets are defined' do
|
70
|
+
let!(:dummy) { form_with_fields }
|
47
71
|
|
48
|
-
# this can get better, but for now it's ok
|
49
72
|
it 'creates virtus attributes' do
|
50
|
-
expect(
|
51
|
-
expect(
|
52
|
-
expect(
|
53
|
-
expect(
|
54
|
-
expect(
|
55
|
-
expect(
|
73
|
+
expect(dummy).to respond_to(:name)
|
74
|
+
expect(dummy).to respond_to(:name=)
|
75
|
+
expect(dummy).to respond_to(:ball)
|
76
|
+
expect(dummy).to respond_to(:ball=)
|
77
|
+
expect(dummy).to respond_to(:car)
|
78
|
+
expect(dummy).to respond_to(:car=)
|
79
|
+
expect(dummy).to respond_to(:email)
|
80
|
+
expect(dummy).to respond_to(:email=)
|
81
|
+
expect(dummy).to respond_to(:phone)
|
82
|
+
expect(dummy).to respond_to(:phone=)
|
56
83
|
end
|
57
84
|
|
58
|
-
it '
|
59
|
-
expect(
|
60
|
-
expect(
|
61
|
-
expect(
|
85
|
+
it 'is ready for validation' do
|
86
|
+
expect(dummy).to_not be_valid
|
87
|
+
expect(dummy.errors[:name]).to eq ["can't be blank"]
|
88
|
+
expect(dummy.errors[:phone]).to eq ["is too short (minimum is 4 characters)"]
|
62
89
|
end
|
63
90
|
|
64
|
-
it '
|
65
|
-
|
91
|
+
it 'calls persisted! when a valid form is saved' do
|
92
|
+
dummy.name = 'Dummy'
|
93
|
+
dummy.phone = '12345'
|
66
94
|
|
67
|
-
expect(
|
68
|
-
|
95
|
+
expect(dummy).to receive(:persist!).once
|
96
|
+
dummy.save
|
97
|
+
end
|
98
|
+
end
|
69
99
|
|
70
|
-
|
100
|
+
context 'when callbacks are defined' do
|
101
|
+
it 'triggers callbacks for save' do
|
102
|
+
dummy = form_with_fields do
|
103
|
+
before_save :callback_call
|
104
|
+
after_save :callback_call
|
105
|
+
end
|
71
106
|
|
72
|
-
|
73
|
-
|
107
|
+
dummy.name = 'Dummy'
|
108
|
+
dummy.phone = '12345'
|
74
109
|
|
75
|
-
expect(
|
76
|
-
|
110
|
+
expect(dummy).to receive(:callback_call).twice
|
111
|
+
dummy.save
|
77
112
|
end
|
78
113
|
|
79
|
-
it '
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
end
|
114
|
+
it 'triggers callbacks for validation' do
|
115
|
+
dummy = form_with_fields do
|
116
|
+
before_validation :callback_call
|
117
|
+
after_validation :callback_call
|
84
118
|
end
|
119
|
+
|
120
|
+
dummy.name = 'Dummy'
|
121
|
+
dummy.phone = '12345'
|
122
|
+
|
123
|
+
expect(dummy).to receive(:callback_call).twice
|
124
|
+
dummy.valid?
|
85
125
|
end
|
126
|
+
end
|
127
|
+
end
|
86
128
|
|
87
|
-
|
88
|
-
|
89
|
-
|
129
|
+
def form_with_fields(&block)
|
130
|
+
Class.new do
|
131
|
+
include SuperForm
|
132
|
+
|
133
|
+
fieldset :general do
|
134
|
+
field :name, Field::Text, presence: true
|
90
135
|
end
|
91
136
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
end
|
137
|
+
fieldset :toys do
|
138
|
+
field :ball, Field::Bare
|
139
|
+
field :car, Field::Text
|
96
140
|
end
|
97
|
-
|
141
|
+
|
142
|
+
field :email, Field::Text
|
143
|
+
field :phone, Field::Text, length: { minimum: 4 }
|
144
|
+
|
145
|
+
instance_eval(&block) if block_given?
|
146
|
+
end.new
|
147
|
+
end
|
148
|
+
|
149
|
+
def form_with_no_fields
|
150
|
+
Class.new do
|
151
|
+
include SuperForm
|
152
|
+
end.new
|
98
153
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'telephone'
|
3
|
+
|
4
|
+
describe Telephone do
|
5
|
+
it "returns true if valid" do
|
6
|
+
valid_numbers = ['8436429999', '(84) 1111-1111', '8498741122']
|
7
|
+
|
8
|
+
valid_numbers.each do |number|
|
9
|
+
telephone = Telephone.new(number)
|
10
|
+
expect(telephone).to be_valid
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns false if not valid" do
|
15
|
+
invalid_numbers = ['843649999', '843 aaa', 'aaa 1234 $%']
|
16
|
+
|
17
|
+
invalid_numbers.each do |number|
|
18
|
+
telephone = Telephone.new(number)
|
19
|
+
expect(telephone).to_not be_valid
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns a stripped number" do
|
24
|
+
telephone = Telephone.new('(84) 3642-9999')
|
25
|
+
expect(telephone.stripped).to eq('8436429999')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns a formatted number" do
|
29
|
+
telephone = Telephone.new('84 3642-9999')
|
30
|
+
expect(telephone.formatted).to eq('(84) 3642-9999')
|
31
|
+
end
|
32
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,17 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
-
# loaded once.
|
5
|
-
#
|
6
|
-
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
1
|
+
require 'pry'
|
2
|
+
|
7
3
|
RSpec.configure do |config|
|
8
4
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
5
|
config.run_all_when_everything_filtered = true
|
10
6
|
config.filter_run :focus
|
11
|
-
|
12
|
-
# Run specs in random order to surface order dependencies. If you find an
|
13
|
-
# order dependency and want to debug it, you can fix the order by providing
|
14
|
-
# the seed, which is printed after each run.
|
15
|
-
# --seed 1234
|
16
7
|
config.order = 'random'
|
17
8
|
end
|
9
|
+
|
10
|
+
I18n.enforce_available_locales = false if defined?(I18n)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
shared_examples "presenter nameable" do
|
2
|
+
describe '.name' do
|
3
|
+
it 'returns a demodulized and underscored presenter name' do
|
4
|
+
presenter = Class.new(described_class) do
|
5
|
+
def self.name
|
6
|
+
'Presenter::Deep::IDontExist'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
expect(presenter.__name__).to eq 'i_dont_exist'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'trims _presenter suffix' do
|
14
|
+
presenter = Class.new(described_class) do
|
15
|
+
def self.name
|
16
|
+
'Presenter::Deep::IDontExistPresenter'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
expect(presenter.__name__).to eq 'i_dont_exist'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'raises an exception if presenter is anonymous' do
|
24
|
+
presenter = Class.new(described_class)
|
25
|
+
expect { presenter.__name__ }.to raise_error RuntimeError
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/super_form.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency 'rspec', '2.14.1'
|
25
25
|
spec.add_development_dependency 'simplecov', '0.8.2'
|
26
26
|
spec.add_development_dependency 'rake'
|
27
|
+
spec.add_development_dependency 'pry', '0.9.12.6'
|
27
28
|
spec.add_development_dependency 'capybara', '2.2.0'
|
28
29
|
spec.add_development_dependency 'activemodel', '4.0.2'
|
29
30
|
spec.add_development_dependency 'activesupport', '4.0.2'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: super_form
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thiago A. Silva
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sqlite3
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
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.9.12.6
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.9.12.6
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: capybara
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -191,24 +205,53 @@ files:
|
|
191
205
|
- lib/cnpj_validator.rb
|
192
206
|
- lib/cpf_validator.rb
|
193
207
|
- lib/field.rb
|
208
|
+
- lib/field/bare.rb
|
194
209
|
- lib/field/base.rb
|
195
210
|
- lib/field/cnpj.rb
|
196
211
|
- lib/field/cpf.rb
|
197
212
|
- lib/field/email.rb
|
198
213
|
- lib/field/error.rb
|
214
|
+
- lib/field/float.rb
|
215
|
+
- lib/field/form.rb
|
216
|
+
- lib/field/form_array.rb
|
217
|
+
- lib/field/form_proxy.rb
|
199
218
|
- lib/field/password.rb
|
200
219
|
- lib/field/person_type.rb
|
201
220
|
- lib/field/telephone.rb
|
202
221
|
- lib/field/text.rb
|
203
222
|
- lib/person_type.rb
|
223
|
+
- lib/presenter.rb
|
224
|
+
- lib/presenter/cnpj.rb
|
225
|
+
- lib/presenter/cpf.rb
|
226
|
+
- lib/presenter/form.rb
|
227
|
+
- lib/presenter/password.rb
|
228
|
+
- lib/presenter/person_type.rb
|
229
|
+
- lib/presenter/telephone.rb
|
204
230
|
- lib/super_form.rb
|
231
|
+
- lib/super_form/fieldable.rb
|
232
|
+
- lib/super_form/fieldset.rb
|
205
233
|
- lib/super_form/version.rb
|
206
234
|
- lib/tasks/.keep
|
207
235
|
- lib/telephone.rb
|
208
236
|
- lib/telephone_validator.rb
|
209
237
|
- lib/uniqueness_validator.rb
|
238
|
+
- spec/lib/field/form_array.rb
|
239
|
+
- spec/lib/field/form_array_spec.rb
|
240
|
+
- spec/lib/field/form_spec.rb
|
241
|
+
- spec/lib/field_spec.rb
|
242
|
+
- spec/lib/person_type_spec.rb
|
243
|
+
- spec/lib/presenter/cnpj_spec.rb
|
244
|
+
- spec/lib/presenter/cpf_spec.rb
|
245
|
+
- spec/lib/presenter/form_spec.rb
|
246
|
+
- spec/lib/presenter/password_spec.rb
|
247
|
+
- spec/lib/presenter/person_type_spec.rb
|
248
|
+
- spec/lib/presenter/telephone_spec.rb
|
249
|
+
- spec/lib/presenter_spec.rb
|
250
|
+
- spec/lib/super_form/fieldable_spec.rb
|
210
251
|
- spec/lib/super_form_spec.rb
|
252
|
+
- spec/lib/telephone_spec.rb
|
211
253
|
- spec/spec_helper.rb
|
254
|
+
- spec/support/presenter_name.rb
|
212
255
|
- super_form.gemspec
|
213
256
|
homepage: http://github.com/thiagoa/super_form
|
214
257
|
licenses:
|
@@ -235,6 +278,21 @@ signing_key:
|
|
235
278
|
specification_version: 4
|
236
279
|
summary: Object oriented forms for Rails
|
237
280
|
test_files:
|
281
|
+
- spec/lib/field/form_array.rb
|
282
|
+
- spec/lib/field/form_array_spec.rb
|
283
|
+
- spec/lib/field/form_spec.rb
|
284
|
+
- spec/lib/field_spec.rb
|
285
|
+
- spec/lib/person_type_spec.rb
|
286
|
+
- spec/lib/presenter/cnpj_spec.rb
|
287
|
+
- spec/lib/presenter/cpf_spec.rb
|
288
|
+
- spec/lib/presenter/form_spec.rb
|
289
|
+
- spec/lib/presenter/password_spec.rb
|
290
|
+
- spec/lib/presenter/person_type_spec.rb
|
291
|
+
- spec/lib/presenter/telephone_spec.rb
|
292
|
+
- spec/lib/presenter_spec.rb
|
293
|
+
- spec/lib/super_form/fieldable_spec.rb
|
238
294
|
- spec/lib/super_form_spec.rb
|
295
|
+
- spec/lib/telephone_spec.rb
|
239
296
|
- spec/spec_helper.rb
|
297
|
+
- spec/support/presenter_name.rb
|
240
298
|
has_rdoc:
|