formotion 0.0.3 → 0.5
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.
- data/.gitignore +2 -1
- data/CHANGELOG.md +10 -0
- data/Gemfile +6 -0
- data/LIST_OF_ROW_TYPES.md +163 -0
- data/NEW_ROW_TYPES.md +73 -0
- data/README.md +11 -14
- data/Rakefile +6 -0
- data/app/app_delegate.rb +22 -0
- data/examples/KitchenSink/Rakefile +1 -1
- data/examples/KitchenSink/app/app_delegate.rb +50 -2
- data/examples/Login/.gitignore +5 -0
- data/examples/Login/Rakefile +9 -0
- data/examples/Login/app/app_delegate.rb +16 -0
- data/examples/Login/app/login_controller.rb +47 -0
- data/examples/Login/app/user_controller.rb +38 -0
- data/examples/Login/spec/main_spec.rb +9 -0
- data/lib/formotion.rb +7 -1
- data/lib/formotion/{form.rb → form/form.rb} +0 -0
- data/lib/formotion/{form_delegate.rb → form/form_delegate.rb} +10 -15
- data/lib/formotion/patch/object.rb +9 -0
- data/lib/formotion/patch/ui_action_sheet.rb +27 -0
- data/lib/formotion/patch/ui_text_view.rb +122 -0
- data/lib/formotion/patch/ui_text_view_placeholder.rb +65 -0
- data/lib/formotion/{row.rb → row/row.rb} +37 -27
- data/lib/formotion/row/row_cell_builder.rb +28 -0
- data/lib/formotion/row_type/base.rb +41 -0
- data/lib/formotion/row_type/check_row.rb +30 -0
- data/lib/formotion/row_type/date_row.rb +61 -0
- data/lib/formotion/row_type/email_row.rb +11 -0
- data/lib/formotion/row_type/image_row.rb +99 -0
- data/lib/formotion/row_type/number_row.rb +11 -0
- data/lib/formotion/row_type/options_row.rb +24 -0
- data/lib/formotion/row_type/phone_row.rb +11 -0
- data/lib/formotion/row_type/row_type.rb +21 -0
- data/lib/formotion/row_type/slider_row.rb +43 -0
- data/lib/formotion/row_type/static_row.rb +6 -0
- data/lib/formotion/row_type/string_row.rb +112 -0
- data/lib/formotion/row_type/submit_row.rb +34 -0
- data/lib/formotion/row_type/switch_row.rb +19 -0
- data/lib/formotion/row_type/text_row.rb +76 -0
- data/lib/formotion/{section.rb → section/section.rb} +3 -0
- data/lib/formotion/version.rb +1 -1
- data/spec/form_spec.rb +5 -4
- data/spec/functional/character_spec.rb +70 -0
- data/spec/functional/check_row_spec.rb +42 -0
- data/spec/functional/date_row_spec.rb +63 -0
- data/spec/functional/image_row_spec.rb +82 -0
- data/spec/functional/options_row_spec.rb +27 -0
- data/spec/functional/slider_row_spec.rb +27 -0
- data/spec/functional/submit_row_spec.rb +30 -0
- data/spec/functional/switch_row_spec.rb +28 -0
- data/spec/functional/text_row_spec.rb +60 -0
- data/spec/row_type/check_spec.rb +27 -0
- data/spec/row_type/date_spec.rb +69 -0
- data/spec/row_type/email_spec.rb +22 -0
- data/spec/row_type/image_spec.rb +43 -0
- data/spec/row_type/number_spec.rb +22 -0
- data/spec/row_type/options_spec.rb +37 -0
- data/spec/row_type/phone_spec.rb +22 -0
- data/spec/row_type/slider_spec.rb +47 -0
- data/spec/row_type/static_spec.rb +15 -0
- data/spec/row_type/string_spec.rb +52 -0
- data/spec/row_type/submit_spec.rb +28 -0
- data/spec/row_type/switch_spec.rb +27 -0
- data/spec/row_type/text_spec.rb +41 -0
- data/spec/support/ui_control_wrap_extension.rb +7 -0
- metadata +88 -9
- data/lib/formotion/row_cell_builder.rb +0 -168
- data/lib/formotion/row_type.rb +0 -33
@@ -0,0 +1,27 @@
|
|
1
|
+
describe "FormController/SliderRow" do
|
2
|
+
tests Formotion::FormController
|
3
|
+
|
4
|
+
# By default, `tests` uses @controller.init
|
5
|
+
# this isn't ideal for our case, so override.
|
6
|
+
def controller
|
7
|
+
row_settings = {
|
8
|
+
title: "Slider",
|
9
|
+
key: :slider,
|
10
|
+
type: :slider,
|
11
|
+
range: (1..100),
|
12
|
+
value: 1
|
13
|
+
}
|
14
|
+
@form ||= Formotion::Form.new(
|
15
|
+
sections: [{
|
16
|
+
rows:[row_settings]
|
17
|
+
}])
|
18
|
+
|
19
|
+
@controller ||= Formotion::FormController.alloc.initWithForm(@form)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should change row value when sliding" do
|
23
|
+
@form.sections[0].rows[0].value.should == 1
|
24
|
+
drag("Slider Slider", :from => :left)
|
25
|
+
@form.sections[0].rows[0].value.should == 100
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
describe "FormController/SubmitRow" do
|
2
|
+
tests Formotion::FormController
|
3
|
+
|
4
|
+
# By default, `tests` uses @controller.init
|
5
|
+
# this isn't ideal for our case, so override.
|
6
|
+
def controller
|
7
|
+
row_settings = {
|
8
|
+
title: "Submit",
|
9
|
+
type: :submit
|
10
|
+
}
|
11
|
+
@form ||= Formotion::Form.new(
|
12
|
+
sections: [{
|
13
|
+
rows:[row_settings]
|
14
|
+
}])
|
15
|
+
|
16
|
+
@controller ||= Formotion::FormController.alloc.initWithForm(@form)
|
17
|
+
end
|
18
|
+
|
19
|
+
def submit_row
|
20
|
+
@form.sections.first.rows.first
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should call .submit when tapped" do
|
24
|
+
@form.on_submit do
|
25
|
+
@submitted = true
|
26
|
+
end
|
27
|
+
tap("Submit")
|
28
|
+
@submitted.should == true
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
describe "FormController/SwitchRow" do
|
2
|
+
tests Formotion::FormController
|
3
|
+
|
4
|
+
# By default, `tests` uses @controller.init
|
5
|
+
# this isn't ideal for our case, so override.
|
6
|
+
def controller
|
7
|
+
row_settings = {
|
8
|
+
title: "Switch",
|
9
|
+
key: :switch,
|
10
|
+
type: :switch,
|
11
|
+
value: false
|
12
|
+
}
|
13
|
+
@form ||= Formotion::Form.new(
|
14
|
+
sections: [{
|
15
|
+
rows:[row_settings]
|
16
|
+
}])
|
17
|
+
|
18
|
+
@controller ||= Formotion::FormController.alloc.initWithForm(@form)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should change row value when tapped" do
|
22
|
+
tap("Switch Switch")
|
23
|
+
@form.sections[0].rows[0].value.should == true
|
24
|
+
|
25
|
+
tap("Switch Switch")
|
26
|
+
@form.sections[0].rows[0].value.should == false
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
describe "FormController/TextRow" do
|
2
|
+
tests Formotion::FormController
|
3
|
+
|
4
|
+
# By default, `tests` uses @controller.init
|
5
|
+
# this isn't ideal for our case, so override.
|
6
|
+
def controller
|
7
|
+
row_settings = {
|
8
|
+
title: "Text",
|
9
|
+
key: :text,
|
10
|
+
type: :text
|
11
|
+
}
|
12
|
+
@form ||= Formotion::Form.new(
|
13
|
+
sections: [{
|
14
|
+
rows:[row_settings]
|
15
|
+
}])
|
16
|
+
|
17
|
+
@controller ||= Formotion::FormController.alloc.initWithForm(@form)
|
18
|
+
end
|
19
|
+
|
20
|
+
def text_row
|
21
|
+
@form.sections.first.rows.first
|
22
|
+
end
|
23
|
+
|
24
|
+
after do
|
25
|
+
text_row.object.dismissKeyboard
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should pop open the keyboard when tapped" do
|
29
|
+
@notif = App.notification_center.observe UIKeyboardDidShowNotification do |notification|
|
30
|
+
@did_show = true
|
31
|
+
end
|
32
|
+
tap("Text")
|
33
|
+
wait 1 do
|
34
|
+
@did_show.should == true
|
35
|
+
App.notification_center.unobserve @notif
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should close the keyboard when tapped again" do
|
40
|
+
@notif = App.notification_center.observe UIKeyboardDidHideNotification do |notification|
|
41
|
+
@did_hide = true
|
42
|
+
end
|
43
|
+
|
44
|
+
tap("Text")
|
45
|
+
wait 1 do
|
46
|
+
tap("Text")
|
47
|
+
wait 1 do
|
48
|
+
@did_hide.should == true
|
49
|
+
App.notification_center.unobserve @notif
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should change value of row when typing" do
|
55
|
+
tap("Text")
|
56
|
+
text_row.object.field.text = "Hello"
|
57
|
+
text_row.object.field.delegate.textViewDidChange(text_row.object.field)
|
58
|
+
text_row.value.should == "Hello"
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
describe "Check Row" do
|
2
|
+
before do
|
3
|
+
row_settings = {
|
4
|
+
title: "Check",
|
5
|
+
key: :check,
|
6
|
+
type: :check,
|
7
|
+
}
|
8
|
+
@row = Formotion::Row.new(row_settings)
|
9
|
+
@row.reuse_identifier = 'test'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should initialize with correct settings" do
|
13
|
+
@row.object.class.should == Formotion::RowType::CheckRow
|
14
|
+
end
|
15
|
+
|
16
|
+
# Value
|
17
|
+
it "should be unchecked by default" do
|
18
|
+
cell = @row.make_cell
|
19
|
+
cell.accessoryType.should == UITableViewCellAccessoryNone
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should be checked when true" do
|
23
|
+
@row.value = true
|
24
|
+
cell = @row.make_cell
|
25
|
+
cell.accessoryType.should == UITableViewCellAccessoryCheckmark
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
MILLENIUM = 946684672
|
2
|
+
TIME_ZONE = NSTimeZone.timeZoneWithName "Europe/Paris"
|
3
|
+
|
4
|
+
describe "Date Row" do
|
5
|
+
before do
|
6
|
+
row_settings = {
|
7
|
+
title: "Date",
|
8
|
+
key: :date,
|
9
|
+
type: :date,
|
10
|
+
}
|
11
|
+
@row = Formotion::Row.new(row_settings)
|
12
|
+
@row.reuse_identifier = 'test'
|
13
|
+
@row.object.formatter.timeZone = TIME_ZONE
|
14
|
+
@row.object.picker.timeZone = TIME_ZONE
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should initialize with correct settings" do
|
18
|
+
@row.object.class.should == Formotion::RowType::DateRow
|
19
|
+
end
|
20
|
+
|
21
|
+
# Value
|
22
|
+
it "should have no value by default" do
|
23
|
+
cell = @row.make_cell
|
24
|
+
|
25
|
+
@row.text_field.text.should == nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should use custom value" do
|
29
|
+
@row.value = MILLENIUM
|
30
|
+
cell = @row.make_cell
|
31
|
+
|
32
|
+
|
33
|
+
@row.text_field.text.should == '1/1/00'
|
34
|
+
end
|
35
|
+
|
36
|
+
# Picker
|
37
|
+
it "should build date picker" do
|
38
|
+
@row.object.picker.class.should == UIDatePicker
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should update value when date is picked" do
|
42
|
+
cell = @row.make_cell
|
43
|
+
|
44
|
+
@row.object.picker.date = NSDate.dateWithTimeIntervalSince1970(MILLENIUM)
|
45
|
+
@row.object.picker.trigger UIControlEventValueChanged
|
46
|
+
|
47
|
+
@row.value.should == MILLENIUM
|
48
|
+
@row.text_field.text.should == '1/1/00'
|
49
|
+
end
|
50
|
+
|
51
|
+
# Formats
|
52
|
+
{
|
53
|
+
:short => '1/1/00',
|
54
|
+
:medium => 'Jan 1, 2000',
|
55
|
+
:long => 'January 1, 2000',
|
56
|
+
:full => 'Saturday, January 1, 2000'
|
57
|
+
}.each do |format, expected_output|
|
58
|
+
|
59
|
+
it "should display date in full format" do
|
60
|
+
@row.value = MILLENIUM
|
61
|
+
@row.format = format
|
62
|
+
@row.object.instance_variable_set("@formatter", nil)
|
63
|
+
@row.object.formatter.timeZone = TIME_ZONE
|
64
|
+
cell = @row.make_cell
|
65
|
+
|
66
|
+
@row.text_field.text.should == expected_output
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
describe "Email Row" do
|
2
|
+
before do
|
3
|
+
row_settings = {
|
4
|
+
title: "Email",
|
5
|
+
key: :email,
|
6
|
+
type: :email,
|
7
|
+
}
|
8
|
+
@row = Formotion::Row.new(row_settings)
|
9
|
+
@row.reuse_identifier = 'test'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should initialize with correct settings" do
|
13
|
+
@row.object.class.should == Formotion::RowType::EmailRow
|
14
|
+
end
|
15
|
+
|
16
|
+
# Keyboard
|
17
|
+
it "should use email keyboard" do
|
18
|
+
cell = @row.make_cell
|
19
|
+
@row.text_field.keyboardType.should == UIKeyboardTypeEmailAddress
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
describe "Image Row" do
|
2
|
+
before do
|
3
|
+
row_settings = {
|
4
|
+
title: "Photo",
|
5
|
+
key: :photo,
|
6
|
+
type: :image
|
7
|
+
}
|
8
|
+
@row = Formotion::Row.new(row_settings)
|
9
|
+
@row.reuse_identifier = 'test'
|
10
|
+
|
11
|
+
|
12
|
+
@row.instance_eval do
|
13
|
+
def form
|
14
|
+
@form ||= Object.new.tap do |o|
|
15
|
+
def o.reload_data
|
16
|
+
# do nothing for tests
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should build cell with an image view" do
|
24
|
+
cell = @row.make_cell
|
25
|
+
image_view = cell.viewWithTag(Formotion::RowType::ImageRow::IMAGE_VIEW_TAG)
|
26
|
+
image_view.nil?.should == false
|
27
|
+
image_view.class.should == UIImageView
|
28
|
+
image_view.image.nil?.should == true
|
29
|
+
cell.accessoryView.class.should == UIButton
|
30
|
+
end
|
31
|
+
|
32
|
+
# Value
|
33
|
+
it "should change row properties when row gets a value" do
|
34
|
+
cell = @row.make_cell
|
35
|
+
|
36
|
+
@row.value = UIImage.alloc.init
|
37
|
+
|
38
|
+
@row.rowHeight.should > 44
|
39
|
+
image_view = cell.viewWithTag(Formotion::RowType::ImageRow::IMAGE_VIEW_TAG)
|
40
|
+
image_view.image.nil?.should == false
|
41
|
+
cell.accessoryView.nil?.should == true
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
describe "Number Row" do
|
2
|
+
before do
|
3
|
+
row_settings = {
|
4
|
+
title: "Number",
|
5
|
+
key: :number,
|
6
|
+
type: :number,
|
7
|
+
}
|
8
|
+
@row = Formotion::Row.new(row_settings)
|
9
|
+
@row.reuse_identifier = 'test'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should initialize with correct settings" do
|
13
|
+
@row.object.class.should == Formotion::RowType::NumberRow
|
14
|
+
end
|
15
|
+
|
16
|
+
# Keyboard
|
17
|
+
it "should use decimal keyboard" do
|
18
|
+
cell = @row.make_cell
|
19
|
+
@row.text_field.keyboardType.should == UIKeyboardTypeDecimalPad
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
describe "Options Row" do
|
2
|
+
before do
|
3
|
+
row_settings = {
|
4
|
+
title: "Options",
|
5
|
+
key: :options,
|
6
|
+
type: :options,
|
7
|
+
items: ['First', 'Second']
|
8
|
+
}
|
9
|
+
@row = Formotion::Row.new(row_settings)
|
10
|
+
@row.reuse_identifier = 'test'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should initialize with correct settings" do
|
14
|
+
@row.object.class.should == Formotion::RowType::OptionsRow
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should build cell with segmented control" do
|
18
|
+
cell = @row.make_cell
|
19
|
+
cell.accessoryView.class.should == UISegmentedControl
|
20
|
+
end
|
21
|
+
|
22
|
+
# Value
|
23
|
+
it "should select default value" do
|
24
|
+
cell = @row.make_cell
|
25
|
+
|
26
|
+
cell.accessoryView.selectedSegmentIndex.should == -1
|
27
|
+
@row.value.should == nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should select custom value" do
|
31
|
+
@row.value = 'Second'
|
32
|
+
cell = @row.make_cell
|
33
|
+
|
34
|
+
cell.accessoryView.selectedSegmentIndex.should == 1
|
35
|
+
@row.value.should == 'Second'
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
describe "Phone Row" do
|
2
|
+
before do
|
3
|
+
row_settings = {
|
4
|
+
title: "Phone",
|
5
|
+
key: :phone,
|
6
|
+
type: :phone,
|
7
|
+
}
|
8
|
+
@row = Formotion::Row.new(row_settings)
|
9
|
+
@row.reuse_identifier = 'test'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should initialize with correct settings" do
|
13
|
+
@row.object.class.should == Formotion::RowType::PhoneRow
|
14
|
+
end
|
15
|
+
|
16
|
+
# Keyboard
|
17
|
+
it "should use phone keyboard" do
|
18
|
+
cell = @row.make_cell
|
19
|
+
@row.text_field.keyboardType.should == UIKeyboardTypePhonePad
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
describe "Slider Row" do
|
2
|
+
before do
|
3
|
+
row_settings = {
|
4
|
+
title: "Slider",
|
5
|
+
key: :slider,
|
6
|
+
type: :slider,
|
7
|
+
range: (1..100)
|
8
|
+
}
|
9
|
+
@row = Formotion::Row.new(row_settings)
|
10
|
+
@row.reuse_identifier = 'test'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should initialize with correct settings" do
|
14
|
+
@row.object.class.should == Formotion::RowType::SliderRow
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should build cell with slider" do
|
18
|
+
cell = @row.make_cell
|
19
|
+
cell.accessoryView.class.should == UISlider
|
20
|
+
end
|
21
|
+
|
22
|
+
# Value
|
23
|
+
it "should set custom value" do
|
24
|
+
@row.value = 50
|
25
|
+
cell = @row.make_cell
|
26
|
+
|
27
|
+
cell.accessoryView.value.should == 50
|
28
|
+
@row.value.should == 50
|
29
|
+
end
|
30
|
+
|
31
|
+
# Range
|
32
|
+
it "should use default range" do
|
33
|
+
@row.range = nil
|
34
|
+
cell = @row.make_cell
|
35
|
+
|
36
|
+
cell.accessoryView.minimumValue.should == 1
|
37
|
+
cell.accessoryView.maximumValue.should == 10
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should use custom range values" do
|
41
|
+
@row.range = (50..100)
|
42
|
+
cell = @row.make_cell
|
43
|
+
|
44
|
+
cell.accessoryView.minimumValue.should == 50
|
45
|
+
cell.accessoryView.maximumValue.should == 100
|
46
|
+
end
|
47
|
+
end
|