freeform 0.0.4 → 1.0.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/.gitignore +8 -17
- data/Gemfile +1 -1
- data/Gemfile.lock +150 -0
- data/MIT-LICENSE +20 -0
- data/README.md +31 -43
- data/Rakefile +32 -1
- data/freeform.gemspec +22 -15
- data/lib/freeform/builder/builder_mixin.rb +111 -0
- data/lib/freeform/builder/builders.rb +32 -0
- data/lib/freeform/builder/engine.rb +14 -0
- data/lib/freeform/builder/view_helper.rb +56 -0
- data/lib/freeform/form/form_input_key.rb +1 -1
- data/lib/freeform/form/nested.rb +17 -55
- data/lib/freeform/form/property.rb +82 -42
- data/lib/freeform/form/validation.rb +38 -11
- data/lib/freeform/form.rb +24 -27
- data/lib/freeform/version.rb +1 -1
- data/lib/freeform.rb +4 -0
- data/lib/generators/freeform/install_generator.rb +17 -0
- data/lib/tasks/freeform_tasks.rake +4 -0
- data/spec/acceptance_spec.rb +261 -155
- data/spec/builder/builder_spec.rb +215 -0
- data/spec/builder/view_helper_spec.rb +97 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +5 -0
- data/spec/dummy/app/assets/javascripts/jquery.js +9404 -0
- data/spec/dummy/app/assets/javascripts/jquery_events_test.js +19 -0
- data/spec/dummy/app/assets/javascripts/projects.js +2 -0
- data/spec/dummy/app/assets/javascripts/prototype.js +6082 -0
- data/spec/dummy/app/assets/javascripts/prototype_events_test.js +20 -0
- data/spec/dummy/app/assets/stylesheets/application.css +7 -0
- data/spec/dummy/app/assets/stylesheets/companies.css +4 -0
- data/spec/dummy/app/assets/stylesheets/projects.css +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/companies_controller.rb +5 -0
- data/spec/dummy/app/controllers/projects_controller.rb +11 -0
- data/spec/dummy/app/forms/milestone_form.rb +4 -0
- data/spec/dummy/app/forms/project_form.rb +11 -0
- data/spec/dummy/app/forms/task_form.rb +10 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/company.rb +5 -0
- data/spec/dummy/app/models/milestone.rb +6 -0
- data/spec/dummy/app/models/project.rb +9 -0
- data/spec/dummy/app/models/project_task.rb +3 -0
- data/spec/dummy/app/models/task.rb +7 -0
- data/spec/dummy/app/views/companies/new.html.erb +16 -0
- data/spec/dummy/app/views/layouts/application.html.erb +19 -0
- data/spec/dummy/app/views/projects/new.html.erb +13 -0
- data/spec/dummy/app/views/projects/without_intermediate_inputs.html.erb +11 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config/application.rb +35 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +13 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/migrate/20110710143903_initial_tables.rb +38 -0
- data/spec/dummy/db/schema.rb +43 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/log/development.log +0 -0
- data/spec/dummy/log/test.log +39736 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/cache/assets/C54/850/sprockets%2Fd484f47085686f151320ff7248bb5105 +0 -0
- data/spec/dummy/tmp/cache/assets/C76/160/sprockets%2F49c594d143212b346d11f1ecf9358103 +0 -0
- data/spec/dummy/tmp/cache/assets/C99/4D0/sprockets%2F5e30a6b911437f1428dc32c3ae182123 +0 -0
- data/spec/dummy/tmp/cache/assets/C99/7D0/sprockets%2F79513e6956e0ee8624976e041fd5636d +0 -0
- data/spec/dummy/tmp/cache/assets/CAA/C90/sprockets%2F1e6c8ee1258009385ccf5b84015424b3 +0 -0
- data/spec/dummy/tmp/cache/assets/CB2/CB0/sprockets%2F11cc8d161d71a716dd36f16849d90870 +0 -0
- data/spec/dummy/tmp/cache/assets/CB7/7F0/sprockets%2Fac97b043470f6fcc925c352f16956643 +0 -0
- data/spec/dummy/tmp/cache/assets/CBA/680/sprockets%2F912d84e091e5f2190b1ab7926de19679 +0 -0
- data/spec/dummy/tmp/cache/assets/CC7/430/sprockets%2F48e99a3e16ba3e65749e009d82546f94 +0 -0
- data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/CDB/8A0/sprockets%2Faed2a2575c376263c26e93b56b57051d +0 -0
- data/spec/dummy/tmp/cache/assets/CF1/E80/sprockets%2F7735295e1e3085f2e1dc29d59a45e8e6 +0 -0
- data/spec/dummy/tmp/cache/assets/D0F/E60/sprockets%2F1123d9a479fdf5c2b8415087e2a43ec6 +0 -0
- data/spec/dummy/tmp/cache/assets/D1F/A10/sprockets%2F60317e62cb324bfd9987e8da9636fd06 +0 -0
- data/spec/dummy/tmp/cache/assets/D25/E20/sprockets%2F29ba1a4a2b611731334f54abb9e5b5d1 +0 -0
- data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/D35/760/sprockets%2F49e26620c5c743ac4cdab7703f54db06 +0 -0
- data/spec/dummy/tmp/cache/assets/D49/870/sprockets%2F90896142645585acc8baf56ad57e3afb +0 -0
- data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/D62/F00/sprockets%2F6ac03a007f26b1c18ed3d53498ad3eb8 +0 -0
- data/spec/dummy/tmp/cache/assets/D79/BC0/sprockets%2F85a1db977361cc5130fcefb4637ff67e +0 -0
- data/spec/dummy/tmp/cache/assets/D87/1F0/sprockets%2F61c9ceafb877fb740c67416ff6f782a9 +0 -0
- data/spec/dummy/tmp/cache/assets/DA8/900/sprockets%2Fde7a2b3987b89b9d9afb268ce4204a4a +0 -0
- data/spec/dummy/tmp/cache/assets/DAD/4F0/sprockets%2F765acd1bf68dc90f7d3e61da78b1e659 +0 -0
- data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/E03/3F0/sprockets%2F82b37ae9eccec44c1ef44cfdd07d8534 +0 -0
- data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/E0A/CA0/sprockets%2F7fe72ac1c0db1a7e8e7f59cf25e8a39e +0 -0
- data/spec/dummy/tmp/cache/assets/E20/9B0/sprockets%2F2fa6cd86b1af7bda41f5b7921cdadf10 +0 -0
- data/spec/dummy/tmp/cache/assets/E3A/A60/sprockets%2F7c72c96cfc66454caf5fc8ca0fedd4f3 +0 -0
- data/spec/dummy/tmp/cache/assets/E54/400/sprockets%2Fd0cbc16cc37efcf9dc41f242b5dbbf81 +0 -0
- data/spec/dummy/tmp/cache/assets/EB7/AB0/sprockets%2F801d29a5debdbfbfb4eef14d70d9bcdb +0 -0
- data/spec/dummy/tmp/cache/assets/F48/5E0/sprockets%2F26cd6ffcffbebbe2fd6cd1a8f0c2debc +0 -0
- data/spec/form/nested_spec.rb +75 -61
- data/spec/form/property_spec.rb +167 -14
- data/spec/form/validation_spec.rb +46 -23
- data/spec/javascript_spec.rb +60 -0
- data/spec/persistence_spec.rb +608 -0
- data/spec/spec_helper.rb +18 -2
- data/vendor/assets/javascripts/jquery_freeform.js +120 -0
- data/vendor/assets/javascripts/jquery_nested_form.js +0 -0
- data/vendor/assets/javascripts/prototype_freeform.js +69 -0
- data/vendor/assets/javascripts/prototype_nested_form.js +0 -0
- metadata +341 -3
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
|
5
|
+
<style>
|
|
6
|
+
body {
|
|
7
|
+
background-color: #EFEFEF;
|
|
8
|
+
color: #2E2F30;
|
|
9
|
+
text-align: center;
|
|
10
|
+
font-family: arial, sans-serif;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
div.dialog {
|
|
14
|
+
width: 25em;
|
|
15
|
+
margin: 4em auto 0 auto;
|
|
16
|
+
border: 1px solid #CCC;
|
|
17
|
+
border-right-color: #999;
|
|
18
|
+
border-left-color: #999;
|
|
19
|
+
border-bottom-color: #BBB;
|
|
20
|
+
border-top: #B00100 solid 4px;
|
|
21
|
+
border-top-left-radius: 9px;
|
|
22
|
+
border-top-right-radius: 9px;
|
|
23
|
+
background-color: white;
|
|
24
|
+
padding: 7px 4em 0 4em;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
h1 {
|
|
28
|
+
font-size: 100%;
|
|
29
|
+
color: #730E15;
|
|
30
|
+
line-height: 1.5em;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
body > p {
|
|
34
|
+
width: 33em;
|
|
35
|
+
margin: 0 auto 1em;
|
|
36
|
+
padding: 1em 0;
|
|
37
|
+
background-color: #F7F7F7;
|
|
38
|
+
border: 1px solid #CCC;
|
|
39
|
+
border-right-color: #999;
|
|
40
|
+
border-bottom-color: #999;
|
|
41
|
+
border-bottom-left-radius: 4px;
|
|
42
|
+
border-bottom-right-radius: 4px;
|
|
43
|
+
border-top-color: #DADADA;
|
|
44
|
+
color: #666;
|
|
45
|
+
box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
|
|
46
|
+
}
|
|
47
|
+
</style>
|
|
48
|
+
</head>
|
|
49
|
+
|
|
50
|
+
<body>
|
|
51
|
+
<!-- This file lives in public/404.html -->
|
|
52
|
+
<div class="dialog">
|
|
53
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
|
54
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
|
55
|
+
</div>
|
|
56
|
+
<p>If you are the application owner check the logs for more information.</p>
|
|
57
|
+
</body>
|
|
58
|
+
</html>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
|
5
|
+
<style>
|
|
6
|
+
body {
|
|
7
|
+
background-color: #EFEFEF;
|
|
8
|
+
color: #2E2F30;
|
|
9
|
+
text-align: center;
|
|
10
|
+
font-family: arial, sans-serif;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
div.dialog {
|
|
14
|
+
width: 25em;
|
|
15
|
+
margin: 4em auto 0 auto;
|
|
16
|
+
border: 1px solid #CCC;
|
|
17
|
+
border-right-color: #999;
|
|
18
|
+
border-left-color: #999;
|
|
19
|
+
border-bottom-color: #BBB;
|
|
20
|
+
border-top: #B00100 solid 4px;
|
|
21
|
+
border-top-left-radius: 9px;
|
|
22
|
+
border-top-right-radius: 9px;
|
|
23
|
+
background-color: white;
|
|
24
|
+
padding: 7px 4em 0 4em;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
h1 {
|
|
28
|
+
font-size: 100%;
|
|
29
|
+
color: #730E15;
|
|
30
|
+
line-height: 1.5em;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
body > p {
|
|
34
|
+
width: 33em;
|
|
35
|
+
margin: 0 auto 1em;
|
|
36
|
+
padding: 1em 0;
|
|
37
|
+
background-color: #F7F7F7;
|
|
38
|
+
border: 1px solid #CCC;
|
|
39
|
+
border-right-color: #999;
|
|
40
|
+
border-bottom-color: #999;
|
|
41
|
+
border-bottom-left-radius: 4px;
|
|
42
|
+
border-bottom-right-radius: 4px;
|
|
43
|
+
border-top-color: #DADADA;
|
|
44
|
+
color: #666;
|
|
45
|
+
box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
|
|
46
|
+
}
|
|
47
|
+
</style>
|
|
48
|
+
</head>
|
|
49
|
+
|
|
50
|
+
<body>
|
|
51
|
+
<!-- This file lives in public/422.html -->
|
|
52
|
+
<div class="dialog">
|
|
53
|
+
<h1>The change you wanted was rejected.</h1>
|
|
54
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
|
55
|
+
</div>
|
|
56
|
+
<p>If you are the application owner check the logs for more information.</p>
|
|
57
|
+
</body>
|
|
58
|
+
</html>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
|
5
|
+
<style>
|
|
6
|
+
body {
|
|
7
|
+
background-color: #EFEFEF;
|
|
8
|
+
color: #2E2F30;
|
|
9
|
+
text-align: center;
|
|
10
|
+
font-family: arial, sans-serif;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
div.dialog {
|
|
14
|
+
width: 25em;
|
|
15
|
+
margin: 4em auto 0 auto;
|
|
16
|
+
border: 1px solid #CCC;
|
|
17
|
+
border-right-color: #999;
|
|
18
|
+
border-left-color: #999;
|
|
19
|
+
border-bottom-color: #BBB;
|
|
20
|
+
border-top: #B00100 solid 4px;
|
|
21
|
+
border-top-left-radius: 9px;
|
|
22
|
+
border-top-right-radius: 9px;
|
|
23
|
+
background-color: white;
|
|
24
|
+
padding: 7px 4em 0 4em;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
h1 {
|
|
28
|
+
font-size: 100%;
|
|
29
|
+
color: #730E15;
|
|
30
|
+
line-height: 1.5em;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
body > p {
|
|
34
|
+
width: 33em;
|
|
35
|
+
margin: 0 auto 1em;
|
|
36
|
+
padding: 1em 0;
|
|
37
|
+
background-color: #F7F7F7;
|
|
38
|
+
border: 1px solid #CCC;
|
|
39
|
+
border-right-color: #999;
|
|
40
|
+
border-bottom-color: #999;
|
|
41
|
+
border-bottom-left-radius: 4px;
|
|
42
|
+
border-bottom-right-radius: 4px;
|
|
43
|
+
border-top-color: #DADADA;
|
|
44
|
+
color: #666;
|
|
45
|
+
box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
|
|
46
|
+
}
|
|
47
|
+
</style>
|
|
48
|
+
</head>
|
|
49
|
+
|
|
50
|
+
<body>
|
|
51
|
+
<!-- This file lives in public/500.html -->
|
|
52
|
+
<div class="dialog">
|
|
53
|
+
<h1>We're sorry, but something went wrong.</h1>
|
|
54
|
+
</div>
|
|
55
|
+
<p>If you are the application owner check the logs for more information.</p>
|
|
56
|
+
</body>
|
|
57
|
+
</html>
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/spec/form/nested_spec.rb
CHANGED
|
@@ -3,56 +3,72 @@ require 'freeform/form/property'
|
|
|
3
3
|
require 'freeform/form/nested'
|
|
4
4
|
|
|
5
5
|
describe FreeForm::Nested do
|
|
6
|
-
describe "
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
describe "has_many", :has_many => true do
|
|
7
|
+
let!(:nested_class) do
|
|
8
|
+
klass = Class.new(Module) do
|
|
9
|
+
include FreeForm::Property
|
|
10
|
+
include FreeForm::Nested
|
|
11
|
+
declared_model :address
|
|
12
|
+
|
|
13
|
+
property :street, :on => :address
|
|
14
|
+
|
|
15
|
+
def initialize(h={})
|
|
16
|
+
h.each {|k,v| send("#{k}=",v)}
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
# This wrapper just avoids CONST warnings
|
|
20
|
+
v, $VERBOSE = $VERBOSE, nil
|
|
21
|
+
Module.const_set("MailingAddressForm", klass)
|
|
22
|
+
$VERBOSE = v
|
|
23
|
+
klass
|
|
24
|
+
end
|
|
18
25
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
let(:form_class) do
|
|
27
|
+
klass = Class.new(Module) do
|
|
28
|
+
include FreeForm::Property
|
|
29
|
+
include FreeForm::Nested
|
|
30
|
+
|
|
31
|
+
has_many :mailing_addresses, :class => Module::MailingAddressForm, :default_initializer => :mailing_address_initializer
|
|
32
|
+
|
|
33
|
+
def initialize(h={})
|
|
34
|
+
h.each {|k,v| send("#{k}=",v)}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def mailing_address_initializer
|
|
38
|
+
{ :address => OpenStruct.new(:id => Random.new.rand(1000000)) }
|
|
22
39
|
end
|
|
23
|
-
# This wrapper just avoids CONST warnings
|
|
24
|
-
v, $VERBOSE = $VERBOSE, nil
|
|
25
|
-
Module.const_set("DummyForm", klass)
|
|
26
|
-
$VERBOSE = v
|
|
27
|
-
klass
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
let(:form) do
|
|
31
|
-
form_class.mailing_address_initializer = lambda { { :address => OpenStruct.new } }
|
|
32
|
-
form_model = form_class.new
|
|
33
40
|
end
|
|
41
|
+
# This wrapper just avoids CONST warnings
|
|
42
|
+
v, $VERBOSE = $VERBOSE, nil
|
|
43
|
+
Module.const_set("DummyForm", klass)
|
|
44
|
+
$VERBOSE = v
|
|
45
|
+
klass
|
|
46
|
+
end
|
|
34
47
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
48
|
+
let(:form) do
|
|
49
|
+
form_model = form_class.new
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe "form class" do
|
|
53
|
+
it "sets nested_form in models" do
|
|
54
|
+
form_class.models.should eq([:mailing_addresses])
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe "building nested models" do
|
|
59
|
+
it "initializes with no nested models prebuilt" do
|
|
60
|
+
form.mailing_addresses.should eq([])
|
|
39
61
|
end
|
|
40
62
|
|
|
41
|
-
|
|
42
|
-
it "initializes with no nested models prebuilt" do
|
|
43
|
-
form.mailing_addresses.should eq([])
|
|
44
|
-
end
|
|
45
|
-
|
|
63
|
+
context "with default initializer" do
|
|
46
64
|
it "allows nested_forms to be built" do
|
|
47
65
|
form.build_mailing_addresses
|
|
48
66
|
form.mailing_addresses.should be_an(Array)
|
|
49
67
|
form.mailing_addresses.should_not be_empty
|
|
50
|
-
form.mailing_addresses.first.should be_a(Module::
|
|
68
|
+
form.mailing_addresses.first.should be_a(Module::MailingAddressForm)
|
|
51
69
|
end
|
|
52
|
-
|
|
70
|
+
|
|
53
71
|
it "builds unique models" do
|
|
54
|
-
# Using module here, since they initialize uniquely
|
|
55
|
-
form_class.mailing_address_initializer = lambda { { :address => Module.new } }
|
|
56
72
|
form = form_class.new
|
|
57
73
|
form.build_mailing_address
|
|
58
74
|
form.build_mailing_address
|
|
@@ -60,36 +76,34 @@ describe FreeForm::Nested do
|
|
|
60
76
|
address_2 = form.mailing_addresses.last.address
|
|
61
77
|
address_1.should_not eq(address_2)
|
|
62
78
|
end
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context "with custom initializer" do
|
|
82
|
+
it "allows nested_forms to be built" do
|
|
83
|
+
form.build_mailing_addresses(:address => OpenStruct.new)
|
|
84
|
+
form.mailing_addresses.should be_an(Array)
|
|
85
|
+
form.mailing_addresses.should_not be_empty
|
|
86
|
+
form.mailing_addresses.first.should be_a(Module::MailingAddressForm)
|
|
68
87
|
end
|
|
69
|
-
|
|
88
|
+
|
|
70
89
|
it "allows nested_forms to be built with custom initializers" do
|
|
71
90
|
form.build_mailing_address(:address => OpenStruct.new(:street => "1600 Pennsylvania Ave."))
|
|
72
91
|
form.mailing_addresses.first.street.should eq("1600 Pennsylvania Ave.")
|
|
73
92
|
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
describe "setting attributes" do
|
|
97
|
+
describe "nested attribute assignment" do
|
|
98
|
+
let(:attributes) do
|
|
99
|
+
{ :mailing_addresses_attributes => { "0" => { :street => "123 Main St." } } }
|
|
100
|
+
end
|
|
74
101
|
|
|
75
|
-
it "
|
|
76
|
-
|
|
77
|
-
|
|
102
|
+
it "assigns nested attributes" do
|
|
103
|
+
form.fill(attributes)
|
|
104
|
+
form.mailing_addresses.first.street.should eq("123 Main St.")
|
|
78
105
|
end
|
|
79
106
|
end
|
|
80
|
-
|
|
81
|
-
describe "setting attributes" do
|
|
82
|
-
describe "nested attribute assignment" do
|
|
83
|
-
let(:attributes) do
|
|
84
|
-
{ :mailing_addresses_attributes => { "0" => { :street => "123 Main St." } } }
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
it "assigns nested attributes" do
|
|
88
|
-
form.fill(attributes)
|
|
89
|
-
form.mailing_addresses.first.street.should eq("123 Main St.")
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
107
|
+
end
|
|
94
108
|
end
|
|
95
109
|
end
|
data/spec/form/property_spec.rb
CHANGED
|
@@ -141,6 +141,39 @@ describe FreeForm::Property do
|
|
|
141
141
|
form_class.models.should eq([:test_model_1, :test_model_2])
|
|
142
142
|
end
|
|
143
143
|
end
|
|
144
|
+
|
|
145
|
+
describe "child models", :child_models => true do
|
|
146
|
+
let(:form_class) do
|
|
147
|
+
Class.new(Module) do
|
|
148
|
+
include FreeForm::Property
|
|
149
|
+
form_model :test_model_1
|
|
150
|
+
child_model :test_model_2 do
|
|
151
|
+
test_model_1.build_child
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def initialize(h={})
|
|
155
|
+
h.each {|k,v| send("#{k}=",v)}
|
|
156
|
+
initialize_test_model_2
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
let(:form) do
|
|
162
|
+
form_class.new(
|
|
163
|
+
:test_model_1 => OpenStruct.new(:dummy => "yes",
|
|
164
|
+
:build_child => OpenStruct.new(:field => "child model"))
|
|
165
|
+
)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it "sets declared models as accessor" do
|
|
169
|
+
form.test_model_1.should eq(OpenStruct.new(:dummy => "yes", :build_child => OpenStruct.new(:field => "child model")))
|
|
170
|
+
form.test_model_2.should eq(OpenStruct.new(:field => "child model"))
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it "sets @models in class to declared models" do
|
|
174
|
+
form_class.models.should eq([:test_model_1, :test_model_2])
|
|
175
|
+
end
|
|
176
|
+
end
|
|
144
177
|
end
|
|
145
178
|
|
|
146
179
|
describe "properties", :properties => true do
|
|
@@ -152,6 +185,7 @@ describe FreeForm::Property do
|
|
|
152
185
|
|
|
153
186
|
property :attribute_1, :on => :test_model
|
|
154
187
|
property :attribute_2, :on => :test_model, :ignore_blank => true
|
|
188
|
+
property :attribute_3, :as => :test_attribute_3, :on => :test_model
|
|
155
189
|
|
|
156
190
|
def initialize(h={})
|
|
157
191
|
h.each {|k,v| send("#{k}=",v)}
|
|
@@ -165,25 +199,144 @@ describe FreeForm::Property do
|
|
|
165
199
|
)
|
|
166
200
|
end
|
|
167
201
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
202
|
+
describe "delegation" do
|
|
203
|
+
it "delegates properties to models" do
|
|
204
|
+
form.attribute_1.should eq("yes")
|
|
205
|
+
form.attribute_2.should be_nil
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it "allows properties to be written, and delegates the values" do
|
|
209
|
+
form.attribute_1 = "changed"
|
|
210
|
+
form.attribute_1.should eq("changed")
|
|
211
|
+
form.test_model.attribute_1.should eq("changed")
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
it "delegates using :as" do
|
|
215
|
+
form.test_attribute_3.should be_nil
|
|
216
|
+
form.test_attribute_3 = "set_using_as"
|
|
217
|
+
form.test_attribute_3.should eq("set_using_as")
|
|
218
|
+
form.test_model.attribute_3.should eq("set_using_as")
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
describe "property_mappings" do
|
|
223
|
+
it "sets appropriate property mappings" do
|
|
224
|
+
form_class.property_mappings.should eq(
|
|
225
|
+
{ :attribute_1 => {:model => :test_model, :field => :attribute_1, :ignore_blank => false},
|
|
226
|
+
:attribute_2 => {:model => :test_model, :field => :attribute_2, :ignore_blank => true},
|
|
227
|
+
:test_attribute_3 => {:model => :test_model, :field => :attribute_3, :ignore_blank => false}
|
|
228
|
+
}
|
|
229
|
+
)
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
describe "allow_destroy_on_save", :allow_destroy_on_save => true do
|
|
235
|
+
let(:form_class) do
|
|
236
|
+
Class.new(Module) do
|
|
237
|
+
include FreeForm::Property
|
|
238
|
+
declared_model :test_model
|
|
239
|
+
allow_destroy_on_save
|
|
240
|
+
|
|
241
|
+
property :attribute_1, :on => :test_model
|
|
242
|
+
property :attribute_2, :on => :test_model, :ignore_blank => true
|
|
243
|
+
|
|
244
|
+
def initialize(h={})
|
|
245
|
+
h.each {|k,v| send("#{k}=",v)}
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
let(:form) do
|
|
251
|
+
form_class.new(:test_model => OpenStruct.new)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
it "has _destroy accessor" do
|
|
255
|
+
form.should respond_to(:_destroy)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it "has marked_for_destruction? accessor" do
|
|
259
|
+
form.should respond_to(:marked_for_destruction?)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
it "has destroy as false by default" do
|
|
263
|
+
form._destroy.should be_false
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
it "has marked_for_destruction? as false by default" do
|
|
267
|
+
form.marked_for_destruction?.should be_false
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it "can be marked for destruction" do
|
|
271
|
+
form.marked_for_destruction?.should be_false
|
|
272
|
+
form.mark_for_destruction
|
|
273
|
+
form.marked_for_destruction?.should be_true
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
it "interprets '0' is not marked for destruction" do
|
|
277
|
+
form.fill({:_destroy => "0"})
|
|
278
|
+
form.marked_for_destruction?.should be_false
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
it "interprets 'false' is not marked for destruction" do
|
|
282
|
+
form.fill({:_destroy => "false"})
|
|
283
|
+
form.marked_for_destruction?.should be_false
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
it "interprets '1' is marked for destruction" do
|
|
287
|
+
form.fill({:_destroy => "1"})
|
|
288
|
+
form.marked_for_destruction?.should be_true
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
it "interprets 'true' is marked for destruction" do
|
|
292
|
+
form.fill({:_destroy => "true"})
|
|
293
|
+
form.marked_for_destruction?.should be_true
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
it "interprets '2' is marked for destruction" do
|
|
297
|
+
form.fill({:_destroy => "2"})
|
|
298
|
+
form.marked_for_destruction?.should be_true
|
|
299
|
+
end
|
|
182
300
|
end
|
|
183
301
|
end
|
|
184
302
|
end
|
|
185
303
|
|
|
186
304
|
describe "instance methods", :instance_methods => true do
|
|
305
|
+
describe "parent_form", :parent_form => true do
|
|
306
|
+
let(:form_class) do
|
|
307
|
+
Class.new(Module) do
|
|
308
|
+
include FreeForm::Property
|
|
309
|
+
declared_model :first_model
|
|
310
|
+
declared_model :second_model
|
|
311
|
+
|
|
312
|
+
property :attribute_1, :on => :first_model
|
|
313
|
+
property :attribute_2, :on => :first_model, :ignore_blank => true
|
|
314
|
+
property :attribute_3, :on => :second_model, :ignore_blank => true
|
|
315
|
+
property :attribute_4, :on => :second_model
|
|
316
|
+
|
|
317
|
+
def initialize(h)
|
|
318
|
+
h.each {|k,v| send("#{k}=",v)}
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
let(:form) do
|
|
324
|
+
form_class.new(
|
|
325
|
+
:first_model => OpenStruct.new(:attribute_1 => "first", :attribute_2 => "second"),
|
|
326
|
+
:second_model => OpenStruct.new(:attribute_3 => "third", :attribute_4 => "fourth"),
|
|
327
|
+
)
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it "has parent_form as nil by default" do
|
|
331
|
+
form.parent_form.should be_nil
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
it "has can assign and reference parent_form" do
|
|
335
|
+
parent = Module.new
|
|
336
|
+
form.parent_form = parent
|
|
337
|
+
form.parent_form.should eq(parent)
|
|
338
|
+
end
|
|
339
|
+
end
|
|
187
340
|
describe "assign_attributes", :assign_attributes => true do
|
|
188
341
|
let(:form_class) do
|
|
189
342
|
Class.new(Module) do
|