formotion 0.5.1 → 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.
- data/CHANGELOG.md +24 -0
- data/LIST_OF_ROW_TYPES.md +1 -1
- data/Rakefile +20 -5
- data/app/app_delegate.rb +89 -17
- data/examples/FormModel/.gitignore +5 -0
- data/examples/FormModel/Rakefile +9 -0
- data/examples/FormModel/app/app_delegate.rb +11 -0
- data/examples/FormModel/app/user.rb +18 -0
- data/examples/FormModel/app/users_controller.rb +52 -0
- data/examples/FormModel/spec/main_spec.rb +9 -0
- data/examples/KitchenSink/app/app_delegate.rb +2 -2
- data/gh-pages/assets/css/bootstrap-responsive.css +815 -0
- data/gh-pages/assets/css/bootstrap-responsive.min.css +9 -0
- data/gh-pages/assets/css/bootstrap.css +4983 -0
- data/gh-pages/assets/css/bootstrap.min.css +9 -0
- data/gh-pages/assets/css/formotion.css +117 -0
- data/gh-pages/assets/css/pygments.css +62 -0
- data/gh-pages/assets/img/glyphicons-halflings-white.png +0 -0
- data/gh-pages/assets/img/glyphicons-halflings.png +0 -0
- data/gh-pages/assets/js/bootstrap-alert.js +90 -0
- data/gh-pages/assets/js/bootstrap-button.js +96 -0
- data/gh-pages/assets/js/bootstrap-carousel.js +169 -0
- data/gh-pages/assets/js/bootstrap-collapse.js +157 -0
- data/gh-pages/assets/js/bootstrap-dropdown.js +100 -0
- data/gh-pages/assets/js/bootstrap-modal.js +218 -0
- data/gh-pages/assets/js/bootstrap-popover.js +98 -0
- data/gh-pages/assets/js/bootstrap-scrollspy.js +151 -0
- data/gh-pages/assets/js/bootstrap-tab.js +135 -0
- data/gh-pages/assets/js/bootstrap-tooltip.js +275 -0
- data/gh-pages/assets/js/bootstrap-transition.js +61 -0
- data/gh-pages/assets/js/bootstrap-typeahead.js +285 -0
- data/gh-pages/assets/js/bootstrap.js +1825 -0
- data/gh-pages/assets/js/bootstrap.min.js +6 -0
- data/gh-pages/index.html +205 -0
- data/lib/formotion.rb +15 -2
- data/lib/formotion/base.rb +5 -5
- data/lib/formotion/{form_controller.rb → controller/form_controller.rb} +22 -3
- data/lib/formotion/controller/formable_controller.rb +21 -0
- data/lib/formotion/form/form.rb +31 -8
- data/lib/formotion/form/form_delegate.rb +26 -3
- data/lib/formotion/model/formable.rb +78 -0
- data/lib/formotion/row/row.rb +54 -21
- data/lib/formotion/row/row_cell_builder.rb +1 -1
- data/lib/formotion/row_type/back_row.rb +11 -0
- data/lib/formotion/row_type/base.rb +42 -1
- data/lib/formotion/row_type/button.rb +30 -0
- data/lib/formotion/row_type/check_row.rb +9 -5
- data/lib/formotion/row_type/date_row.rb +5 -0
- data/lib/formotion/row_type/edit_row.rb +14 -0
- data/lib/formotion/row_type/image_row.rb +7 -7
- data/lib/formotion/row_type/options_row.rb +18 -8
- data/lib/formotion/row_type/slider_row.rb +14 -5
- data/lib/formotion/row_type/string_row.rb +17 -5
- data/lib/formotion/row_type/subform_row.rb +16 -0
- data/lib/formotion/row_type/submit_row.rb +1 -24
- data/lib/formotion/row_type/switch_row.rb +10 -2
- data/lib/formotion/row_type/template_row.rb +77 -0
- data/lib/formotion/row_type/text_row.rb +12 -4
- data/lib/formotion/section/section.rb +9 -1
- data/lib/formotion/version.rb +1 -1
- data/spec/form_spec.rb +24 -0
- data/spec/formable_spec.rb +100 -0
- data/spec/functional/formable_controller_spec.rb +47 -0
- data/spec/functional/image_row_spec.rb +2 -2
- data/spec/functional/subform_row.rb +33 -0
- data/spec/functional/template_row_spec.rb +57 -0
- data/spec/helpers/row_test_helpers.rb +26 -0
- data/spec/row_type/back_spec.rb +31 -0
- data/spec/row_type/check_spec.rb +9 -9
- data/spec/row_type/date_spec.rb +3 -10
- data/spec/row_type/email_spec.rb +1 -9
- data/spec/row_type/image_spec.rb +3 -12
- data/spec/row_type/number_spec.rb +1 -9
- data/spec/row_type/options_spec.rb +18 -10
- data/spec/row_type/phone_spec.rb +1 -9
- data/spec/row_type/picker_spec.rb +2 -11
- data/spec/row_type/slider_spec.rb +11 -10
- data/spec/row_type/static_spec.rb +1 -9
- data/spec/row_type/string_spec.rb +13 -9
- data/spec/row_type/subform_spec.rb +47 -0
- data/spec/row_type/submit_spec.rb +1 -9
- data/spec/row_type/switch_spec.rb +9 -9
- data/spec/row_type/template_spec.rb +14 -0
- data/spec/row_type/text_spec.rb +9 -9
- metadata +58 -6
@@ -0,0 +1,47 @@
|
|
1
|
+
class TestModel
|
2
|
+
include Formotion::Formable
|
3
|
+
|
4
|
+
attr_accessor :my_name, :my_number
|
5
|
+
|
6
|
+
form_property :my_name, :string, title: "My Name"
|
7
|
+
form_property :my_number, :number, title: "My Number", :transform => lambda { |value| value.to_i + 10 }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "FormableController" do
|
11
|
+
tests Formotion::FormableController
|
12
|
+
|
13
|
+
def controller
|
14
|
+
@model ||= TestModel.new
|
15
|
+
|
16
|
+
@controller ||= Formotion::FormableController.alloc.initWithModel(@model)
|
17
|
+
end
|
18
|
+
|
19
|
+
def string_row
|
20
|
+
@controller.form.sections.first.rows.first
|
21
|
+
end
|
22
|
+
|
23
|
+
def number_row
|
24
|
+
@controller.form.sections.first.rows.last
|
25
|
+
end
|
26
|
+
|
27
|
+
after do
|
28
|
+
(@active_row || string_row).text_field.resignFirstResponder
|
29
|
+
wait 1 do
|
30
|
+
@active_row = nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should have new my_value after typing" do
|
35
|
+
@active_row = string_row
|
36
|
+
tap("My Name")
|
37
|
+
string_row.text_field.setText("Hello")
|
38
|
+
@model.my_name.should == "Hello"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have new my_number after typing" do
|
42
|
+
@active_row = number_row
|
43
|
+
tap("My Number")
|
44
|
+
number_row.text_field.setText("10")
|
45
|
+
@model.my_number.should == 20
|
46
|
+
end
|
47
|
+
end
|
@@ -70,13 +70,13 @@ describe "FormController/ImageRow" do
|
|
70
70
|
it "should be able to delete value" do
|
71
71
|
image = UIImage.alloc.init
|
72
72
|
image_row.value = image
|
73
|
-
image_row.
|
73
|
+
image_row.row_height.should > 44
|
74
74
|
|
75
75
|
tap("Photo")
|
76
76
|
|
77
77
|
# Looks like view(label) doesn't scan the UIActionSheet properly, so we override it.
|
78
78
|
tap_action_sheet("Delete")
|
79
|
-
image_row.
|
79
|
+
image_row.row_height.should == 44
|
80
80
|
image_row.value.should == nil
|
81
81
|
end
|
82
82
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
describe "FormController/SubformRow" 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: "Goto",
|
9
|
+
type: :subform,
|
10
|
+
subform: {
|
11
|
+
title: 'Subform',
|
12
|
+
sections: [{
|
13
|
+
rows: [{
|
14
|
+
title: 'Mordor',
|
15
|
+
type: :static,
|
16
|
+
}]
|
17
|
+
}]
|
18
|
+
}
|
19
|
+
}
|
20
|
+
@form ||= Formotion::Form.new(
|
21
|
+
sections: [{
|
22
|
+
rows:[row_settings]
|
23
|
+
}])
|
24
|
+
|
25
|
+
@controller ||= Formotion::FormController.alloc.initWithForm(@form)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should goto subform when tapped" do
|
29
|
+
tap("Goto")
|
30
|
+
controller.modalViewController.should != nil
|
31
|
+
window.viewByName('Mordor').should != nil
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
describe "FormController/TemplateRow" 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: "Add element",
|
9
|
+
key: :template,
|
10
|
+
type: :template,
|
11
|
+
value: ['Value'],
|
12
|
+
template: {
|
13
|
+
title: 'Element',
|
14
|
+
type: :string,
|
15
|
+
indented: true,
|
16
|
+
deletable: true
|
17
|
+
}
|
18
|
+
}
|
19
|
+
@form ||= Formotion::Form.new(
|
20
|
+
sections: [{
|
21
|
+
rows:[row_settings]
|
22
|
+
}])
|
23
|
+
|
24
|
+
@controller ||= Formotion::FormController.alloc.initWithForm(@form)
|
25
|
+
end
|
26
|
+
|
27
|
+
def new_row
|
28
|
+
@form.sections.first.rows[-2]
|
29
|
+
end
|
30
|
+
|
31
|
+
after do
|
32
|
+
@form = nil
|
33
|
+
@controller = nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should insert row" do
|
37
|
+
tap("Add element")
|
38
|
+
@form.sections.first.rows.size.should == 3
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should remove row" do
|
42
|
+
tap("Add element")
|
43
|
+
new_row.object.on_delete(nil, nil)
|
44
|
+
@form.sections.first.rows.size.should == 2
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should render values as array" do
|
48
|
+
|
49
|
+
tap("Add element")
|
50
|
+
new_row.value = 'Value 2'
|
51
|
+
|
52
|
+
tap("Add element")
|
53
|
+
new_row.value = 'Value 3'
|
54
|
+
|
55
|
+
@form.render[:template].should == ['Value', 'Value 2', 'Value 3']
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Bacon
|
2
|
+
class Context
|
3
|
+
# Sets up a new @row RowType object to be reset before every test.
|
4
|
+
#
|
5
|
+
# @param row_settings is a hash of row settings or a symbol
|
6
|
+
# corresponding to a row type
|
7
|
+
# @param block is optional; the @row object is passed if given.
|
8
|
+
#
|
9
|
+
# EX
|
10
|
+
# test_row :image
|
11
|
+
# => tests the RowType::ImageRow
|
12
|
+
# test_row title: "Title", key: "some key", type: :string
|
13
|
+
# => tests the RowType::StringRow
|
14
|
+
def tests_row(row_settings, &block)
|
15
|
+
if row_settings.is_a? Symbol
|
16
|
+
type = row_settings
|
17
|
+
row_settings = { type: type, key: type, title: type.capitalize.to_s }
|
18
|
+
end
|
19
|
+
before do
|
20
|
+
@row = Formotion::Row.new(row_settings)
|
21
|
+
@row.reuse_identifier = 'test'
|
22
|
+
block && block.call(@row)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
describe "Back Row" do
|
2
|
+
tests_row :back
|
3
|
+
|
4
|
+
it "should initialize with correct settings" do
|
5
|
+
@row.object.class.should == Formotion::RowType::BackRow
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should pop subform on select" do
|
9
|
+
form = FakeForm.new
|
10
|
+
@row.instance_variable_set("@section", form)
|
11
|
+
@row.object.on_select(nil, nil)
|
12
|
+
form.controller.pop_subform_called.should == true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class FakeForm
|
17
|
+
def form
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def controller
|
22
|
+
@controller ||= FakeControllerClass.new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class FakeControllerClass
|
27
|
+
attr_accessor :pop_subform_called
|
28
|
+
def pop_subform
|
29
|
+
self.pop_subform_called = true
|
30
|
+
end
|
31
|
+
end
|
data/spec/row_type/check_spec.rb
CHANGED
@@ -1,13 +1,5 @@
|
|
1
1
|
describe "Check Row" do
|
2
|
-
|
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
|
2
|
+
tests_row :check
|
11
3
|
|
12
4
|
it "should initialize with correct settings" do
|
13
5
|
@row.object.class.should == Formotion::RowType::CheckRow
|
@@ -24,4 +16,12 @@ describe "Check Row" do
|
|
24
16
|
cell = @row.make_cell
|
25
17
|
cell.accessoryType.should == UITableViewCellAccessoryCheckmark
|
26
18
|
end
|
19
|
+
|
20
|
+
it "should bind its accessory" do
|
21
|
+
@row.value = true
|
22
|
+
cell = @row.make_cell
|
23
|
+
|
24
|
+
@row.value = false
|
25
|
+
cell.accessoryType.should == UITableViewCellAccessoryNone
|
26
|
+
end
|
27
27
|
end
|
data/spec/row_type/date_spec.rb
CHANGED
@@ -2,16 +2,9 @@ MILLENIUM = 946684672
|
|
2
2
|
TIME_ZONE = NSTimeZone.timeZoneWithName "Europe/Paris"
|
3
3
|
|
4
4
|
describe "Date Row" do
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
5
|
+
tests_row :date do |row|
|
6
|
+
row.object.formatter.timeZone = TIME_ZONE
|
7
|
+
row.object.picker.timeZone = TIME_ZONE
|
15
8
|
end
|
16
9
|
|
17
10
|
it "should initialize with correct settings" do
|
data/spec/row_type/email_spec.rb
CHANGED
@@ -1,13 +1,5 @@
|
|
1
1
|
describe "Email Row" do
|
2
|
-
|
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
|
2
|
+
tests_row :email
|
11
3
|
|
12
4
|
it "should initialize with correct settings" do
|
13
5
|
@row.object.class.should == Formotion::RowType::EmailRow
|
data/spec/row_type/image_spec.rb
CHANGED
@@ -1,15 +1,6 @@
|
|
1
1
|
describe "Image Row" do
|
2
|
-
|
3
|
-
|
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
|
2
|
+
tests_row :image do |row|
|
3
|
+
row.instance_eval do
|
13
4
|
def form
|
14
5
|
@form ||= Object.new.tap do |o|
|
15
6
|
def o.reload_data
|
@@ -35,7 +26,7 @@ describe "Image Row" do
|
|
35
26
|
|
36
27
|
@row.value = UIImage.alloc.init
|
37
28
|
|
38
|
-
@row.
|
29
|
+
@row.row_height.should > 44
|
39
30
|
image_view = cell.viewWithTag(Formotion::RowType::ImageRow::IMAGE_VIEW_TAG)
|
40
31
|
image_view.image.nil?.should == false
|
41
32
|
cell.accessoryView.nil?.should == true
|
@@ -1,13 +1,5 @@
|
|
1
1
|
describe "Number Row" do
|
2
|
-
|
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
|
2
|
+
tests_row :number
|
11
3
|
|
12
4
|
it "should initialize with correct settings" do
|
13
5
|
@row.object.class.should == Formotion::RowType::NumberRow
|
@@ -1,14 +1,6 @@
|
|
1
1
|
describe "Options Row" do
|
2
|
-
|
3
|
-
|
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
|
2
|
+
tests_row title: "Options", key: :options, type: :options,
|
3
|
+
items: ["First", "Second"]
|
12
4
|
|
13
5
|
it "should initialize with correct settings" do
|
14
6
|
@row.object.class.should == Formotion::RowType::OptionsRow
|
@@ -34,4 +26,20 @@ describe "Options Row" do
|
|
34
26
|
cell.accessoryView.selectedSegmentIndex.should == 1
|
35
27
|
@row.value.should == 'Second'
|
36
28
|
end
|
29
|
+
|
30
|
+
it "should bind value to control" do
|
31
|
+
@row.value = 'Second'
|
32
|
+
cell = @row.make_cell
|
33
|
+
|
34
|
+
@row.value = "First"
|
35
|
+
cell.accessoryView.selectedSegmentIndex.should == 0
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should bind nil to no selected segment" do
|
39
|
+
@row.value = 'Second'
|
40
|
+
cell = @row.make_cell
|
41
|
+
|
42
|
+
@row.value = nil
|
43
|
+
cell.accessoryView.selectedSegmentIndex.should == UISegmentedControlNoSegment
|
44
|
+
end
|
37
45
|
end
|
data/spec/row_type/phone_spec.rb
CHANGED
@@ -1,13 +1,5 @@
|
|
1
1
|
describe "Phone Row" do
|
2
|
-
|
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
|
2
|
+
tests_row :phone
|
11
3
|
|
12
4
|
it "should initialize with correct settings" do
|
13
5
|
@row.object.class.should == Formotion::RowType::PhoneRow
|
@@ -1,15 +1,6 @@
|
|
1
1
|
describe "Picker Row" do
|
2
|
-
|
3
|
-
|
4
|
-
title: "Picker",
|
5
|
-
key: :picker,
|
6
|
-
type: :picker,
|
7
|
-
items: ["Ruby", "Motion"],
|
8
|
-
value: "Motion"
|
9
|
-
}
|
10
|
-
@row = Formotion::Row.new(row_settings)
|
11
|
-
@row.reuse_identifier = 'test'
|
12
|
-
end
|
2
|
+
tests_row title: "Picker", key: :picker, type: :picker,
|
3
|
+
items: ["Ruby", "Motion"], value: "Motion"
|
13
4
|
|
14
5
|
it "should initialize with correct settings" do
|
15
6
|
@row.object.class.should == Formotion::RowType::PickerRow
|
@@ -1,14 +1,6 @@
|
|
1
1
|
describe "Slider Row" do
|
2
|
-
|
3
|
-
|
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
|
2
|
+
tests_row title: "Slider", key: :slider, type: :slider,
|
3
|
+
range: (1..100)
|
12
4
|
|
13
5
|
it "should initialize with correct settings" do
|
14
6
|
@row.object.class.should == Formotion::RowType::SliderRow
|
@@ -28,6 +20,15 @@ describe "Slider Row" do
|
|
28
20
|
@row.value.should == 50
|
29
21
|
end
|
30
22
|
|
23
|
+
it "should bind to row value" do
|
24
|
+
@row.range = (50..100)
|
25
|
+
@row.value = 25
|
26
|
+
cell = @row.make_cell
|
27
|
+
|
28
|
+
@row.value = 75
|
29
|
+
cell.accessoryView.value.should == 75
|
30
|
+
end
|
31
|
+
|
31
32
|
# Range
|
32
33
|
it "should use default range" do
|
33
34
|
@row.range = nil
|
@@ -1,13 +1,5 @@
|
|
1
1
|
describe "Static Row" do
|
2
|
-
|
3
|
-
row_settings = {
|
4
|
-
title: "Static",
|
5
|
-
key: :static,
|
6
|
-
type: :static,
|
7
|
-
}
|
8
|
-
@row = Formotion::Row.new(row_settings)
|
9
|
-
@row.reuse_identifier = 'test'
|
10
|
-
end
|
2
|
+
tests_row :static
|
11
3
|
|
12
4
|
it "should initialize with correct settings" do
|
13
5
|
@row.object.class.should == Formotion::RowType::StaticRow
|