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.
Files changed (69) hide show
  1. data/.gitignore +2 -1
  2. data/CHANGELOG.md +10 -0
  3. data/Gemfile +6 -0
  4. data/LIST_OF_ROW_TYPES.md +163 -0
  5. data/NEW_ROW_TYPES.md +73 -0
  6. data/README.md +11 -14
  7. data/Rakefile +6 -0
  8. data/app/app_delegate.rb +22 -0
  9. data/examples/KitchenSink/Rakefile +1 -1
  10. data/examples/KitchenSink/app/app_delegate.rb +50 -2
  11. data/examples/Login/.gitignore +5 -0
  12. data/examples/Login/Rakefile +9 -0
  13. data/examples/Login/app/app_delegate.rb +16 -0
  14. data/examples/Login/app/login_controller.rb +47 -0
  15. data/examples/Login/app/user_controller.rb +38 -0
  16. data/examples/Login/spec/main_spec.rb +9 -0
  17. data/lib/formotion.rb +7 -1
  18. data/lib/formotion/{form.rb → form/form.rb} +0 -0
  19. data/lib/formotion/{form_delegate.rb → form/form_delegate.rb} +10 -15
  20. data/lib/formotion/patch/object.rb +9 -0
  21. data/lib/formotion/patch/ui_action_sheet.rb +27 -0
  22. data/lib/formotion/patch/ui_text_view.rb +122 -0
  23. data/lib/formotion/patch/ui_text_view_placeholder.rb +65 -0
  24. data/lib/formotion/{row.rb → row/row.rb} +37 -27
  25. data/lib/formotion/row/row_cell_builder.rb +28 -0
  26. data/lib/formotion/row_type/base.rb +41 -0
  27. data/lib/formotion/row_type/check_row.rb +30 -0
  28. data/lib/formotion/row_type/date_row.rb +61 -0
  29. data/lib/formotion/row_type/email_row.rb +11 -0
  30. data/lib/formotion/row_type/image_row.rb +99 -0
  31. data/lib/formotion/row_type/number_row.rb +11 -0
  32. data/lib/formotion/row_type/options_row.rb +24 -0
  33. data/lib/formotion/row_type/phone_row.rb +11 -0
  34. data/lib/formotion/row_type/row_type.rb +21 -0
  35. data/lib/formotion/row_type/slider_row.rb +43 -0
  36. data/lib/formotion/row_type/static_row.rb +6 -0
  37. data/lib/formotion/row_type/string_row.rb +112 -0
  38. data/lib/formotion/row_type/submit_row.rb +34 -0
  39. data/lib/formotion/row_type/switch_row.rb +19 -0
  40. data/lib/formotion/row_type/text_row.rb +76 -0
  41. data/lib/formotion/{section.rb → section/section.rb} +3 -0
  42. data/lib/formotion/version.rb +1 -1
  43. data/spec/form_spec.rb +5 -4
  44. data/spec/functional/character_spec.rb +70 -0
  45. data/spec/functional/check_row_spec.rb +42 -0
  46. data/spec/functional/date_row_spec.rb +63 -0
  47. data/spec/functional/image_row_spec.rb +82 -0
  48. data/spec/functional/options_row_spec.rb +27 -0
  49. data/spec/functional/slider_row_spec.rb +27 -0
  50. data/spec/functional/submit_row_spec.rb +30 -0
  51. data/spec/functional/switch_row_spec.rb +28 -0
  52. data/spec/functional/text_row_spec.rb +60 -0
  53. data/spec/row_type/check_spec.rb +27 -0
  54. data/spec/row_type/date_spec.rb +69 -0
  55. data/spec/row_type/email_spec.rb +22 -0
  56. data/spec/row_type/image_spec.rb +43 -0
  57. data/spec/row_type/number_spec.rb +22 -0
  58. data/spec/row_type/options_spec.rb +37 -0
  59. data/spec/row_type/phone_spec.rb +22 -0
  60. data/spec/row_type/slider_spec.rb +47 -0
  61. data/spec/row_type/static_spec.rb +15 -0
  62. data/spec/row_type/string_spec.rb +52 -0
  63. data/spec/row_type/submit_spec.rb +28 -0
  64. data/spec/row_type/switch_spec.rb +27 -0
  65. data/spec/row_type/text_spec.rb +41 -0
  66. data/spec/support/ui_control_wrap_extension.rb +7 -0
  67. metadata +88 -9
  68. data/lib/formotion/row_cell_builder.rb +0 -168
  69. 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