validation_sync 0.0.4 → 0.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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/generate_validations.js.erb +138 -0
- data/app/assets/javascripts/validation_sync.js +2 -1
- data/app/helpers/validation_sync_form_helper.rb +12 -71
- data/lib/validation_sync/engine.rb +2 -0
- data/lib/validation_sync/validation_builder.rb +139 -0
- data/lib/validation_sync/version.rb +1 -1
- data/lib/validation_sync.rb +1 -0
- data/spec/dummy/app/controllers/posts_controller.rb +1 -1
- data/spec/dummy/app/controllers/users_controller.rb +58 -0
- data/spec/dummy/app/models/post.rb +15 -4
- data/spec/dummy/app/models/user.rb +11 -0
- data/spec/dummy/app/views/posts/_form.html.erb +8 -0
- data/spec/dummy/app/views/posts/show.html.erb +5 -0
- data/spec/dummy/app/views/users/_form.html.erb +33 -0
- data/spec/dummy/app/views/users/edit.html.erb +6 -0
- data/spec/dummy/app/views/users/index.html.erb +29 -0
- data/spec/dummy/app/views/users/new.html.erb +5 -0
- data/spec/dummy/app/views/users/show.html.erb +14 -0
- data/spec/dummy/config/application.rb +1 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20140211200846_create_users.rb +10 -0
- data/spec/dummy/db/migrate/20140212170448_add_order_to_posts.rb +5 -0
- data/spec/dummy/db/migrate/20140212173012_add_user_id_to_posts.rb +5 -0
- data/spec/dummy/db/schema.rb +10 -1
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +7256 -0
- data/spec/dummy/log/test.log +6037 -0
- data/spec/dummy/spec/factories/posts.rb +26 -0
- data/spec/dummy/spec/factories/users.rb +14 -0
- data/spec/dummy/spec/models/post_spec.rb +98 -0
- data/spec/dummy/spec/models/user_spec.rb +27 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/10c6f05e183df4466be1e0171868fbd3 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/254f7fcb30f60607963da8bbb320eb25 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/256916ba749d0c14e36b55d4b382e9f5 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/38ec44893aed52b20a20a929a47e0ad9 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4a4d6fda449d6b443e5b29ccb755c732 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/513dd40b9b52367f54d64438a9d802b9 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/56146675dbad13c72d3eb9ebd823dc11 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/7aaf7da4e6ec4c84cc7948fb20c35064 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ba165ee56ce37f61865fe03d6503539b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/bfaeb96080cc4d8ba400fbdcd1d4aab2 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c4f1b332263aa5004a8ac54ca9530510 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c63406c52c03bbb24922ded6ebb0e0a2 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cbc66bd36b3aa4411f9ce20da0fd37a0 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d7874cf8a5946ec3899e5bb627905ca5 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e1d4998592ddfea795aca82d742d9478 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/0f11e0b3e0ece93d6c047318f2e5497d +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/10c6f05e183df4466be1e0171868fbd3 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/122e92d06837af295d6c941999a8d48f +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/254f7fcb30f60607963da8bbb320eb25 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/256916ba749d0c14e36b55d4b382e9f5 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/4a4d6fda449d6b443e5b29ccb755c732 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/56146675dbad13c72d3eb9ebd823dc11 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/bfaeb96080cc4d8ba400fbdcd1d4aab2 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/c4f1b332263aa5004a8ac54ca9530510 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/d7874cf8a5946ec3899e5bb627905ca5 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/e1d4998592ddfea795aca82d742d9478 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/capybara/capybara-201402111733312899331645.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402111742049902988712.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402111743461497527818.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121034216891460553.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121100145511229652.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-20140212110749239625833.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121110009350488348.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121242315707153414.html +54 -0
- data/spec/dummy/tmp/capybara/capybara-2014021212463939561980.html +47 -0
- data/spec/dummy/tmp/capybara/capybara-201402121308362867044001.html +47 -0
- data/spec/dummy/tmp/capybara/capybara-201402121309286432044699.html +47 -0
- data/spec/dummy/tmp/capybara/capybara-201402121506235794052148.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121507316558835315.html +27 -0
- data/spec/dummy/tmp/capybara/capybara-201402121512202956445364.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121517176338336364.html +39 -0
- data/spec/dummy/tmp/capybara/capybara-201402121518121290133083.html +39 -0
- data/spec/dummy/tmp/pids/server.pid +1 -0
- data/spec/features/form_interactions_spec.rb +153 -0
- data/spec/features/generate_validations_spec.rb +26 -0
- data/spec/helpers/validation_sync_form_helper_spec.rb +24 -0
- data/spec/lib/validation_builder_spec.rb +173 -0
- data/spec/spec_helper.rb +7 -1
- metadata +120 -11
- data/app/assets/javascripts/validations.js.coffee.erb +0 -51
- data/spec/dummy/app/assets/javascripts/posts.js +0 -2
- data/spec/dummy/app/assets/stylesheets/posts.css +0 -4
- data/spec/features/form_validation_spec.rb +0 -53
- data/spec/helpers/form_helper_spec.rb +0 -4
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<!DOCTYPE html><html><head>
|
|
2
|
+
<title>Dummy</title>
|
|
3
|
+
<link data-turbolinks-track="true" href="/assets/application.css" media="all" rel="stylesheet">
|
|
4
|
+
<script data-turbolinks-track="true" src="/assets/application.js"></script>
|
|
5
|
+
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
|
|
9
|
+
<h1>New post</h1>
|
|
10
|
+
|
|
11
|
+
<form accept-charset="UTF-8" action="/posts" class="new_post" data-sync-validations="true" id="new_post" method="post" novalidate="novalidate"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"></div>
|
|
12
|
+
|
|
13
|
+
<div class="field">
|
|
14
|
+
<label for="post_title">Title</label><br>
|
|
15
|
+
<input id="post_title" name="post[title]" type="text" class="valid">
|
|
16
|
+
</div>
|
|
17
|
+
<div class="field">
|
|
18
|
+
<label for="post_content">Content</label><br>
|
|
19
|
+
<textarea id="post_content" name="post[content]" class="valid"></textarea>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="field">
|
|
22
|
+
<label for="post_view_count">View count</label><br>
|
|
23
|
+
<input id="post_view_count" name="post[view_count]" type="text" class="valid">
|
|
24
|
+
</div>
|
|
25
|
+
<div class="field">
|
|
26
|
+
<label for="post_order">Order</label><br>
|
|
27
|
+
<input id="post_order" name="post[order]" type="text" class="valid">
|
|
28
|
+
</div>
|
|
29
|
+
<div class="field">
|
|
30
|
+
<label for="post_author_email">Author email</label><br>
|
|
31
|
+
<input id="post_author_email" name="post[author_email]" type="text" class="error"><label for="post_author_email" class="error"></label>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="field">
|
|
34
|
+
<label for="post_user_id">User</label><br>
|
|
35
|
+
<input id="post_user_id" name="post[user_id]" type="text" class="error"><label for="post_user_id" class="error"></label>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="actions">
|
|
38
|
+
<input name="commit" type="submit" value="Create Post">
|
|
39
|
+
</div>
|
|
40
|
+
</form>
|
|
41
|
+
|
|
42
|
+
<a href="/posts">Back</a>
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
</body></html>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<!DOCTYPE html><html><head>
|
|
2
|
+
<title>Dummy</title>
|
|
3
|
+
<link data-turbolinks-track="true" href="/assets/application.css" media="all" rel="stylesheet">
|
|
4
|
+
<script data-turbolinks-track="true" src="/assets/application.js"></script>
|
|
5
|
+
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
|
|
9
|
+
<h1>New post</h1>
|
|
10
|
+
|
|
11
|
+
<form accept-charset="UTF-8" action="/posts" class="new_post" data-sync-validations="true" id="new_post" method="post" novalidate="novalidate"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"></div>
|
|
12
|
+
|
|
13
|
+
<div class="field">
|
|
14
|
+
<label for="post_title">Title</label><br>
|
|
15
|
+
<input id="post_title" name="post[title]" type="text" class="valid">
|
|
16
|
+
</div>
|
|
17
|
+
<div class="field">
|
|
18
|
+
<label for="post_content">Content</label><br>
|
|
19
|
+
<textarea id="post_content" name="post[content]" class="valid"></textarea>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="field">
|
|
22
|
+
<label for="post_view_count">View count</label><br>
|
|
23
|
+
<input id="post_view_count" name="post[view_count]" type="text" class="valid">
|
|
24
|
+
</div>
|
|
25
|
+
<div class="field">
|
|
26
|
+
<label for="post_order">Order</label><br>
|
|
27
|
+
<input id="post_order" name="post[order]" type="text" class="valid">
|
|
28
|
+
</div>
|
|
29
|
+
<div class="field">
|
|
30
|
+
<label for="post_author_email">Author email</label><br>
|
|
31
|
+
<input id="post_author_email" name="post[author_email]" type="text" class="error"><label for="post_author_email" class="error"></label>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="field">
|
|
34
|
+
<label for="post_user_id">User</label><br>
|
|
35
|
+
<input id="post_user_id" name="post[user_id]" type="text" class="valid">
|
|
36
|
+
</div>
|
|
37
|
+
<div class="actions">
|
|
38
|
+
<input name="commit" type="submit" value="Create Post">
|
|
39
|
+
</div>
|
|
40
|
+
</form>
|
|
41
|
+
|
|
42
|
+
<a href="/posts">Back</a>
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
</body></html>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!DOCTYPE html><html><head>
|
|
2
|
+
<title>Dummy</title>
|
|
3
|
+
<link data-turbolinks-track="true" href="/assets/application.css" media="all" rel="stylesheet">
|
|
4
|
+
<script data-turbolinks-track="true" src="/assets/application.js"></script>
|
|
5
|
+
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
|
|
9
|
+
<h1>New user</h1>
|
|
10
|
+
|
|
11
|
+
<form accept-charset="UTF-8" action="/users" class="new_user" data-sync-validations="true" id="new_user" method="post" novalidate="novalidate"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"></div>
|
|
12
|
+
|
|
13
|
+
<div class="field">
|
|
14
|
+
<label for="user_email">Email</label><br>
|
|
15
|
+
<input id="user_email" name="user[email]" type="text" class="error"><label for="user_email" class="error">Please enter the same value again.</label>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="field">
|
|
18
|
+
<label for="user_email_confirmation">Email confirmation</label><br>
|
|
19
|
+
<input id="user_email_confirmation" name="user[email_confirmation]" type="text" class="valid">
|
|
20
|
+
</div>
|
|
21
|
+
<div class="field">
|
|
22
|
+
<label for="user_password">Password</label><br>
|
|
23
|
+
<textarea id="user_password" name="user[password]" class="error"></textarea><label for="user_password" class="error">Please enter the same value again.</label>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="field">
|
|
26
|
+
<label for="user_password_confirmation">Password confirmation</label><br>
|
|
27
|
+
<input id="user_password_confirmation" name="user[password_confirmation]" type="text" class="valid">
|
|
28
|
+
</div>
|
|
29
|
+
<div class="actions">
|
|
30
|
+
<input name="commit" type="submit" value="Create User">
|
|
31
|
+
</div>
|
|
32
|
+
</form>
|
|
33
|
+
|
|
34
|
+
<a href="/users">Back</a>
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
</body></html>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!DOCTYPE html><html><head>
|
|
2
|
+
<title>Dummy</title>
|
|
3
|
+
<link data-turbolinks-track="true" href="/assets/application.css" media="all" rel="stylesheet">
|
|
4
|
+
<script data-turbolinks-track="true" src="/assets/application.js"></script>
|
|
5
|
+
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
|
|
9
|
+
<p id="notice">User was successfully created.</p>
|
|
10
|
+
|
|
11
|
+
<p>
|
|
12
|
+
<strong>Email:</strong>
|
|
13
|
+
email4@example.com
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<p>
|
|
17
|
+
<strong>Password:</strong>
|
|
18
|
+
password!
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
<a href="/users/29/edit">Edit</a> |
|
|
22
|
+
<a href="/users">Back</a>
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
</body></html>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!DOCTYPE html><html><head>
|
|
2
|
+
<title>Dummy</title>
|
|
3
|
+
<link data-turbolinks-track="true" href="/assets/application.css" media="all" rel="stylesheet">
|
|
4
|
+
<script data-turbolinks-track="true" src="/assets/application.js"></script>
|
|
5
|
+
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
|
|
9
|
+
<h1>New user</h1>
|
|
10
|
+
|
|
11
|
+
<form accept-charset="UTF-8" action="/users" class="new_user" data-sync-validations="true" id="new_user" method="post" novalidate="novalidate"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"></div>
|
|
12
|
+
|
|
13
|
+
<div class="field">
|
|
14
|
+
<label for="user_email">Email</label><br>
|
|
15
|
+
<input id="user_email" name="user[email]" type="text" class="error"><label for="user_email" class="error"></label>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="field">
|
|
18
|
+
<label for="user_email_confirmation">Email confirmation</label><br>
|
|
19
|
+
<input id="user_email_confirmation" name="user[email_confirmation]" type="text" class="valid">
|
|
20
|
+
</div>
|
|
21
|
+
<div class="field">
|
|
22
|
+
<label for="user_password">Password</label><br>
|
|
23
|
+
<textarea id="user_password" name="user[password]" class="error"></textarea><label for="user_password" class="error">Confirm your password, bitch!</label>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="field">
|
|
26
|
+
<label for="user_password_confirmation">Password confirmation</label><br>
|
|
27
|
+
<input id="user_password_confirmation" name="user[password_confirmation]" type="text" class="valid">
|
|
28
|
+
</div>
|
|
29
|
+
<div class="actions">
|
|
30
|
+
<input name="commit" type="submit" value="Create User">
|
|
31
|
+
</div>
|
|
32
|
+
</form>
|
|
33
|
+
|
|
34
|
+
<a href="/users">Back</a>
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
</body></html>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!DOCTYPE html><html><head>
|
|
2
|
+
<title>Dummy</title>
|
|
3
|
+
<link data-turbolinks-track="true" href="/assets/application.css" media="all" rel="stylesheet">
|
|
4
|
+
<script data-turbolinks-track="true" src="/assets/application.js"></script>
|
|
5
|
+
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
|
|
9
|
+
<h1>New user</h1>
|
|
10
|
+
|
|
11
|
+
<form accept-charset="UTF-8" action="/users" class="new_user" data-sync-validations="true" id="new_user" method="post" novalidate="novalidate"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"></div>
|
|
12
|
+
|
|
13
|
+
<div class="field">
|
|
14
|
+
<label for="user_email">Email</label><br>
|
|
15
|
+
<input id="user_email" name="user[email]" type="text" class="valid"><label for="user_email" class="error" style="display: none; ">Please enter the same value again.</label>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="field">
|
|
18
|
+
<label for="user_email_confirmation">Email confirmation</label><br>
|
|
19
|
+
<input id="user_email_confirmation" name="user[email_confirmation]" type="text" class="valid">
|
|
20
|
+
</div>
|
|
21
|
+
<div class="field">
|
|
22
|
+
<label for="user_password">Password</label><br>
|
|
23
|
+
<input id="user_password" name="user[password]" type="text" class="error"><label for="user_password" class="error">Please enter the same value again.</label>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="field">
|
|
26
|
+
<label for="user_password_confirmation">Password confirmation</label><br>
|
|
27
|
+
<input id="user_password_confirmation" name="user[password_confirmation]" type="text" class="valid">
|
|
28
|
+
</div>
|
|
29
|
+
<div class="actions">
|
|
30
|
+
<input name="commit" type="submit" value="Create User">
|
|
31
|
+
</div>
|
|
32
|
+
</form>
|
|
33
|
+
|
|
34
|
+
<a href="/users">Back</a>
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
</body></html>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!DOCTYPE html><html><head>
|
|
2
|
+
<title>Dummy</title>
|
|
3
|
+
<link data-turbolinks-track="true" href="/assets/application.css" media="all" rel="stylesheet">
|
|
4
|
+
<script data-turbolinks-track="true" src="/assets/application.js"></script>
|
|
5
|
+
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
|
|
9
|
+
<h1>New user</h1>
|
|
10
|
+
|
|
11
|
+
<form accept-charset="UTF-8" action="/users" class="new_user" data-sync-validations="true" id="new_user" method="post" novalidate="novalidate"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"></div>
|
|
12
|
+
|
|
13
|
+
<div class="field">
|
|
14
|
+
<label for="user_email">Email</label><br>
|
|
15
|
+
<input id="user_email" name="user[email]" type="text" class="valid"><label for="user_email" class="error" style="display: none; ">Please enter the same value again.</label>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="field">
|
|
18
|
+
<label for="user_email_confirmation">Email confirmation</label><br>
|
|
19
|
+
<input id="user_email_confirmation" name="user[email_confirmation]" type="text" class="valid">
|
|
20
|
+
</div>
|
|
21
|
+
<div class="field">
|
|
22
|
+
<label for="user_password">Password</label><br>
|
|
23
|
+
<input id="user_password" name="user[password]" type="text" class="error"><label for="user_password" class="error">Please enter the same value again.</label>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="field">
|
|
26
|
+
<label for="user_password_confirmation">Password confirmation</label><br>
|
|
27
|
+
<input id="user_password_confirmation" name="user[password_confirmation]" type="text" class="valid">
|
|
28
|
+
</div>
|
|
29
|
+
<div class="actions">
|
|
30
|
+
<input name="commit" type="submit" value="Create User">
|
|
31
|
+
</div>
|
|
32
|
+
</form>
|
|
33
|
+
|
|
34
|
+
<a href="/users">Back</a>
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
</body></html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
13129
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Interacting with forms", :js => true do
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
describe "posts" do
|
|
7
|
+
|
|
8
|
+
# Helper to quickly complete a valid form
|
|
9
|
+
def complete_form
|
|
10
|
+
@post = attributes_for(:post)
|
|
11
|
+
fill_in "post[title]", :with => @post[:title]
|
|
12
|
+
fill_in "post[content]", :with => @post[:content]
|
|
13
|
+
fill_in "post[view_count]", :with => @post[:view_count]
|
|
14
|
+
fill_in "post[order]", :with => @post[:order]
|
|
15
|
+
fill_in "post[user_id]", :with => @post[:user_id]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
before :each do
|
|
19
|
+
visit new_post_path
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
it "creates a valid record" do
|
|
24
|
+
complete_form
|
|
25
|
+
click_button "Create Post"
|
|
26
|
+
expect(page).to have_content @post[:title]
|
|
27
|
+
new_post = Post.last
|
|
28
|
+
expect(current_path).to eq post_path(new_post)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
describe "validates_presence_of" do
|
|
34
|
+
|
|
35
|
+
it "shows the custom message, when defined" do
|
|
36
|
+
complete_form
|
|
37
|
+
fill_in "post[title]", :with => ""
|
|
38
|
+
click_button "Create Post"
|
|
39
|
+
# we should not have changed pages
|
|
40
|
+
expect(current_path).to eq new_post_path
|
|
41
|
+
# We validate the presence of Post.title with the message "You need a title, bro."
|
|
42
|
+
expect(page).to have_content "You need a title, bro."
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "shows the default message when no custom message is defined" do
|
|
46
|
+
complete_form
|
|
47
|
+
fill_in "post[content]", :with => ""
|
|
48
|
+
click_button "Create Post"
|
|
49
|
+
# we should not have changed pages
|
|
50
|
+
expect(current_path).to eq new_post_path
|
|
51
|
+
# We validate the presence of Post.content with the default error message
|
|
52
|
+
expect(page).to have_content I18n.t('errors.messages.blank')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end # validates_presence_of
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
describe "validates_numericality_of" do
|
|
60
|
+
|
|
61
|
+
it "shows the custom message, when defined" do
|
|
62
|
+
complete_form
|
|
63
|
+
fill_in "post[order]", :with => "letters"
|
|
64
|
+
click_button "Create Post"
|
|
65
|
+
# we should not have changed pages
|
|
66
|
+
expect(current_path).to eq new_post_path
|
|
67
|
+
# We validate the numericality of Post.order with the message "Make that shit a number!"
|
|
68
|
+
expect(page).to have_content "Make that shit a number!"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "shows the default message when no custom message is defined" do
|
|
72
|
+
complete_form
|
|
73
|
+
fill_in "post[view_count]", :with => "letters"
|
|
74
|
+
click_button "Create Post"
|
|
75
|
+
# we should not have changed pages
|
|
76
|
+
expect(current_path).to eq new_post_path
|
|
77
|
+
# We validate the numericality of Post.view_count with the default error message
|
|
78
|
+
expect(page).to have_content I18n.t('errors.messages.not_a_number')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "Adds a 'required' validator if :allow_nil => false" do
|
|
82
|
+
complete_form
|
|
83
|
+
fill_in "post[user_id]", :with => ""
|
|
84
|
+
click_button "Create Post"
|
|
85
|
+
# we should not have changed pages
|
|
86
|
+
expect(current_path).to eq new_post_path
|
|
87
|
+
# We validate the numericality (allow_nil = false) of Post.user_id with the message "User ID Must be a number."
|
|
88
|
+
expect(page).to have_content "User ID Must be a number."
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end # validates_numericality_of
|
|
92
|
+
|
|
93
|
+
end # posts
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
describe "users" do
|
|
99
|
+
|
|
100
|
+
# Helper to quickly complete a valid form
|
|
101
|
+
def complete_form
|
|
102
|
+
@user = attributes_for(:user)
|
|
103
|
+
fill_in "user[email]", :with => @user[:email]
|
|
104
|
+
fill_in "user[email_confirmation]", :with => @user[:email]
|
|
105
|
+
fill_in "user[password]", :with => @user[:password]
|
|
106
|
+
fill_in "user[password_confirmation]", :with => @user[:password]
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
before :each do
|
|
110
|
+
visit new_user_path
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
it "creates a valid record" do
|
|
115
|
+
complete_form
|
|
116
|
+
click_button "Create User"
|
|
117
|
+
expect(page).to have_content @user[:title]
|
|
118
|
+
new_user = User.last
|
|
119
|
+
expect(current_path).to eq user_path(new_user)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
describe "validates_confirmation_of" do
|
|
125
|
+
|
|
126
|
+
it "shows the custom message, when defined" do
|
|
127
|
+
complete_form
|
|
128
|
+
fill_in "user[password_confirmation]", :with => "differentPassword"
|
|
129
|
+
click_button "Create User"
|
|
130
|
+
# we should not have changed pages
|
|
131
|
+
expect(current_path).to eq new_user_path
|
|
132
|
+
# We validate the confirmation of of User.password with the message "Confirm your password, bitch!"
|
|
133
|
+
expect(page).to have_content "Confirm your password, bitch!"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "shows the default message when no custom message is defined" do
|
|
137
|
+
complete_form
|
|
138
|
+
fill_in "user[email_confirmation]", :with => ""
|
|
139
|
+
click_button "Create User"
|
|
140
|
+
# we should not have changed pages
|
|
141
|
+
expect(current_path).to eq new_user_path
|
|
142
|
+
# We validate the confirmation of of User.email with the default error message
|
|
143
|
+
expect(page).to have_content I18n.t('errors.messages.confirmation', attribute: "Email")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
end # validates_confirmation_of
|
|
147
|
+
|
|
148
|
+
end # users
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
end # Interacting with forms
|
|
153
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
# describe "Generating Validation JS" do
|
|
4
|
+
|
|
5
|
+
# before :each do
|
|
6
|
+
# visit "/assets/generate_validations.js"
|
|
7
|
+
# end
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# describe "creating a method for each model" do
|
|
12
|
+
|
|
13
|
+
# it "wraps the page in a function" do
|
|
14
|
+
# expect(page).to have_content "ValidationSync"
|
|
15
|
+
# end
|
|
16
|
+
|
|
17
|
+
# it "creates an init method for each ActiveRecord model" do
|
|
18
|
+
# expect(page).to have_content "validatePost"
|
|
19
|
+
# expect(page).to have_content "validateUser"
|
|
20
|
+
# end
|
|
21
|
+
|
|
22
|
+
# end # creating a method for each model
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# end # Generating Validation JS
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ValidationSyncFormHelper do
|
|
4
|
+
|
|
5
|
+
describe "Overriding the Form Builder" do
|
|
6
|
+
|
|
7
|
+
it "adds the 'data-sync-validations' attribute to all forms" do
|
|
8
|
+
form = form_for(Post.new) {|p| }
|
|
9
|
+
expect(form).to include "data-sync-validations="
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "defaults to data-sync-validations = false" do
|
|
13
|
+
form = form_for(Post.new) {|p| }
|
|
14
|
+
expect(form).to include 'data-sync-validations="false"'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "allows you to set data-sync-validations = true" do
|
|
18
|
+
form = form_for(Post.new, :validate => true) {|p| }
|
|
19
|
+
expect(form).to include 'data-sync-validations="true"'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end # Overriding the Form Builder
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ValidationBuilder do
|
|
4
|
+
|
|
5
|
+
before :each do
|
|
6
|
+
@builder = ValidationBuilder.new
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
describe "setting default arguments" do
|
|
11
|
+
|
|
12
|
+
it "gives you access to 'object_name' attribute" do
|
|
13
|
+
expect(ValidationBuilder.method_defined?(:object_name)).to be_true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "gives you access to 'method' attribute" do
|
|
17
|
+
expect(ValidationBuilder.method_defined?(:method)).to be_true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
describe "the find_all_models method" do
|
|
24
|
+
|
|
25
|
+
it "returns an array" do
|
|
26
|
+
expect(@builder.find_all_models).to be_a(Array)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "lists all of the app's models by name" do
|
|
30
|
+
post_model = {
|
|
31
|
+
name: "post",
|
|
32
|
+
attributes: ["id","title","content","view_count","author_email","created_at","updated_at","order","user_id"]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
user_model = {
|
|
36
|
+
name: "user",
|
|
37
|
+
attributes: ["id","email","password","created_at","updated_at"]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
expect(@builder.find_all_models).to include post_model
|
|
41
|
+
expect(@builder.find_all_models).to include user_model
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end # the find_all_models method
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
describe "get_model_validation" do
|
|
50
|
+
|
|
51
|
+
it "returns a validation object if a model uses the given validation" do
|
|
52
|
+
# our dummy app validates the presence of Post.title
|
|
53
|
+
check = @builder.get_model_validation("post", :title, ActiveRecord::Validations::PresenceValidator)
|
|
54
|
+
expect(check.class).to eq ActiveRecord::Validations::PresenceValidator
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "makes use of the builder's default arguments" do
|
|
58
|
+
@builder.object_name = "post"
|
|
59
|
+
@builder.method = :title
|
|
60
|
+
# our dummy app validates the presence of Post.title
|
|
61
|
+
check = @builder.get_model_validation(ActiveRecord::Validations::PresenceValidator)
|
|
62
|
+
expect(check.class).to eq ActiveRecord::Validations::PresenceValidator
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "returns nil if a model doesn't use a given validation" do
|
|
66
|
+
# our dummy app does not validate the Numericality of Post.content
|
|
67
|
+
check = @builder.get_model_validation("post", :content, ActiveModel::Validations::NumericalityValidator)
|
|
68
|
+
expect(check).to eq nil
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end # check_model_validation
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
describe "check_model_validation" do
|
|
77
|
+
|
|
78
|
+
it "returns true if a model uses a given validation" do
|
|
79
|
+
# our dummy app validates the presence of Post.title
|
|
80
|
+
check = @builder.check_model_validation("post", :title, ActiveRecord::Validations::PresenceValidator)
|
|
81
|
+
expect(check).to eq true
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "makes use of the builder's default arguments" do
|
|
85
|
+
@builder.object_name = "post"
|
|
86
|
+
@builder.method = :title
|
|
87
|
+
# our dummy app validates the presence of Post.title
|
|
88
|
+
check = @builder.check_model_validation(ActiveRecord::Validations::PresenceValidator)
|
|
89
|
+
expect(check).to eq true
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "returns false if a model doesn't use a given validation" do
|
|
93
|
+
# our dummy app does not validate the Numericality of Post.content
|
|
94
|
+
check = @builder.check_model_validation("post", :content, ActiveModel::Validations::NumericalityValidator)
|
|
95
|
+
expect(check).to eq false
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end # check_model_validation
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
describe "get_validation_attr" do
|
|
104
|
+
|
|
105
|
+
it "returns an validation option's value if that option is present" do
|
|
106
|
+
# our dummy app validates the length of Post.title, :minimum => 5
|
|
107
|
+
check = @builder.get_validation_attr("post", :title, ActiveModel::Validations::LengthValidator, :minimum)
|
|
108
|
+
expect(check).to eq 5
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "makes use of the builder's default arguments" do
|
|
112
|
+
@builder.object_name = "post"
|
|
113
|
+
@builder.method = :title
|
|
114
|
+
# our dummy app validates the length of Post.title, :minimum => 5
|
|
115
|
+
check = @builder.get_validation_attr(ActiveModel::Validations::LengthValidator, :minimum)
|
|
116
|
+
expect(check).to eq 5
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "returns nil if that option is not present" do
|
|
120
|
+
# our dummy app validates the length of Post.title, but not :maximum
|
|
121
|
+
check = @builder.get_validation_attr("post", :title, ActiveModel::Validations::LengthValidator, :maximum)
|
|
122
|
+
expect(check).to eq nil
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "returns nil if that validation is not used at all" do
|
|
126
|
+
# our dummy app does not validate the length of Post.author_email
|
|
127
|
+
check = @builder.get_validation_attr("post", :author_email, ActiveModel::Validations::LengthValidator, :maximum)
|
|
128
|
+
expect(check).to eq nil
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
end # get_validation_attr
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
describe "get_validation_message" do
|
|
137
|
+
|
|
138
|
+
it "returns a custom validation message, if one exists" do
|
|
139
|
+
# our dummy app validates the presence of Post.title with the message "You need a title, bro."
|
|
140
|
+
message = @builder.get_validation_message("post", :title, ActiveRecord::Validations::PresenceValidator)
|
|
141
|
+
expect(message).to eq "You need a title, bro."
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "makes use of the builder's default arguments" do
|
|
145
|
+
@builder.object_name = "post"
|
|
146
|
+
@builder.method = :title
|
|
147
|
+
# our dummy app validates the presence of Post.title with the message "You need a title, bro."
|
|
148
|
+
message = @builder.get_validation_message(ActiveRecord::Validations::PresenceValidator)
|
|
149
|
+
expect(message).to eq "You need a title, bro."
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "returns nil if that validation is not used at all" do
|
|
153
|
+
# our dummy app doesn't validate the presence of Post.author_email
|
|
154
|
+
message = @builder.get_validation_message("post", :author_email, ActiveRecord::Validations::PresenceValidator)
|
|
155
|
+
expect(message).to eq nil
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "returns a default validation message, if a custom message is not defined" do
|
|
159
|
+
# our dummy app validates the presence of Post.content, but provides no custom message
|
|
160
|
+
message = @builder.get_validation_message("post", :content, ActiveRecord::Validations::PresenceValidator)
|
|
161
|
+
expect(message).to eq I18n.t('errors.messages.blank')
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it "returns the default validation message for validates_confirmation_of attributes" do
|
|
165
|
+
# our dummy app validates the confirmation of User.email, but provides no custom message
|
|
166
|
+
message = @builder.get_validation_message("user", :email, ActiveModel::Validations::ConfirmationValidator)
|
|
167
|
+
expect(message).to eq I18n.t('errors.messages.confirmation', attribute: "Email")
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
end # get_validation_message
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
end # ValidationBuilder
|