hoarder-js 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +1 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +100 -0
- data/LICENSE +21 -0
- data/Manifest +42 -0
- data/README.rdoc +0 -0
- data/Rakefile +38 -0
- data/assets/scripts/coffee/hoarder/form/form.coffee +48 -0
- data/assets/scripts/coffee/hoarder/form/form_element.coffee +22 -0
- data/assets/scripts/coffee/hoarder/form_manager.coffee +32 -0
- data/assets/scripts/coffee/hoarder/submitter/form_submitter.coffee +29 -0
- data/assets/scripts/coffee/hoarder/submitter/submitters/polling_submitter.coffee +36 -0
- data/assets/scripts/coffee/hoarder/submitter/submitters/simple_submitter.coffee +30 -0
- data/assets/scripts/coffee/hoarder/validator/constraints/alpha_constraint.coffee +18 -0
- data/assets/scripts/coffee/hoarder/validator/constraints/alphanumeric_constraint.coffee +18 -0
- data/assets/scripts/coffee/hoarder/validator/constraints/credit_card_constraint.coffee +18 -0
- data/assets/scripts/coffee/hoarder/validator/constraints/email_constraint.coffee +18 -0
- data/assets/scripts/coffee/hoarder/validator/constraints/max_length_constraint.coffee +18 -0
- data/assets/scripts/coffee/hoarder/validator/constraints/min_length_constraint.coffee +18 -0
- data/assets/scripts/coffee/hoarder/validator/constraints/numeric_constraint.coffee +18 -0
- data/assets/scripts/coffee/hoarder/validator/constraints/phone_constraint.coffee +18 -0
- data/assets/scripts/coffee/hoarder/validator/constraints/required_constraint.coffee +18 -0
- data/assets/scripts/coffee/hoarder/validator/error/validation_error.coffee +9 -0
- data/assets/scripts/coffee/hoarder/validator/form_validator.coffee +53 -0
- data/assets/scripts/js/lib/jquery.js +5 -0
- data/bin/hoarder.js +1197 -0
- data/config/assets.rb +8 -0
- data/hoarder-js.gemspec +36 -0
- data/lib/hoarder.rb +1 -0
- data/lib/hoarder/symbols.rb +17 -0
- data/spec/jasmine.yml +44 -0
- data/spec/runner.html +75 -0
- data/spec/support/classes.coffee +0 -0
- data/spec/support/helpers.coffee +22 -0
- data/spec/support/mocks.coffee +42 -0
- data/spec/support/objects.coffee +0 -0
- data/spec/support/requirements.coffee +1 -0
- data/spec/tests/form_manager_spec.coffee +43 -0
- data/spec/tests/submitter/form_submitter_spec.coffee +47 -0
- data/spec/tests/submitter/submitters/polling_submitter_spec.coffee +60 -0
- data/spec/tests/submitter/submitters/simple_submitter_spec.coffee +19 -0
- data/spec/tests/validator/constraints_spec.coffee +74 -0
- data/spec/tests/validator/form_validator_spec.coffee +29 -0
- metadata +132 -0
data/config/assets.rb
ADDED
data/hoarder-js.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "hoarder-js"
|
5
|
+
s.version = "0.0.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Tim Shelburne"]
|
9
|
+
s.date = "2013-05-01"
|
10
|
+
s.description = ""
|
11
|
+
s.email = "shelburt02@gmail.com"
|
12
|
+
s.executables = ["hoarder.js"]
|
13
|
+
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.rdoc", "bin/hoarder.js", "lib/hoarder.rb", "lib/hoarder/symbols.rb"]
|
14
|
+
s.files = ["CHANGELOG", "Gemfile", "Gemfile.lock", "LICENSE", "Manifest", "README.rdoc", "Rakefile", "assets/scripts/coffee/hoarder/form/form.coffee", "assets/scripts/coffee/hoarder/form/form_element.coffee", "assets/scripts/coffee/hoarder/form_manager.coffee", "assets/scripts/coffee/hoarder/submitter/form_submitter.coffee", "assets/scripts/coffee/hoarder/submitter/submitters/polling_submitter.coffee", "assets/scripts/coffee/hoarder/submitter/submitters/simple_submitter.coffee", "assets/scripts/coffee/hoarder/validator/constraints/alpha_constraint.coffee", "assets/scripts/coffee/hoarder/validator/constraints/alphanumeric_constraint.coffee", "assets/scripts/coffee/hoarder/validator/constraints/credit_card_constraint.coffee", "assets/scripts/coffee/hoarder/validator/constraints/email_constraint.coffee", "assets/scripts/coffee/hoarder/validator/constraints/max_length_constraint.coffee", "assets/scripts/coffee/hoarder/validator/constraints/min_length_constraint.coffee", "assets/scripts/coffee/hoarder/validator/constraints/numeric_constraint.coffee", "assets/scripts/coffee/hoarder/validator/constraints/phone_constraint.coffee", "assets/scripts/coffee/hoarder/validator/constraints/required_constraint.coffee", "assets/scripts/coffee/hoarder/validator/error/validation_error.coffee", "assets/scripts/coffee/hoarder/validator/form_validator.coffee", "assets/scripts/js/lib/jquery.js", "bin/hoarder.js", "config/assets.rb", "lib/hoarder.rb", "lib/hoarder/symbols.rb", "spec/jasmine.yml", "spec/runner.html", "spec/support/classes.coffee", "spec/support/helpers.coffee", "spec/support/mocks.coffee", "spec/support/objects.coffee", "spec/support/requirements.coffee", "spec/tests/form_manager_spec.coffee", "spec/tests/submitter/form_submitter_spec.coffee", "spec/tests/submitter/submitters/polling_submitter_spec.coffee", "spec/tests/submitter/submitters/simple_submitter_spec.coffee", "spec/tests/validator/constraints_spec.coffee", "spec/tests/validator/form_validator_spec.coffee", "hoarder-js.gemspec"]
|
15
|
+
s.homepage = "https://github.com/tshelburne/hoarder-js"
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Hoarder-js", "--main", "README.rdoc"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = "hoarder-js"
|
19
|
+
s.rubygems_version = "1.8.24"
|
20
|
+
s.summary = ""
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
s.specification_version = 3
|
24
|
+
|
25
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
26
|
+
s.add_development_dependency(%q<jasmine>, [">= 0"])
|
27
|
+
s.add_development_dependency(%q<jasmine-headless-webkit>, [">= 0"])
|
28
|
+
else
|
29
|
+
s.add_dependency(%q<jasmine>, [">= 0"])
|
30
|
+
s.add_dependency(%q<jasmine-headless-webkit>, [">= 0"])
|
31
|
+
end
|
32
|
+
else
|
33
|
+
s.add_dependency(%q<jasmine>, [">= 0"])
|
34
|
+
s.add_dependency(%q<jasmine-headless-webkit>, [">= 0"])
|
35
|
+
end
|
36
|
+
end
|
data/lib/hoarder.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "hoarder/symbols"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "keystone"
|
2
|
+
|
3
|
+
module Hoarder
|
4
|
+
|
5
|
+
def self.pipeline
|
6
|
+
@@pipeline ||= ::Keystone.bootstrap("#{root_path}/config/assets.rb")
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.keystone_compiler
|
10
|
+
@@keystone_compiler ||= pipeline.compiler("hoarder.js")
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.root_path
|
14
|
+
File.expand_path("#{File.dirname(__FILE__)}/../../")
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
data/spec/jasmine.yml
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
runner_output: "spec/runner.html"
|
2
|
+
|
3
|
+
# src_files
|
4
|
+
#
|
5
|
+
# Return an array of filepaths relative to src_dir to include before jasmine specs.
|
6
|
+
# Default: []
|
7
|
+
src_files:
|
8
|
+
- bin/*.js
|
9
|
+
|
10
|
+
# stylesheets
|
11
|
+
#
|
12
|
+
# Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs.
|
13
|
+
# Default: []
|
14
|
+
stylesheets:
|
15
|
+
|
16
|
+
# helpers
|
17
|
+
#
|
18
|
+
# Return an array of filepaths relative to spec_dir to include before jasmine specs.
|
19
|
+
# Default: ["helpers/**/*.js"]
|
20
|
+
helpers:
|
21
|
+
- support/requirements.coffee
|
22
|
+
- support/helpers.coffee
|
23
|
+
- support/objects.coffee
|
24
|
+
- support/classes.coffee
|
25
|
+
- support/mocks.coffee
|
26
|
+
|
27
|
+
# spec_files
|
28
|
+
#
|
29
|
+
# Return an array of filepaths relative to spec_dir to include.
|
30
|
+
# Default: ["**/*[sS]pec.js"]
|
31
|
+
spec_files:
|
32
|
+
- ./**/*_spec.coffee
|
33
|
+
|
34
|
+
# src_dir
|
35
|
+
#
|
36
|
+
# Source directory path. Your src_files must be returned relative to this path. Will use root if left blank.
|
37
|
+
# Default: project root
|
38
|
+
src_dir:
|
39
|
+
|
40
|
+
# spec_dir
|
41
|
+
#
|
42
|
+
# Spec directory path. Your spec_files must be returned relative to this path.
|
43
|
+
# Default: spec/javascripts
|
44
|
+
spec_dir: spec
|
data/spec/runner.html
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
|
5
|
+
<title>Jasmine Test Runner - Generated by jasmine-headless-webkit</title>
|
6
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/prolog.js"></script>
|
7
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/vendor/ruby/1.9.1/gems/jasmine-core-1.3.1/lib/jasmine-core/jasmine.js"></script>
|
8
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/vendor/ruby/1.9.1/gems/jasmine-core-1.3.1/lib/jasmine-core/jasmine-html.js"></script>
|
9
|
+
<link rel="stylesheet" href="/Users/tshelburne/Sites/dontlook/jslib/hoarder/vendor/ruby/1.9.1/gems/jasmine-core-1.3.1/lib/jasmine-core/jasmine.css" type="text/css" />
|
10
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/jasmine-extensions.js"></script>
|
11
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/intense.js"></script>
|
12
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/headless_reporter_result.js"></script>
|
13
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/jasmine.HeadlessConsoleReporter.js"></script>
|
14
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/jsDump.js"></script>
|
15
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/beautify-html.js"></script>
|
16
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/bin/hoarder.js"></script>
|
17
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/.jhw-cache/coffee_script/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/support/requirements.coffee.js"></script>
|
18
|
+
<script type="text/javascript">window.CSTF['requirements.coffee.js'] = '/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/support/requirements.coffee';</script>
|
19
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/.jhw-cache/coffee_script/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/support/helpers.coffee.js"></script>
|
20
|
+
<script type="text/javascript">window.CSTF['helpers.coffee.js'] = '/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/support/helpers.coffee';</script>
|
21
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/.jhw-cache/coffee_script/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/support/objects.coffee.js"></script>
|
22
|
+
<script type="text/javascript">window.CSTF['objects.coffee.js'] = '/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/support/objects.coffee';</script>
|
23
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/.jhw-cache/coffee_script/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/support/classes.coffee.js"></script>
|
24
|
+
<script type="text/javascript">window.CSTF['classes.coffee.js'] = '/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/support/classes.coffee';</script>
|
25
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/.jhw-cache/coffee_script/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/support/mocks.coffee.js"></script>
|
26
|
+
<script type="text/javascript">window.CSTF['mocks.coffee.js'] = '/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/support/mocks.coffee';</script>
|
27
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/.jhw-cache/coffee_script/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/submitter/submitters/polling_submitter_spec.coffee.js"></script>
|
28
|
+
<script type="text/javascript">window.CSTF['polling_submitter_spec.coffee.js'] = '/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/submitter/submitters/polling_submitter_spec.coffee';</script>
|
29
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/.jhw-cache/coffee_script/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/form_manager_spec.coffee.js"></script>
|
30
|
+
<script type="text/javascript">window.CSTF['form_manager_spec.coffee.js'] = '/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/form_manager_spec.coffee';</script>
|
31
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/.jhw-cache/coffee_script/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/submitter/submitters/simple_submitter_spec.coffee.js"></script>
|
32
|
+
<script type="text/javascript">window.CSTF['simple_submitter_spec.coffee.js'] = '/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/submitter/submitters/simple_submitter_spec.coffee';</script>
|
33
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/.jhw-cache/coffee_script/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/submitter/form_submitter_spec.coffee.js"></script>
|
34
|
+
<script type="text/javascript">window.CSTF['form_submitter_spec.coffee.js'] = '/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/submitter/form_submitter_spec.coffee';</script>
|
35
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/.jhw-cache/coffee_script/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/validator/constraints_spec.coffee.js"></script>
|
36
|
+
<script type="text/javascript">window.CSTF['constraints_spec.coffee.js'] = '/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/validator/constraints_spec.coffee';</script>
|
37
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/dontlook/jslib/hoarder/.jhw-cache/coffee_script/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/validator/form_validator_spec.coffee.js"></script>
|
38
|
+
<script type="text/javascript">window.CSTF['form_validator_spec.coffee.js'] = '/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/validator/form_validator_spec.coffee';</script>
|
39
|
+
<script type="text/javascript">
|
40
|
+
if (window.JHW) { HeadlessReporterResult.specLineNumbers = {"/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/submitter/submitters/polling_submitter_spec.coffee":{"PollingSubmitter":[3],"can initiate a poll upon successful submission of a form":[9],"can respond to a successful poll check":[15],"can poll with the given frequency":[21],"will stop polling after receiving a pollCompleted message":[38],"can respond to an error-ridden polling form submission":[50],"can respond to an error-ridden poll check":[56]},"/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/form_manager_spec.coffee":{"FormManager":[3],"when working with the FormValidator":[9],"can validate forms":[10],"and the FormSubmitter":[16],"can return validation errors when submitting a form":[28],"can submit a form and relay a success message":[33],"can submit a form and relay an error message":[39]},"/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/submitter/submitters/simple_submitter_spec.coffee":{"SimpleSubmitter":[3],"can submit a form, and respond to a successful submit":[9],"can respond to an error-ridden submission":[15]},"/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/submitter/form_submitter_spec.coffee":{"FormSubmitter":[3],"can successfully submit a simple form":[17],"can relay errors on a simple form submission":[23],"can successfully submit a polling form":[29],"can relay errors on a polling form submission":[36],"can relay errors on a polling check submission":[42]},"/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/validator/constraints_spec.coffee":{"Validator Constraints":[13],"can require that a value be alphanumeric only":[14],"can require that a value be a valid credit card number":[21],"can require that a value be a valid email address":[28],"can require that a value have a maximum length":[35],"can require that a value have a minimum length":[44],"can require that a value be numeric only":[53],"can require that a value be a valid phone number":[60],"can require that a value be required":[67]},"/Users/tshelburne/Sites/dontlook/jslib/hoarder/spec/tests/validator/form_validator_spec.coffee":{"FormValidator":[4],"can validate an element":[12],"can validate a form":[25]}}; }
|
41
|
+
</script>
|
42
|
+
</head>
|
43
|
+
<body>
|
44
|
+
<script type="text/javascript">
|
45
|
+
jasmine.getEnv().console = {
|
46
|
+
log: function(msg) { JHW.stdout.puts(msg) }
|
47
|
+
}
|
48
|
+
|
49
|
+
window._onload = window.onload;
|
50
|
+
|
51
|
+
window.onload = function() {
|
52
|
+
if (window._onload && (window._onload != window.onload)) {
|
53
|
+
window._onload();
|
54
|
+
}
|
55
|
+
|
56
|
+
if (window.JHW) {
|
57
|
+
jasmine.getEnv().addReporter(new jasmine.HeadlessConsoleReporter());
|
58
|
+
} else {
|
59
|
+
types = [ 'HtmlReporter', 'TrivialReporter' ];
|
60
|
+
|
61
|
+
for (var i = 0, j = types.length; i < j; ++i) {
|
62
|
+
var type = jasmine[types[i]]
|
63
|
+
if (type) {
|
64
|
+
jasmine.getEnv().addReporter(new type());
|
65
|
+
break;
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
jasmine.getEnv().execute();
|
71
|
+
}
|
72
|
+
</script>
|
73
|
+
</body>
|
74
|
+
</html>
|
75
|
+
|
File without changes
|
@@ -0,0 +1,22 @@
|
|
1
|
+
(exports ? this).globalize = (fxn, name=null)=>
|
2
|
+
functionName = if name is null then fxn.name else name
|
3
|
+
(exports ? this)[functionName] = fxn
|
4
|
+
|
5
|
+
|
6
|
+
# MOCKING #
|
7
|
+
(exports ? this).mocks = {}
|
8
|
+
|
9
|
+
(exports ? this).addMock = (name, obj)=>
|
10
|
+
(exports ? this).mocks[name] = obj
|
11
|
+
|
12
|
+
|
13
|
+
# RUNTIME PATCHING #
|
14
|
+
(exports ? this).patches = {}
|
15
|
+
|
16
|
+
(exports ? this).patch = (method, patch)=>
|
17
|
+
(exports ? this).patches[method.name] = method
|
18
|
+
method = patch
|
19
|
+
|
20
|
+
(exports ? this).restore = (method)=>
|
21
|
+
method = (exports ? this).patches[method.name]
|
22
|
+
delete (exports ? this).patches[method.name]
|
@@ -0,0 +1,42 @@
|
|
1
|
+
addMock "submitSimpleFormResponse",
|
2
|
+
status: "success"
|
3
|
+
|
4
|
+
addMock "submitPollingFormResponse",
|
5
|
+
pollId: "1234"
|
6
|
+
|
7
|
+
addMock "submitFormPollingCheckResponse",
|
8
|
+
pollCompleted: true
|
9
|
+
pollData:
|
10
|
+
success: true
|
11
|
+
countdownTime: 300
|
12
|
+
|
13
|
+
addMock "submitFormPollingCheckFailedResponse",
|
14
|
+
pollCompleted: false
|
15
|
+
|
16
|
+
addMock "simpleForm",
|
17
|
+
type: "simple"
|
18
|
+
action: "/submit-simple-form"
|
19
|
+
method: "POST"
|
20
|
+
elements: -> [
|
21
|
+
{ name: "street1", value: "123 Duval", validationRules: [ "required", "alphanumeric"], addError: -> }
|
22
|
+
{ name: "street2", value: "", validationRules: [ "alphanumeric" ], addError: -> }
|
23
|
+
{ name: "city", value: "Austin", validationRules: [ "required" ], addError: -> }
|
24
|
+
{ name: "state", value: "TX", validationRules: [ "required" ], addError: -> }
|
25
|
+
{ name: "zipCode", value: "78753", validationRules: [ "required", "numeric", "maxLength=5", "minLength=5" ], addError: -> }
|
26
|
+
]
|
27
|
+
serialize: -> "street1=123 Duval&street2=&city=Austin&state=TX&zipCode=78753"
|
28
|
+
|
29
|
+
addMock "pollingForm",
|
30
|
+
type: "polling"
|
31
|
+
action: "/submit-polling-form"
|
32
|
+
method: "POST"
|
33
|
+
serialize: -> "products[1234]=2&products[2345]=3"
|
34
|
+
|
35
|
+
addMock "invalidForm",
|
36
|
+
elements: -> [
|
37
|
+
{ name: "street1", value: "$$$#", validationRules: [ "required", "alphanumeric"], addError: -> }
|
38
|
+
{ name: "street2", value: "", validationRules: [ "alphanumeric" ], addError: -> }
|
39
|
+
{ name: "city", value: "", validationRules: [ "required" ], addError: -> }
|
40
|
+
{ name: "state", value: "", validationRules: [ "required" ], addError: -> }
|
41
|
+
{ name: "zipCode", value: "asdf", validationRules: [ "required", "numeric", "maxLength=5", "minLength=5" ], addError: -> }
|
42
|
+
]
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'lib/jquery'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
FormManager = require "hoarder/form_manager"
|
2
|
+
|
3
|
+
describe "FormManager", ->
|
4
|
+
manager = null
|
5
|
+
|
6
|
+
beforeEach ->
|
7
|
+
manager = FormManager.default()
|
8
|
+
|
9
|
+
describe "when working with the FormValidator", ->
|
10
|
+
it "can validate forms", ->
|
11
|
+
errors = manager.validateForm(mocks.simpleForm)
|
12
|
+
expect(errors.length).toEqual 0
|
13
|
+
errors = manager.validateForm(mocks.invalidForm)
|
14
|
+
expect(errors.length).toEqual 4
|
15
|
+
|
16
|
+
describe "and the FormSubmitter", ->
|
17
|
+
response = null
|
18
|
+
success = (form, data)->
|
19
|
+
response = { form: form, data: data }
|
20
|
+
error = (form, text)->
|
21
|
+
response = { form: form, text: text }
|
22
|
+
|
23
|
+
beforeEach ->
|
24
|
+
response = null
|
25
|
+
manager.submittedWithSuccess.add(success)
|
26
|
+
manager.submittedWithError.add(error)
|
27
|
+
|
28
|
+
it "can return validation errors when submitting a form", ->
|
29
|
+
spyOn(manager.validatedWithErrors, "dispatch")
|
30
|
+
manager.submitForm mocks.invalidForm
|
31
|
+
expect(manager.validatedWithErrors.dispatch).toHaveBeenCalled()
|
32
|
+
|
33
|
+
it "can submit a form and relay a success message", ->
|
34
|
+
spyOn(manager.formSubmitter, "submitForm").andCallFake (form)-> @submittedWithSuccess.dispatch(form, "success")
|
35
|
+
manager.submitForm mocks.simpleForm
|
36
|
+
expect(response.form).toBe mocks.simpleForm
|
37
|
+
expect(response.data).toEqual "success"
|
38
|
+
|
39
|
+
it "can submit a form and relay an error message", ->
|
40
|
+
spyOn(manager.formSubmitter, "submitForm").andCallFake (form)-> @submittedWithError.dispatch(form, "error")
|
41
|
+
manager.submitForm mocks.simpleForm
|
42
|
+
expect(response.form).toBe mocks.simpleForm
|
43
|
+
expect(response.text).toEqual "error"
|
@@ -0,0 +1,47 @@
|
|
1
|
+
FormSubmitter = require "hoarder/submitter/form_submitter"
|
2
|
+
|
3
|
+
describe "FormSubmitter", ->
|
4
|
+
formSubmitter = null
|
5
|
+
response = null
|
6
|
+
success = (form, data)->
|
7
|
+
response = { form : form, data : data }
|
8
|
+
error = (form, text)->
|
9
|
+
response = { form : form, text : text }
|
10
|
+
|
11
|
+
beforeEach ->
|
12
|
+
response = null
|
13
|
+
formSubmitter = FormSubmitter.default("http://mydomain.com/my/polling/url")
|
14
|
+
formSubmitter.submittedWithSuccess.add(success)
|
15
|
+
formSubmitter.submittedWithError.add(error)
|
16
|
+
|
17
|
+
it "can successfully submit a simple form", ->
|
18
|
+
spyOn(formSubmitter.submitters[0], "submitForm").andCallFake (form)-> @submitSuccess(form, "simple")
|
19
|
+
formSubmitter.submitForm mocks.simpleForm
|
20
|
+
expect(response.form).toBe mocks.simpleForm
|
21
|
+
expect(response.data).toEqual "simple"
|
22
|
+
|
23
|
+
it "can relay errors on a simple form submission", ->
|
24
|
+
spyOn(formSubmitter.submitters[0], "submitForm").andCallFake (form)-> @submitError(form, {}, "simple error")
|
25
|
+
formSubmitter.submitForm mocks.simpleForm
|
26
|
+
expect(response.form).toBe mocks.simpleForm
|
27
|
+
expect(response.text).toEqual "simple error"
|
28
|
+
|
29
|
+
it "can successfully submit a polling form", ->
|
30
|
+
spyOn(formSubmitter.submitters[1], "submitForm").andCallFake (form)-> @submitSuccess(form, { pollId: "1234" })
|
31
|
+
spyOn(formSubmitter.submitters[1], "queryPoll").andCallFake (form, pollId)-> @pollSuccess(form, pollId, { pollCompleted: true, pollData: "polling" })
|
32
|
+
formSubmitter.submitForm mocks.pollingForm
|
33
|
+
expect(response.form).toBe mocks.pollingForm
|
34
|
+
expect(response.data).toEqual "polling"
|
35
|
+
|
36
|
+
it "can relay errors on a polling form submission", ->
|
37
|
+
spyOn(formSubmitter.submitters[1], "submitForm").andCallFake (form)-> @submitError(form, {}, "polling error")
|
38
|
+
formSubmitter.submitForm mocks.pollingForm
|
39
|
+
expect(response.form).toBe mocks.pollingForm
|
40
|
+
expect(response.text).toEqual "polling error"
|
41
|
+
|
42
|
+
it "can relay errors on a polling check submission", ->
|
43
|
+
spyOn(formSubmitter.submitters[1], "submitForm").andCallFake (form)-> @submitSuccess(form, { pollId: "1234" })
|
44
|
+
spyOn(formSubmitter.submitters[1], "queryPoll").andCallFake (form, pollId)-> @submitError(form, {}, "polling error")
|
45
|
+
formSubmitter.submitForm mocks.pollingForm
|
46
|
+
expect(response.form).toBe mocks.pollingForm
|
47
|
+
expect(response.text).toEqual "polling error"
|
@@ -0,0 +1,60 @@
|
|
1
|
+
PollingSubmitter = require "hoarder/submitter/submitters/polling_submitter"
|
2
|
+
|
3
|
+
describe "PollingSubmitter", ->
|
4
|
+
submitter = null
|
5
|
+
|
6
|
+
beforeEach ->
|
7
|
+
submitter = new PollingSubmitter("/poll-check-form-submit", 500)
|
8
|
+
|
9
|
+
it "can initiate a poll upon successful submission of a form", ->
|
10
|
+
spyOn($, "ajax").andCallFake( (params)-> params.success(mocks.submitPollingFormResponse))
|
11
|
+
spyOn(submitter, "queryPoll")
|
12
|
+
submitter.submitForm(mocks.pollingForm)
|
13
|
+
expect(submitter.queryPoll).toHaveBeenCalledWith(mocks.pollingForm, "1234")
|
14
|
+
|
15
|
+
it "can respond to a successful poll check", ->
|
16
|
+
spyOn($, "ajax").andCallFake( (params)-> params.success(mocks.submitFormPollingCheckResponse))
|
17
|
+
spyOn(submitter.submittedWithSuccess, "dispatch")
|
18
|
+
submitter.queryPoll(mocks.pollingForm, "1234")
|
19
|
+
expect(submitter.submittedWithSuccess.dispatch).toHaveBeenCalledWith(mocks.pollingForm, mocks.submitFormPollingCheckResponse.pollData)
|
20
|
+
|
21
|
+
it "can poll with the given frequency", ->
|
22
|
+
jasmine.Clock.useMock()
|
23
|
+
spyOn($, "ajax").andCallFake( (params)=> if $.ajax.calls.length < 3 then params.success(mocks.submitFormPollingCheckFailedResponse) else params.success(mocks.submitFormPollingCheckResponse))
|
24
|
+
spyOn(submitter, "queryPoll").andCallThrough()
|
25
|
+
spyOn(submitter.submittedWithSuccess, "dispatch")
|
26
|
+
spyOn(submitter.submittedWithError, "dispatch")
|
27
|
+
submitter.submitSuccess(mocks.pollingForm, { pollId:"1234" })
|
28
|
+
expect(submitter.submittedWithSuccess.dispatch).not.toHaveBeenCalled()
|
29
|
+
expect(submitter.submittedWithError.dispatch).not.toHaveBeenCalled()
|
30
|
+
expect(submitter.queryPoll.calls.length).toEqual 1
|
31
|
+
jasmine.Clock.tick 501
|
32
|
+
expect(submitter.submittedWithSuccess.dispatch).not.toHaveBeenCalled()
|
33
|
+
expect(submitter.submittedWithError.dispatch).not.toHaveBeenCalled()
|
34
|
+
expect(submitter.queryPoll.calls.length).toEqual 2
|
35
|
+
jasmine.Clock.tick 501
|
36
|
+
expect(submitter.submittedWithSuccess.dispatch).toHaveBeenCalledWith(mocks.pollingForm, mocks.submitFormPollingCheckResponse.pollData)
|
37
|
+
|
38
|
+
it "will stop polling after receiving a pollCompleted message", ->
|
39
|
+
jasmine.Clock.useMock()
|
40
|
+
spyOn($, "ajax").andCallFake( (params)-> params.success(mocks.submitFormPollingCheckResponse))
|
41
|
+
spyOn(submitter, "queryPoll").andCallThrough()
|
42
|
+
spyOn(submitter.submittedWithSuccess, "dispatch")
|
43
|
+
spyOn(submitter.submittedWithError, "dispatch")
|
44
|
+
submitter.submitSuccess(mocks.pollingForm, { pollId:"1234" })
|
45
|
+
expect(submitter.submittedWithSuccess.dispatch).toHaveBeenCalledWith(mocks.pollingForm, mocks.submitFormPollingCheckResponse.pollData)
|
46
|
+
expect(submitter.submittedWithSuccess.dispatch.calls.length).toEqual 1
|
47
|
+
jasmine.Clock.tick 501
|
48
|
+
expect(submitter.submittedWithSuccess.dispatch.calls.length).toEqual 1
|
49
|
+
|
50
|
+
it "can respond to an error-ridden polling form submission", ->
|
51
|
+
spyOn($, "ajax").andCallFake( (params)-> params.error({}, "Error!"))
|
52
|
+
spyOn(submitter.submittedWithError, "dispatch")
|
53
|
+
submitter.submitForm(mocks.pollingForm)
|
54
|
+
expect(submitter.submittedWithError.dispatch).toHaveBeenCalledWith(mocks.pollingForm, "Error!" )
|
55
|
+
|
56
|
+
it "can respond to an error-ridden poll check", ->
|
57
|
+
spyOn($, "ajax").andCallFake( (params)-> params.error({}, "Error!"))
|
58
|
+
spyOn(submitter.submittedWithError, "dispatch")
|
59
|
+
submitter.queryPoll(mocks.pollingForm, "1234")
|
60
|
+
expect(submitter.submittedWithError.dispatch).toHaveBeenCalledWith(mocks.pollingForm, "Error!" )
|
@@ -0,0 +1,19 @@
|
|
1
|
+
SimpleSubmitter = require "hoarder/submitter/submitters/simple_submitter"
|
2
|
+
|
3
|
+
describe "SimpleSubmitter", ->
|
4
|
+
submitter = null
|
5
|
+
|
6
|
+
beforeEach ->
|
7
|
+
submitter = new SimpleSubmitter()
|
8
|
+
|
9
|
+
it "can submit a form, and respond to a successful submit", ->
|
10
|
+
spyOn(submitter.submittedWithSuccess, "dispatch")
|
11
|
+
spyOn($,"ajax").andCallFake( (params)-> params.success(mocks.submitSimpleFormResponse))
|
12
|
+
submitter.submitForm(mocks.simpleForm)
|
13
|
+
expect(submitter.submittedWithSuccess.dispatch).toHaveBeenCalledWith(mocks.simpleForm, mocks.submitSimpleFormResponse)
|
14
|
+
|
15
|
+
it "can respond to an error-ridden submission", ->
|
16
|
+
spyOn($, "ajax").andCallFake( (params)-> params.error({}, "Error!"))
|
17
|
+
spyOn(submitter.submittedWithError, "dispatch")
|
18
|
+
submitter.submitForm(mocks.simpleForm)
|
19
|
+
expect(submitter.submittedWithError.dispatch).toHaveBeenCalledWith(mocks.simpleForm, "Error!" )
|
@@ -0,0 +1,74 @@
|
|
1
|
+
FormElement = require 'hoarder/form/form_element'
|
2
|
+
|
3
|
+
#AlphaConstraint = require "/hoarder/validator/constraints/alpha_constraint"
|
4
|
+
AlphanumericConstraint = require "hoarder/validator/constraints/alphanumeric_constraint"
|
5
|
+
CreditCardConstraint = require "hoarder/validator/constraints/credit_card_constraint"
|
6
|
+
EmailConstraint = require "hoarder/validator/constraints/email_constraint"
|
7
|
+
MaxLengthConstraint = require "hoarder/validator/constraints/max_length_constraint"
|
8
|
+
MinLengthConstraint = require "hoarder/validator/constraints/min_length_constraint"
|
9
|
+
NumericConstraint = require "hoarder/validator/constraints/numeric_constraint"
|
10
|
+
PhoneConstraint = require "hoarder/validator/constraints/phone_constraint"
|
11
|
+
RequiredConstraint = require "hoarder/validator/constraints/required_constraint"
|
12
|
+
|
13
|
+
describe "Validator Constraints", ->
|
14
|
+
it "can require that a value be alphanumeric only", ->
|
15
|
+
constraint = new AlphanumericConstraint()
|
16
|
+
validElement = new FormElement("fullName", "71m5h3lburn3")
|
17
|
+
invalidElement = new FormElement("fullName", "T!m $h3lbur*3")
|
18
|
+
expect(constraint.handle(validElement)).toEqual []
|
19
|
+
expect(constraint.handle(invalidElement)[0].message).toEqual "This field only accepts numbers and characters (0-9, A-Z, a-z)."
|
20
|
+
|
21
|
+
it "can require that a value be a valid credit card number", ->
|
22
|
+
constraint = new CreditCardConstraint()
|
23
|
+
validElement = new FormElement("number", "4111111111111111")
|
24
|
+
invalidElement = new FormElement("number", "12345")
|
25
|
+
expect(constraint.handle(validElement)).toEqual []
|
26
|
+
expect(constraint.handle(invalidElement)[0].message).toEqual "Please enter a valid credit card number."
|
27
|
+
|
28
|
+
it "can require that a value be a valid email address", ->
|
29
|
+
constraint = new EmailConstraint()
|
30
|
+
validElement = new FormElement("email", "tim@musiconelive.com")
|
31
|
+
invalidElement = new FormElement("email", "tim she@d")
|
32
|
+
expect(constraint.handle(validElement)).toEqual []
|
33
|
+
expect(constraint.handle(invalidElement)[0].message).toEqual "Please enter a valid email address."
|
34
|
+
|
35
|
+
it "can require that a value have a maximum length", ->
|
36
|
+
constraint = new MaxLengthConstraint()
|
37
|
+
validElement = new FormElement("zipCode", "78765")
|
38
|
+
validElementTwo = new FormElement("zipCode", "787")
|
39
|
+
invalidElement = new FormElement("zipCode", "787657")
|
40
|
+
expect(constraint.handle(validElement, { value: 5 })).toEqual []
|
41
|
+
expect(constraint.handle(validElementTwo, { value: 5 })).toEqual []
|
42
|
+
expect(constraint.handle(invalidElement, { value: 5 })[0].message).toEqual "The maximum length of this field is 5."
|
43
|
+
|
44
|
+
it "can require that a value have a minimum length", ->
|
45
|
+
constraint = new MinLengthConstraint()
|
46
|
+
validElement = new FormElement("zipCode", "78765")
|
47
|
+
validElementTwo = new FormElement("zipCode", "787643")
|
48
|
+
invalidElement = new FormElement("zipCode", "787")
|
49
|
+
expect(constraint.handle(validElement, { value: 5 })).toEqual []
|
50
|
+
expect(constraint.handle(validElementTwo, { value: 5 })).toEqual []
|
51
|
+
expect(constraint.handle(invalidElement, { value: 5 })[0].message).toEqual "The minimum length of this field is 5."
|
52
|
+
|
53
|
+
it "can require that a value be numeric only", ->
|
54
|
+
constraint = new NumericConstraint()
|
55
|
+
validElement = new FormElement("zipCode", "78765")
|
56
|
+
invalidElement = new FormElement("zipCode", "Seven8765")
|
57
|
+
expect(constraint.handle(validElement)).toEqual []
|
58
|
+
expect(constraint.handle(invalidElement)[0].message).toEqual "This field only accepts numbers (0-9)."
|
59
|
+
|
60
|
+
it "can require that a value be a valid phone number", ->
|
61
|
+
constraint = new PhoneConstraint()
|
62
|
+
validElement = new FormElement("phone", "(555)555-5555")
|
63
|
+
invalidElement = new FormElement("phone", "12341")
|
64
|
+
expect(constraint.handle(validElement)).toEqual []
|
65
|
+
expect(constraint.handle(invalidElement)[0].message).toEqual "Please enter a valid phone number."
|
66
|
+
|
67
|
+
it "can require that a value be required", ->
|
68
|
+
constraint = new RequiredConstraint()
|
69
|
+
validElement = new FormElement("fullName", "Tim Shelburne")
|
70
|
+
invalidElement = new FormElement("fullName", "")
|
71
|
+
invalidElementTwo = new FormElement("fullName", null)
|
72
|
+
expect(constraint.handle(validElement)).toEqual []
|
73
|
+
expect(constraint.handle(invalidElement)[0].message).toEqual "This field is required."
|
74
|
+
expect(constraint.handle(invalidElementTwo)[0].message).toEqual "This field is required."
|