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,71 @@
|
|
1
|
+
require 'super_form'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Field::FormArray do
|
5
|
+
context 'when creating a form collection field' do
|
6
|
+
it 'assigns an array of child forms to the field attribute' do
|
7
|
+
child_form = Class.new { include SuperForm }
|
8
|
+
|
9
|
+
field = Field::FormArray.new(:fake)
|
10
|
+
field.form_class = child_form
|
11
|
+
|
12
|
+
expect(field.attribute).to eq Array[child_form]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when the form field has a container' do
|
17
|
+
before do
|
18
|
+
@child_form = Class.new do
|
19
|
+
include SuperForm
|
20
|
+
|
21
|
+
field :name, Field::Text, presence: true
|
22
|
+
end
|
23
|
+
|
24
|
+
parent_form = Class.new { include SuperForm }
|
25
|
+
|
26
|
+
field = Field::FormArray.new(:child_form)
|
27
|
+
field.form_class = @child_form
|
28
|
+
field.setup_container(parent_form)
|
29
|
+
|
30
|
+
@parent_form = parent_form.new
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#inject_attributes' do
|
34
|
+
it 'injects attributes into the parent form' do
|
35
|
+
expect(@parent_form).to respond_to :child_form=
|
36
|
+
expect(@parent_form).to respond_to :child_form
|
37
|
+
expect(@parent_form.child_form).to eq []
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#inject validations' do
|
42
|
+
it 'forces the parent object to validate the child object' do
|
43
|
+
@parent_form.child_form = [@child_form.new, @child_form.new, @child_form.new]
|
44
|
+
@parent_form.save
|
45
|
+
errors = [
|
46
|
+
'Invalid child_form on row 1',
|
47
|
+
'Invalid child_form on row 2',
|
48
|
+
'Invalid child_form on row 3'
|
49
|
+
]
|
50
|
+
expect(@parent_form.errors[:base]).to eq(errors)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#[]' do
|
56
|
+
before do
|
57
|
+
@child_form = Class.new { include SuperForm }
|
58
|
+
proxy = Field::FormArray[@child_form]
|
59
|
+
|
60
|
+
@field = proxy.factory(:name)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'creates a form instance' do
|
64
|
+
expect(@field).to be_instance_of(Field::FormArray)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'stores the child form into the form_class attribute' do
|
68
|
+
expect(@field.form_class).to eq @child_form
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'super_form'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Field::Form do
|
5
|
+
context 'when creating a form field isolatedly' do
|
6
|
+
it 'assigns the child form to the field attribute' do
|
7
|
+
child_form = Class.new { include SuperForm }
|
8
|
+
|
9
|
+
field = Field::Form.new(:fake)
|
10
|
+
field.form_class = child_form
|
11
|
+
|
12
|
+
expect(field.attribute).to eq child_form
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when the form field has a container' do
|
17
|
+
before do
|
18
|
+
@child_form = Class.new do
|
19
|
+
include SuperForm
|
20
|
+
|
21
|
+
field :name, Field::Text, presence: true
|
22
|
+
end
|
23
|
+
|
24
|
+
parent_form = Class.new { include SuperForm }
|
25
|
+
|
26
|
+
field = Field::Form.new(:child_form)
|
27
|
+
field.form_class = @child_form
|
28
|
+
field.setup_container(parent_form)
|
29
|
+
|
30
|
+
@parent_form = parent_form.new
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#inject_attributes' do
|
34
|
+
it 'injects virtus attributes into the parent form' do
|
35
|
+
expect(@parent_form).to respond_to :child_form=
|
36
|
+
expect(@parent_form).to respond_to :child_form
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns an instance of child form as the default value' do
|
40
|
+
expect(@parent_form.child_form).to be_instance_of(@child_form)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#inject validations' do
|
45
|
+
it 'forces the parent object to validate the child object' do
|
46
|
+
@parent_form.save
|
47
|
+
expect(@parent_form.errors[:base]).to eq(['Invalid child_form'])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#[]' do
|
53
|
+
before do
|
54
|
+
@child_form = Class.new { include SuperForm }
|
55
|
+
proxy = Field::Form[@child_form]
|
56
|
+
|
57
|
+
@field = proxy.factory(:name)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'creates a form instance' do
|
61
|
+
expect(@field).to be_instance_of(Field::Form)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'stores the child form into the form_class attribute' do
|
65
|
+
expect(@field.form_class).to eq @child_form
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'field'
|
2
|
+
|
3
|
+
describe Field::Base do
|
4
|
+
it 'responds to presenter_class' do
|
5
|
+
field = Field::Base.new(:fake)
|
6
|
+
expect(field).to respond_to :presenter_class
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'presenter_class returns nil by default' do
|
10
|
+
field = Field::Base.new(:fake)
|
11
|
+
expect(field.presenter_class).to be_nil
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'person_type'
|
3
|
+
|
4
|
+
describe PersonType do
|
5
|
+
describe '#valid?' do
|
6
|
+
it "returns false when person type is invalid" do
|
7
|
+
invalid_values = %w{one two three four 3244}
|
8
|
+
|
9
|
+
invalid_values.each do |value|
|
10
|
+
person = PersonType.new(value)
|
11
|
+
expect(person).to_not be_valid
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns true when person type is valid" do
|
16
|
+
valid_values = [PersonType::NATURAL, PersonType::LEGAL]
|
17
|
+
|
18
|
+
valid_values.each do |value|
|
19
|
+
person = PersonType.new(value)
|
20
|
+
expect(person).to be_valid
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#value" do
|
26
|
+
context "with a valid value" do
|
27
|
+
it "returns the value" do
|
28
|
+
person = PersonType.new(PersonType::LEGAL)
|
29
|
+
expect(person.value).to eq PersonType::LEGAL
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "with an invalid value" do
|
34
|
+
it "returns nil" do
|
35
|
+
person = PersonType.new('bossal')
|
36
|
+
expect(person.value).to be_nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#description' do
|
42
|
+
it 'returns "Natural person" when value is "natural"' do
|
43
|
+
person = PersonType.new(PersonType::NATURAL)
|
44
|
+
expect(person.description).to eq 'Natural person'
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'returns "Legal entity" when value is "legal"' do
|
48
|
+
person = PersonType.new(PersonType::LEGAL)
|
49
|
+
expect(person.description).to eq 'Legal entity'
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'returns a default description otherwise' do
|
53
|
+
person = PersonType.new('bossal')
|
54
|
+
expect(person.description('Bossal')).to eq 'Bossal'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '.to_collection' do
|
59
|
+
it "returns an array with the collection" do
|
60
|
+
expect(PersonType.to_collection).to eq [
|
61
|
+
['Natural person', PersonType::NATURAL],
|
62
|
+
['Legal entity', PersonType::LEGAL],
|
63
|
+
]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'super_form'
|
2
|
+
require 'presenter'
|
3
|
+
|
4
|
+
describe Presenter::Form do
|
5
|
+
it 'outputs each field according to its defined presenter class' do
|
6
|
+
field_class_with_presenter_class = Class.new(Field::Base) do
|
7
|
+
def presenter_class
|
8
|
+
Class.new(Presenter::Each) do
|
9
|
+
def self.__name__
|
10
|
+
'anonymous'
|
11
|
+
end
|
12
|
+
|
13
|
+
def output
|
14
|
+
'formatted output'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
field_class_without_presenter_class = Class.new(Field::Base)
|
21
|
+
|
22
|
+
form_class = Class.new do
|
23
|
+
include SuperForm
|
24
|
+
|
25
|
+
add_field(field_class_with_presenter_class.new(:with_presenter))
|
26
|
+
add_field(field_class_without_presenter_class.new(:without_presenter))
|
27
|
+
end
|
28
|
+
|
29
|
+
form = form_class.new(
|
30
|
+
with_presenter: 'unformatted output',
|
31
|
+
without_presenter: 'unformattable'
|
32
|
+
)
|
33
|
+
|
34
|
+
presenter = Presenter::Form.factory(form)
|
35
|
+
|
36
|
+
expect(presenter.with_presenter).to eq('formatted output')
|
37
|
+
expect(presenter.without_presenter).to eq('unformattable')
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'presenter'
|
2
|
+
require File.expand_path('../../support/presenter_name', __FILE__)
|
3
|
+
|
4
|
+
module Presenter
|
5
|
+
describe Base do
|
6
|
+
it_behaves_like 'presenter nameable'
|
7
|
+
|
8
|
+
describe 'delegates to the source object' do
|
9
|
+
it 'calls the source object correspondent methods' do
|
10
|
+
source = stub_source_object([:name, :phone])
|
11
|
+
presenter = Base.new(source)
|
12
|
+
|
13
|
+
expect(source).to receive(:name)
|
14
|
+
expect(source).to receive(:phone)
|
15
|
+
|
16
|
+
presenter.name
|
17
|
+
presenter.phone
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns the same values as the source object' do
|
21
|
+
source = stub_source_object([:name, :phone])
|
22
|
+
presenter = Base.new(source)
|
23
|
+
|
24
|
+
expect(presenter.name).to eq (source.name)
|
25
|
+
expect(presenter.phone).to eq (source.phone)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '.map' do
|
30
|
+
context 'with one mapping specified' do
|
31
|
+
it 'assigns specified attribute to specified "each presenter"' do
|
32
|
+
presenter = stub_presenter(:inexistent) { map :inexistent => :fake }
|
33
|
+
fake_presenter = stub_each_presenter(:fake, presenter)
|
34
|
+
|
35
|
+
expect(presenter.inexistent).to eq fake_presenter.output
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with multiple mappings specified' do
|
40
|
+
it 'assigns specified attributes to specified "each presenters"' do
|
41
|
+
presenter = stub_presenter(:inexistent, :power) do
|
42
|
+
map :inexistent => :fake, :power => :chord
|
43
|
+
end
|
44
|
+
|
45
|
+
fake = stub_each_presenter(:fake, presenter)
|
46
|
+
chord = stub_each_presenter(:chord, presenter)
|
47
|
+
|
48
|
+
expect(presenter.inexistent).to eq fake.output
|
49
|
+
expect(presenter.power).to eq chord.output
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'tries to guess the presenter when no presenter is assigned' do
|
54
|
+
presenter = stub_presenter(:something) { map :something => :fake }
|
55
|
+
|
56
|
+
class Fake < Each
|
57
|
+
def output
|
58
|
+
'123456'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
expect(presenter.something).to eq('123456')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '.use' do
|
67
|
+
context 'with one presenter specified' do
|
68
|
+
it 'uses one presenter' do
|
69
|
+
presenter = stub_presenter(:inexistent) { use :inexistent }
|
70
|
+
inexistent = stub_each_presenter(:inexistent, presenter)
|
71
|
+
|
72
|
+
expect(presenter.inexistent).to eq inexistent.output
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'with multiple presenters specified' do
|
77
|
+
it 'uses multiple presenters' do
|
78
|
+
presenter = stub_presenter(:inexistent, :fake) do
|
79
|
+
use :inexistent, :fake
|
80
|
+
end
|
81
|
+
|
82
|
+
inexistent = stub_each_presenter(:inexistent, presenter)
|
83
|
+
fake = stub_each_presenter(:fake, presenter)
|
84
|
+
|
85
|
+
expect(presenter.inexistent).to eq inexistent.output
|
86
|
+
expect(presenter.fake).to eq fake.output
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'tries to guess the presenter when no presenter is assigned' do
|
91
|
+
presenter = stub_presenter(:inexistent) { use :inexistent }
|
92
|
+
|
93
|
+
class Inexistent < Each
|
94
|
+
def output
|
95
|
+
'12345'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
expect(presenter.inexistent).to eq('12345')
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'works if given a presenter class instead of a symbol' do
|
103
|
+
each_presenter = Class.new(Each) do
|
104
|
+
def self.__name__
|
105
|
+
'fake'
|
106
|
+
end
|
107
|
+
|
108
|
+
def output
|
109
|
+
'it works'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
presenter = stub_presenter(:fake) { map :fake => each_presenter }
|
114
|
+
expect(presenter.fake).to eq('it works')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe Each do
|
120
|
+
it_behaves_like 'presenter nameable'
|
121
|
+
|
122
|
+
it 'can access the raw value' do
|
123
|
+
presenter = Each.new('some value')
|
124
|
+
expect(presenter.value).to eq('some value')
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'outputs the raw value by default' do
|
128
|
+
presenter = Each.new('some value')
|
129
|
+
expect(presenter.output).to eq(presenter.value)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'delegates to :output when :to_s is called' do
|
133
|
+
presenter = Each.new('some value')
|
134
|
+
expect(presenter.to_s).to eq(presenter.output)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def stub_source_object(params)
|
140
|
+
source = Object.new
|
141
|
+
|
142
|
+
Array(params).each do |p|
|
143
|
+
source.stub(p).and_return(p.to_s)
|
144
|
+
end
|
145
|
+
|
146
|
+
source
|
147
|
+
end
|
148
|
+
|
149
|
+
def stub_presenter(*source_params, &block)
|
150
|
+
source = stub_source_object(source_params)
|
151
|
+
Class.new(Presenter::Base, &block).new(source)
|
152
|
+
end
|
153
|
+
|
154
|
+
def stub_each_presenter(id, presenter = nil)
|
155
|
+
each_presenter = Class.new(Presenter::Each) do
|
156
|
+
def output
|
157
|
+
'output'
|
158
|
+
end
|
159
|
+
end.new
|
160
|
+
|
161
|
+
if presenter
|
162
|
+
presenter.send("#{id}_presenter=", each_presenter)
|
163
|
+
end
|
164
|
+
|
165
|
+
each_presenter
|
166
|
+
end
|