monkey_forms 0.0.15

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 ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ bin
6
+ *.rbc
data/BUGS ADDED
@@ -0,0 +1 @@
1
+ - Forms that inherit from other forms don't seem have their form_name set correctly (according to Rails, anyways).
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "deep_merge",
4
+ '0',
5
+ :git => "git://github.com/joevandyk/deep_merge.git",
6
+ :ref => "a244fdd2d3a633743b054857b43f1ee4cacad9ff"
7
+
8
+ # Specify your gem's dependencies in monkey_forms.gemspec
9
+ gemspec
data/NOTES ADDED
@@ -0,0 +1,4 @@
1
+ ActiveModel::Validator seems to depend on
2
+ ActiveSupport::Callbacks?
3
+ Got undefined method `extlib_inheritable_reader'
4
+ when I included ActiveModel into a class.
data/README.md ADDED
@@ -0,0 +1,154 @@
1
+ NOTE! If you use the cookie serialization feature, you
2
+ need to use this version of deep_merge for now.
3
+ https://github.com/joevandyk/deep_merge
4
+
5
+
6
+ MonkeyForms::Form is an ActiveModel-compliant interface
7
+ between your controllers and models (or whatever you are
8
+ saving the data to).
9
+
10
+ MonkeyForms supports multi-page wizards and validation groups.
11
+
12
+ class OrderForm
13
+ include MonkeyForms::Form
14
+ form_name 'cart'
15
+ form_attributes :name, :address, :city, :state, :zip
16
+
17
+ validates :name, :presence => true
18
+
19
+ # Save the data however you want.
20
+ def save
21
+ address = Address.new(:street => address, :city => city, :state => state, :zip => zip)
22
+ OrderService.place_order(:the_name => name, :address => address)
23
+ end
24
+ end
25
+
26
+
27
+ In your controller:
28
+ def new
29
+ @cart = OrderForm.new
30
+ end
31
+ def create
32
+ @cart = OrderForm.new(:form => params[:cart])
33
+ if @cart.valid?
34
+ @cart.save
35
+ redirect_to "/thanks"
36
+ else
37
+ render :action => 'new'
38
+ end
39
+ end
40
+ end
41
+
42
+ In your view:
43
+ = form_for @cart do |f|
44
+ = f.text_field :name
45
+ = f.text_field :address
46
+ = f.text_field :city
47
+ = # etc
48
+ = f.submit
49
+
50
+
51
+ A more complex multi-page order process.
52
+ State is remembered in a cookie; the form params are merged into the cookie's state on each request.
53
+
54
+ class OrderForm
55
+ include MonkeyForms::Form
56
+
57
+ # Declares a few attributes on the form.
58
+ form_attributes :name, :email, :city, :state, :line_items
59
+ custom_attributes :user_id
60
+ form_name :cart
61
+
62
+ # This form serializes the submit into a gzip'd cookie with a name
63
+ # of 'order_cookie'.
64
+ set_form_storage(
65
+ MonkeyForms::Serializers::GzipCookie.new(
66
+ :name => 'order_cookie',
67
+ :domain => 'test.domain.com',
68
+ :secure => true,
69
+ :httponly => true))
70
+
71
+ after_initialize :set_default_state
72
+
73
+ # We must submit an email address for the form to validate.
74
+ validates :email, :presence => true
75
+
76
+ validation_group :cart do
77
+ # Scope some of the validation checks
78
+ validates :name, :presence => true
79
+ end
80
+
81
+ validation_group :address do
82
+ validates :city, :presence => true
83
+ validates :state, :presence => true
84
+ end
85
+
86
+ # This is a method that uses some form attributes.
87
+ def person
88
+ "#{ name } <#{ email }>"
89
+ end
90
+
91
+ private
92
+
93
+ def set_default_state
94
+ if state.blank?
95
+ self.state = "WA"
96
+ end
97
+ end
98
+ end
99
+
100
+
101
+ class Controller
102
+ before_filter :load_cart
103
+ # Name / Email
104
+ def page1
105
+ if request.post?
106
+ if group.valid?(:name)
107
+ redirect_to "/page2"
108
+ end
109
+ end
110
+ end
111
+
112
+ # Address
113
+ def page2
114
+ if request.post?
115
+ if group.valid?(:address)
116
+ # whatever..
117
+ end
118
+ end
119
+ end
120
+
121
+ private
122
+
123
+ def load_cart
124
+ @cart = OrderForm::Form.new(:form => params[:cart]
125
+ end
126
+ end
127
+
128
+
129
+ The validation_group code is modified from
130
+ https://github.com/adzap/grouped_validations
131
+
132
+
133
+ This is pretty similar to the Presenter Pattern as described
134
+ by Jay Fields, by the way. http://blog.jayfields.com/2007/03/rails-presenter-pattern.html
135
+
136
+
137
+
138
+ There is a sample sinatra application in test/sinatra. Run with:
139
+ cd test/sinatra
140
+ rackup config.ru
141
+
142
+
143
+
144
+ ??? WHY ???
145
+
146
+ Moving the form logic to a separate class has a ton of advantages:
147
+
148
+ * Keeps the controller really simple.
149
+ * Makes it easier to test. You can write tests directly against the form handling class.
150
+ * Classes should do one thing.
151
+ * You can have complex validations.
152
+ * Your ActiveRecord models can probably become simpler.
153
+ * Since the form handling logic is encapsulated into one class, you can use inheritance, modules, etc.
154
+ * You want to move away from ActiveRecord? It's no problem -- just change how the form values are saved in the #save method.
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'bundler/setup'
5
+
6
+ Bundler::GemHelper.install_tasks
7
+
8
+ Rake::TestTask.new(:test) do |test|
9
+ test.libs << 'lib' << 'test'
10
+ test.pattern = 'test/**/test_*.rb'
11
+ end
12
+
13
+ task :default => :test
@@ -0,0 +1,12 @@
1
+ # Saves form as cookie as json+gzip
2
+ class MonkeyForms::Serializers::ActiveRecordSesssion
3
+ def initialize options={}
4
+ @cookie_name = options[:name]
5
+ end
6
+
7
+ def load options={}
8
+ end
9
+
10
+ def save options = {}
11
+ end
12
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: UTF-8
2
+ require 'zlib'
3
+
4
+ # Saves form as cookie as json+gzip
5
+ class MonkeyForms::Serializers::GzipCookie
6
+ def initialize options={}
7
+ @cookie_name = options[:name]
8
+ @domain = options[:domain]
9
+ @secure = options[:secure]
10
+ @httponly = options[:httponly]
11
+ end
12
+
13
+ def load options={}
14
+ request = options[:request]
15
+ result = ActiveSupport::HashWithIndifferentAccess.new
16
+ return result if request.blank?
17
+ cookie = request.cookies[@cookie_name]
18
+ return result if cookie.nil? or cookie.empty?
19
+ result.merge!(ActiveSupport::JSON.decode(Zlib::Inflate.inflate(cookie)).stringify_keys)
20
+ end
21
+
22
+ def save options = {}
23
+ attributes = options[:attributes]
24
+ response = options[:response]
25
+
26
+ cookie_json = ActiveSupport::JSON.encode(attributes)
27
+ cookie_json = Zlib::Deflate.deflate(cookie_json, Zlib::BEST_COMPRESSION)
28
+ cookie_hash = { :value => cookie_json,
29
+ :httponly => @httponly,
30
+ :secure => @secure,
31
+ :domain => @domain }
32
+ response.set_cookie(@cookie_name, cookie_hash)
33
+ end
34
+ end
@@ -0,0 +1,32 @@
1
+ require 'msgpack'
2
+
3
+ # Saves form as cookie as json+gzip
4
+ class MonkeyForms::Serializers::MessagePackJson
5
+ def initialize options={}
6
+ @cookie_name = options[:name]
7
+ @domain = options[:domain]
8
+ @secure = options[:secure]
9
+ @httponly = options[:httponly]
10
+ end
11
+
12
+ def load options={}
13
+ request = options[:request]
14
+ result = ActiveSupport::HashWithIndifferentAccess.new
15
+ return result if request.blank?
16
+ cookie = request.cookies[@cookie_name]
17
+ return result if cookie.blank?
18
+ result.merge!(ActiveSupport::JSON.decode(MessagePack.unpack(cookie)).stringify_keys)
19
+ end
20
+
21
+ def save options = {}
22
+ attributes = options[:attributes]
23
+ response = options[:response]
24
+
25
+ cookie_json = ActiveSupport::JSON.encode(attributes).to_msgpack
26
+ cookie_hash = { :value => cookie_json,
27
+ :httponly => @httponly,
28
+ :secure => @secure,
29
+ :domain => @domain }
30
+ response.set_cookie(@cookie_name, cookie_hash)
31
+ end
32
+ end
@@ -0,0 +1,7 @@
1
+
2
+ module MonkeyForms
3
+ module Serializers
4
+ autoload :GzipCookie, 'monkey_forms/serializers/gzip_cookie'
5
+ autoload :MessagePackJson, 'monkey_forms/serializers/message_pack_json'
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module MonkeyForms
2
+ VERSION = "0.0.15"
3
+ end
@@ -0,0 +1,146 @@
1
+ module MonkeyForms
2
+ require 'monkey_forms/serializers'
3
+ require 'active_model'
4
+ require 'active_support/hash_with_indifferent_access'
5
+ require 'active_support/core_ext/object/try'
6
+ require 'grouped_validations'
7
+ require 'deep_merge'
8
+
9
+ module Form
10
+
11
+ def self.included base
12
+ base.send :include, ActiveModel::Validations
13
+ base.send :extend, ActiveModel::Callbacks
14
+ base.send :include, InstanceMethods
15
+ base.send :extend, ClassMethods
16
+ base.instance_eval do
17
+ define_model_callbacks :initialize
18
+ end
19
+ base.send :include, ActiveModel::Validations
20
+ end
21
+
22
+ module InstanceMethods
23
+ attr_reader :attributes
24
+
25
+ def persisted?
26
+ false
27
+ end
28
+
29
+ # TODO not sure what's best here
30
+ def html_error_messages
31
+ errors.full_messages.join("<br />")
32
+ end
33
+
34
+ def to_model
35
+ self
36
+ end
37
+
38
+ def to_param
39
+ nil
40
+ end
41
+
42
+ def to_key
43
+ nil
44
+ end
45
+
46
+ def initialize options = {}
47
+ _run_initialize_callbacks do
48
+ form_params = options.delete(:form) || {}
49
+ @options = options
50
+
51
+ @options.each do |key, value|
52
+ instance_variable_set "@#{key}", value
53
+ end
54
+
55
+ # Load the saved form from storage
56
+ @attributes =
57
+ if self.class.form_storage
58
+ self.class.form_storage.load(@options)
59
+ else
60
+ ActiveSupport::HashWithIndifferentAccess.new
61
+ end
62
+
63
+ # Merge in this form's params
64
+ DeepMerge.deep_merge!(form_params, @attributes)
65
+
66
+ self.class.attributes.each do |a|
67
+ @attributes[a] ||= ""
68
+ end
69
+ end
70
+ end
71
+
72
+ def save_to_storage!
73
+ @options[:attributes] = @attributes
74
+ self.class.form_storage.save(@options)
75
+ end
76
+
77
+ end
78
+
79
+ module ClassMethods
80
+ attr_reader :form_storage
81
+
82
+ def attributes
83
+ @attributes ||= {}
84
+ end
85
+
86
+ # Compatibility with ActiveModel::Naming
87
+ def model_name
88
+ if !defined?(@_model_name)
89
+ # EWWWW
90
+ @_model_name = (@_form_name.try(:to_s) ||
91
+ superclass.instance_variable_get(:@_form_name).try(:to_s) ||
92
+ name.underscore).try(:underscore)
93
+ %w( singular human i18n_key partial_path plural ).each do |method|
94
+ @_model_name.class_eval do
95
+ define_method method do
96
+ self
97
+ end
98
+ end
99
+ end
100
+ end
101
+ @_model_name
102
+ end
103
+
104
+ def form_name name
105
+ @_form_name = name
106
+ end
107
+
108
+ def set_form_storage storage_object
109
+ @form_storage = storage_object
110
+ end
111
+
112
+ def set_form_attribute_human_names options
113
+ @_form_attribute_names ||= {}
114
+ @_form_attribute_names.merge!(options)
115
+ end
116
+
117
+ def human_attribute_name name, *options
118
+ @_form_attribute_names ||= {}
119
+ @_form_attribute_names[name] || super
120
+ end
121
+
122
+ def form_attributes *attrs
123
+ @attributes ||= []
124
+ attrs.each do |attr|
125
+ @attributes << attr
126
+
127
+ # Defines public method
128
+ define_method attr do
129
+ @attributes[attr.to_s]
130
+ end
131
+ define_method "#{attr}=" do |value|
132
+ @attributes[attr.to_s] = value
133
+ end
134
+ end
135
+ end
136
+
137
+ def custom_attributes *attrs
138
+ attrs.each do |attr|
139
+ instance_eval do
140
+ attr_reader attr
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "monkey_forms/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "monkey_forms"
7
+ s.version = MonkeyForms::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Joe Van Dyk"]
10
+ s.email = ["joe@tanga.com"]
11
+ s.homepage = "https://github.com/joevandyk/monkey_forms"
12
+ s.summary = %q{Helps make complex forms}
13
+ s.description = %q{Helps make complex forms}
14
+ s.rubyforge_project = "monkey_forms"
15
+
16
+ s.add_dependency('activemodel')
17
+ s.add_dependency('deep_merge')
18
+
19
+ s.add_development_dependency 'minitest'
20
+ s.add_development_dependency 'rake'
21
+ s.add_development_dependency 'sinatra'
22
+ s.add_development_dependency 'rack-test'
23
+ s.add_development_dependency 'shotgun'
24
+ s.add_development_dependency 'haml'
25
+ s.add_development_dependency('msgpack')
26
+
27
+ s.files = `git ls-files`.split("\n")
28
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
29
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
30
+ s.require_paths = ["lib"]
31
+ end
@@ -0,0 +1,8 @@
1
+ require 'monkey_forms'
2
+
3
+ class BasicForm
4
+ include MonkeyForms::Form
5
+ form_attributes :name
6
+ validates :name, :presence => true
7
+ end
8
+
@@ -0,0 +1,54 @@
1
+ require 'monkey_forms'
2
+
3
+ class OrderForm
4
+ include MonkeyForms::Form
5
+ attr_reader :an_attribute
6
+
7
+ # Declares a few attributes on the form.
8
+ form_attributes :name, :email, :city, :state, :line_items
9
+ custom_attributes :user_id
10
+ form_name :cart
11
+
12
+ # This form serializes the submit into a gzip'd cookie with a name
13
+ # of 'order_cookie'.
14
+ set_form_storage(
15
+ MonkeyForms::Serializers::GzipCookie.new(
16
+ :name => 'order_cookie',
17
+ :domain => 'test.domain.com',
18
+ :secure => true,
19
+ :httponly => true))
20
+
21
+ after_initialize :set_attribute, :set_default_state
22
+
23
+ # We must submit an email address for the form to validate.
24
+ validates :email, :presence => true
25
+
26
+ set_form_attribute_human_names :name => "Your Name"
27
+
28
+ validation_group :cart do
29
+ # Scope some of the validation checks
30
+ validates :name, :presence => true
31
+ end
32
+
33
+ validation_group :address do
34
+ validates :city, :presence => true
35
+ validates :state, :presence => true
36
+ end
37
+
38
+ # This is a method that uses some form attributes.
39
+ def person
40
+ "#{ name } <#{ email }>"
41
+ end
42
+
43
+ private
44
+
45
+ def set_attribute
46
+ @an_attribute = true
47
+ end
48
+
49
+ def set_default_state
50
+ if state.blank?
51
+ self.state = "WA"
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,4 @@
1
+ require 'monkey_forms'
2
+ class OrderFormChild < OrderForm
3
+ form_attributes :child
4
+ end
@@ -0,0 +1,5 @@
1
+ require 'bundler'
2
+ require 'bundler/setup'
3
+
4
+ require 'sample_sinatra'
5
+ run SampleSinatra
@@ -0,0 +1,50 @@
1
+ require 'sinatra/base'
2
+ require 'forms/order_form'
3
+
4
+ class SampleSinatra < Sinatra::Base
5
+ #set :show_exceptions, false
6
+
7
+ before do
8
+ load_form
9
+ end
10
+
11
+ get "/" do
12
+ @page = 1
13
+ haml :form
14
+ end
15
+
16
+ get "/2" do
17
+ @page = 2
18
+ haml :form
19
+ end
20
+
21
+ get "/3" do
22
+ @page = 3
23
+ haml :form
24
+ end
25
+
26
+ post "/haml_form" do
27
+ # We could probably do something with the form object here, maybe
28
+ # Tells the form to serialize itself.
29
+ @form.save_to_storage!
30
+ redirect "/"
31
+ end
32
+
33
+ # Only used in unit tests
34
+ post "/form" do
35
+ # Tells the form to serialize itself.
36
+ @form.save_to_storage!
37
+
38
+ # Renders something (used in tests)
39
+ @form.person
40
+ end
41
+
42
+ private
43
+
44
+ def load_form
45
+ @form = OrderForm.new(:form => request.params["form"],
46
+ :request => request,
47
+ :response => response)
48
+ end
49
+ end
50
+
@@ -0,0 +1,25 @@
1
+ %h1 Welcome to Monkey Forms Page #{ @page }
2
+
3
+ %h3
4
+ %a{:href => "/"} Page 1
5
+ |
6
+ %a{:href => "/2"} Page 2
7
+ |
8
+ %a{:href => "/3"} Page 3
9
+
10
+ %h3 Form Values
11
+ = @form.attributes.inspect
12
+
13
+ %p
14
+ As you click from page to page, note that your form
15
+ values are saved. They are saved in a cookie!
16
+
17
+ %form{:action => '/haml_form', :method => 'post'}
18
+ - @form.class.attributes.each do |name|
19
+ %input{:type => 'text', :id => "form_#{name}", :name => "form[#{name}]", :value => @form.send(name)}
20
+ %label{:for => "form_#{name}"}= name
21
+
22
+ %br
23
+
24
+ %input{:type => 'submit'}
25
+
@@ -0,0 +1,182 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/pride'
3
+ require 'rack/test'
4
+
5
+ require 'sinatra/sample_sinatra'
6
+ require 'forms/order_form'
7
+ require 'forms/order_form_child'
8
+ require 'forms/basic_form'
9
+
10
+ # I want to ensure this library works fine with all of ActiveSupport loaded
11
+ require 'active_support/all'
12
+
13
+ class TestMonkeyForms < MiniTest::Unit::TestCase
14
+ include Rack::Test::Methods
15
+
16
+ def app
17
+ SampleSinatra.new
18
+ end
19
+
20
+ def test_form_post_with_cookie
21
+ post "https://test.domain.com/form", :form => { :name => "Joe" }
22
+ assert_equal "Joe <>", last_response.body
23
+ post "https://test.domain.com/form", :form => { :email => "joe@tanga.com" }
24
+ assert_equal "Joe <joe@tanga.com>", last_response.body
25
+ end
26
+
27
+ def test_attribute_name
28
+ o = OrderForm.new
29
+ o.valid?
30
+ assert o.errors.full_messages.include?("Your Name can't be blank")
31
+ end
32
+
33
+ def test_form_works_without_human_names_set
34
+ o = BasicForm.new
35
+ o.valid?
36
+ assert o.errors.full_messages.include?("Name can't be blank")
37
+ end
38
+
39
+ def test_form_cookie
40
+ submit_form :name => "joe"
41
+ # TODO figure out how to get test the cookie stuff properly
42
+ assert last_response.headers["Set-Cookie"].include?("HttpOnly")
43
+ assert last_response.headers["Set-Cookie"].include?("secure")
44
+ assert last_response.headers["Set-Cookie"].include?("test.domain.com")
45
+ end
46
+
47
+ def test_setters_from_inside_form
48
+ a = submit_form :name => 'joe'
49
+ assert_equal 'WA', a[:state]
50
+ end
51
+
52
+ def test_child_form
53
+ o = OrderFormChild.new :form => { :child => 'new', :name => 'joe' }
54
+ assert_equal 'new', o.child
55
+ assert_equal 'joe', o.name
56
+
57
+ assert_equal 'cart', o.class.model_name
58
+ end
59
+
60
+ def test_basic
61
+ o = OrderForm.new :form => { :name => "Joe", :email => "joe@tanga.com" }
62
+ assert_equal "Joe", o.name
63
+ assert_equal "joe@tanga.com", o.email
64
+ assert_equal "", o.city
65
+ assert_equal 5, o.attributes.size
66
+ assert_equal "Joe", o.attributes[:name]
67
+ assert_equal "Joe", o.attributes["name"]
68
+ end
69
+
70
+ def test_validation
71
+ o = OrderForm.new :form => { :name => "Joe" }
72
+ o.valid?
73
+ assert_equal ["can't be blank"], o.errors[:email]
74
+ end
75
+
76
+ def test_validation_before_valid_called
77
+ o = OrderForm.new
78
+ assert_equal [], o.errors[:name]
79
+ assert_equal [], o.errors[:email]
80
+ end
81
+
82
+ def test_html_errors
83
+ o = OrderForm.new
84
+ o.valid?
85
+ assert o.html_error_messages.include?("City can't be blank")
86
+ end
87
+
88
+ def test_validation_scope_after_valid_called
89
+ o = OrderForm.new
90
+ refute o.valid?
91
+ assert ["can't be blank"], o.errors[:name]
92
+ assert ["can't be blank"], o.errors[:email]
93
+ end
94
+
95
+ def test_group_validation
96
+ o = OrderForm.new
97
+ refute o.group_valid?(:cart)
98
+ assert_equal ["can't be blank"], o.errors[:name]
99
+ assert_equal [], o.errors[:email]
100
+
101
+ o.valid?
102
+ assert_equal ["can't be blank"], o.errors[:email]
103
+ end
104
+
105
+ def test_after_initialize
106
+ o = OrderForm.new
107
+ assert o.an_attribute
108
+ end
109
+
110
+ def test_set_custom_attributes
111
+ o = OrderForm.new :user_id => 1
112
+ assert_equal 1, o.user_id
113
+ end
114
+
115
+ def test_can_access_attributes
116
+ o = OrderForm.new :form => { :email => "joe@tanga.com" , :name => "Joe" }
117
+ assert_equal "Joe <joe@tanga.com>", o.person
118
+ end
119
+
120
+ def test_array
121
+ submit_form(:line_items => [ {:id => "previous"}])
122
+ attributes = submit_form(:line_items => [ {:id => "new"}])
123
+
124
+ assert_equal 2, attributes[:line_items].size
125
+ assert_equal "previous", attributes[:line_items].first[:id]
126
+ assert_equal "new", attributes[:line_items].last[:id]
127
+ end
128
+
129
+ def test_array_update
130
+ submit_form(:line_items => [ {:id => "first", :quantity => 1}])
131
+ attributes = submit_form(:line_items => [ {:id => "first", :quantity => 3}])
132
+ assert_equal "3", attributes[:line_items].last[:quantity]
133
+ end
134
+
135
+ def test_submit_blank
136
+ a = submit_form(:name => "Joe", :city => "Seattle")
137
+ assert_equal "Joe", a[:name]
138
+
139
+ a = submit_form(:name => "", :city => "Seattle")
140
+ assert_equal "", a[:name]
141
+ end
142
+
143
+
144
+ def extract_attributes request
145
+ serializer = MonkeyForms::Serializers::GzipCookie.new(:name => "order_cookie")
146
+ serializer.load(:request => request)
147
+ end
148
+
149
+ def submit_form attributes
150
+ post "https://test.domain.com/form", :form => attributes
151
+ post "https://test.domain.com/form", :form => {} # not sure why the cookies don't get set in last_request without this
152
+ extract_attributes last_request
153
+ end
154
+ end
155
+
156
+ class TestMonkeyFormsActiveModelLint < MiniTest::Unit::TestCase
157
+ include ActiveModel::Lint::Tests
158
+
159
+ def setup
160
+ @model = OrderForm.new
161
+ end
162
+
163
+ def test_form_name
164
+ assert_equal "cart", @model.class.model_name
165
+ end
166
+ end
167
+
168
+ class TestMonkeyFormsBasic < MiniTest::Unit::TestCase
169
+ include ActiveModel::Lint::Tests
170
+
171
+ def setup
172
+ @model = BasicForm.new
173
+ end
174
+
175
+ def test_form_name
176
+ assert_equal "basic_form", @model.class.model_name
177
+ end
178
+
179
+ def test_attributes
180
+ assert_equal @model.attributes, {"name" => ""}
181
+ end
182
+ end
metadata ADDED
@@ -0,0 +1,179 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: monkey_forms
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.15
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Joe Van Dyk
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-07-03 00:00:00.000000000 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activemodel
17
+ requirement: &2165026280 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2165026280
26
+ - !ruby/object:Gem::Dependency
27
+ name: deep_merge
28
+ requirement: &2165025680 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *2165025680
37
+ - !ruby/object:Gem::Dependency
38
+ name: minitest
39
+ requirement: &2165025120 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *2165025120
48
+ - !ruby/object:Gem::Dependency
49
+ name: rake
50
+ requirement: &2165024680 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *2165024680
59
+ - !ruby/object:Gem::Dependency
60
+ name: sinatra
61
+ requirement: &2165024140 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *2165024140
70
+ - !ruby/object:Gem::Dependency
71
+ name: rack-test
72
+ requirement: &2165023560 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: *2165023560
81
+ - !ruby/object:Gem::Dependency
82
+ name: shotgun
83
+ requirement: &2165022960 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: *2165022960
92
+ - !ruby/object:Gem::Dependency
93
+ name: haml
94
+ requirement: &2162564820 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ type: :development
101
+ prerelease: false
102
+ version_requirements: *2162564820
103
+ - !ruby/object:Gem::Dependency
104
+ name: msgpack
105
+ requirement: &2162564280 !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: *2162564280
114
+ description: Helps make complex forms
115
+ email:
116
+ - joe@tanga.com
117
+ executables: []
118
+ extensions: []
119
+ extra_rdoc_files: []
120
+ files:
121
+ - .gitignore
122
+ - BUGS
123
+ - Gemfile
124
+ - NOTES
125
+ - README.md
126
+ - Rakefile
127
+ - lib/monkey_forms.rb
128
+ - lib/monkey_forms/serializers.rb
129
+ - lib/monkey_forms/serializers/active_record_session.rb
130
+ - lib/monkey_forms/serializers/gzip_cookie.rb
131
+ - lib/monkey_forms/serializers/message_pack_json.rb
132
+ - lib/monkey_forms/version.rb
133
+ - monkey_forms.gemspec
134
+ - test/forms/basic_form.rb
135
+ - test/forms/order_form.rb
136
+ - test/forms/order_form_child.rb
137
+ - test/sinatra/config.ru
138
+ - test/sinatra/sample_sinatra.rb
139
+ - test/sinatra/views/form.haml
140
+ - test/test_monkey_forms.rb
141
+ has_rdoc: true
142
+ homepage: https://github.com/joevandyk/monkey_forms
143
+ licenses: []
144
+ post_install_message:
145
+ rdoc_options: []
146
+ require_paths:
147
+ - lib
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ segments:
155
+ - 0
156
+ hash: -2757128949908824304
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ none: false
159
+ requirements:
160
+ - - ! '>='
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ segments:
164
+ - 0
165
+ hash: -2757128949908824304
166
+ requirements: []
167
+ rubyforge_project: monkey_forms
168
+ rubygems_version: 1.6.2
169
+ signing_key:
170
+ specification_version: 3
171
+ summary: Helps make complex forms
172
+ test_files:
173
+ - test/forms/basic_form.rb
174
+ - test/forms/order_form.rb
175
+ - test/forms/order_form_child.rb
176
+ - test/sinatra/config.ru
177
+ - test/sinatra/sample_sinatra.rb
178
+ - test/sinatra/views/form.haml
179
+ - test/test_monkey_forms.rb