client_side_validations 0.8.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,210 +0,0 @@
1
-
2
- // JSpec - XHR - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
3
-
4
- (function(){
5
-
6
- var lastRequest
7
-
8
- // --- Original XMLHttpRequest
9
-
10
- var OriginalXMLHttpRequest = 'XMLHttpRequest' in this ?
11
- XMLHttpRequest :
12
- function(){}
13
- var OriginalActiveXObject = 'ActiveXObject' in this ?
14
- ActiveXObject :
15
- undefined
16
-
17
- // --- MockXMLHttpRequest
18
-
19
- var MockXMLHttpRequest = function() {
20
- this.requestHeaders = {}
21
- }
22
-
23
- MockXMLHttpRequest.prototype = {
24
- status: 0,
25
- async: true,
26
- readyState: 0,
27
- responseXML: null,
28
- responseText: '',
29
- abort: function(){},
30
- onreadystatechange: function(){},
31
-
32
- /**
33
- * Return response headers hash.
34
- */
35
-
36
- getAllResponseHeaders : function(){
37
- return JSpec.inject(this.responseHeaders, '', function(buf, key, val){
38
- return buf + key + ': ' + val + '\r\n'
39
- })
40
- },
41
-
42
- /**
43
- * Return case-insensitive value for header _name_.
44
- */
45
-
46
- getResponseHeader : function(name) {
47
- return this.responseHeaders[name.toLowerCase()]
48
- },
49
-
50
- /**
51
- * Set case-insensitive _value_ for header _name_.
52
- */
53
-
54
- setRequestHeader : function(name, value) {
55
- this.requestHeaders[name.toLowerCase()] = value
56
- },
57
-
58
- /**
59
- * Open mock request.
60
- */
61
-
62
- open : function(method, url, async, user, password) {
63
- this.user = user
64
- this.password = password
65
- this.url = url
66
- this.readyState = 1
67
- this.method = method.toUpperCase()
68
- if (async != undefined) this.async = async
69
- if (this.async) this.onreadystatechange()
70
- },
71
-
72
- /**
73
- * Send request _data_.
74
- */
75
-
76
- send : function(data) {
77
- var self = this
78
- this.data = data
79
- this.readyState = 4
80
- if (this.method == 'HEAD') this.responseText = null
81
- this.responseHeaders['content-length'] = (this.responseText || '').length
82
- if(this.async) this.onreadystatechange()
83
- this.populateResponseXML()
84
- lastRequest = function(){
85
- return self
86
- }
87
- },
88
-
89
- /**
90
- * Parse request body and populate responseXML if response-type is xml
91
- * Based on the standard specification : http://www.w3.org/TR/XMLHttpRequest/
92
- */
93
- populateResponseXML: function() {
94
- var type = this.getResponseHeader("content-type")
95
- if (!type || !this.responseText || !type.match(/(text\/xml|application\/xml|\+xml$)/g))
96
- return
97
- this.responseXML = JSpec.parseXML(this.responseText)
98
- }
99
- }
100
-
101
- // --- Response status codes
102
-
103
- JSpec.statusCodes = {
104
- 100: 'Continue',
105
- 101: 'Switching Protocols',
106
- 200: 'OK',
107
- 201: 'Created',
108
- 202: 'Accepted',
109
- 203: 'Non-Authoritative Information',
110
- 204: 'No Content',
111
- 205: 'Reset Content',
112
- 206: 'Partial Content',
113
- 300: 'Multiple Choice',
114
- 301: 'Moved Permanently',
115
- 302: 'Found',
116
- 303: 'See Other',
117
- 304: 'Not Modified',
118
- 305: 'Use Proxy',
119
- 307: 'Temporary Redirect',
120
- 400: 'Bad Request',
121
- 401: 'Unauthorized',
122
- 402: 'Payment Required',
123
- 403: 'Forbidden',
124
- 404: 'Not Found',
125
- 405: 'Method Not Allowed',
126
- 406: 'Not Acceptable',
127
- 407: 'Proxy Authentication Required',
128
- 408: 'Request Timeout',
129
- 409: 'Conflict',
130
- 410: 'Gone',
131
- 411: 'Length Required',
132
- 412: 'Precondition Failed',
133
- 413: 'Request Entity Too Large',
134
- 414: 'Request-URI Too Long',
135
- 415: 'Unsupported Media Type',
136
- 416: 'Requested Range Not Satisfiable',
137
- 417: 'Expectation Failed',
138
- 422: 'Unprocessable Entity',
139
- 500: 'Internal Server Error',
140
- 501: 'Not Implemented',
141
- 502: 'Bad Gateway',
142
- 503: 'Service Unavailable',
143
- 504: 'Gateway Timeout',
144
- 505: 'HTTP Version Not Supported'
145
- }
146
-
147
- /**
148
- * Mock XMLHttpRequest requests.
149
- *
150
- * mockRequest().and_return('some data', 'text/plain', 200, { 'X-SomeHeader' : 'somevalue' })
151
- *
152
- * @return {hash}
153
- * @api public
154
- */
155
-
156
- function mockRequest() {
157
- return { and_return : function(body, type, status, headers) {
158
- XMLHttpRequest = MockXMLHttpRequest
159
- ActiveXObject = false
160
- status = status || 200
161
- headers = headers || {}
162
- headers['content-type'] = type
163
- JSpec.extend(XMLHttpRequest.prototype, {
164
- responseText: body,
165
- responseHeaders: headers,
166
- status: status,
167
- statusText: JSpec.statusCodes[status]
168
- })
169
- }}
170
- }
171
-
172
- /**
173
- * Unmock XMLHttpRequest requests.
174
- *
175
- * @api public
176
- */
177
-
178
- function unmockRequest() {
179
- XMLHttpRequest = OriginalXMLHttpRequest
180
- ActiveXObject = OriginalActiveXObject
181
- }
182
-
183
- JSpec.include({
184
- name: 'Mock XHR',
185
-
186
- // --- Utilities
187
-
188
- utilities : {
189
- mockRequest: mockRequest,
190
- unmockRequest: unmockRequest
191
- },
192
-
193
- // --- Hooks
194
-
195
- afterSpec : function() {
196
- unmockRequest()
197
- },
198
-
199
- // --- DSLs
200
-
201
- DSLs : {
202
- snake : {
203
- mock_request: mockRequest,
204
- unmock_request: unmockRequest,
205
- last_request: function(){ return lastRequest() }
206
- }
207
- }
208
-
209
- })
210
- })()
@@ -1,39 +0,0 @@
1
- module DNCLabs
2
- module ClientSideValidations
3
- module Adapters
4
- module ActionView
5
- module BaseMethods
6
-
7
- def client_side_validations(object_name, options = {})
8
- url = options.delete(:url)
9
- raise "No URL Specified!" unless url
10
- adapter = options.delete(:adapter) || 'jquery.validate'
11
- js = %{<script type="text/javascript">$(document).ready(function(){$('##{dom_id(options[:object])}').clientSideValidations('#{url}','#{adapter}');});</script>}
12
- if js.respond_to?(:html_safe)
13
- js.html_safe
14
- else
15
- js
16
- end
17
- end
18
-
19
- end # BaseMethods
20
-
21
- module FormBuilderMethods
22
-
23
- def client_side_validations(options = {})
24
- @template.send(:client_side_validations, @object_name, objectify_options(options))
25
- end
26
-
27
- end # FormBuilderMethods
28
- end
29
- end
30
- end
31
- end
32
-
33
- ActionView::Base.class_eval do
34
- include DNCLabs::ClientSideValidations::Adapters::ActionView::BaseMethods
35
- end
36
-
37
- ActionView::Helpers::FormBuilder.class_eval do
38
- include DNCLabs::ClientSideValidations::Adapters::ActionView::FormBuilderMethods
39
- end
@@ -1,55 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- gem 'actionpack', '~> 2.0'
3
- require 'action_pack'
4
- require 'action_view'
5
- require 'client_side_validations'
6
-
7
- describe 'ActionView 2.x Form Helper' do
8
- context 'ActionView::Base' do
9
- subject { ActionView::Base.new }
10
-
11
- context 'only the url' do
12
- before do
13
- @object_name = 'object'
14
- @url = '/objects/new.json'
15
- @expected_javascript = %{<script type="text/javascript">$(document).ready(function(){$('##{@object_name}').clientSideValidations('#{@url}','jquery.validate');});</script>}
16
- subject.should_receive(:dom_id).and_return(@object_name)
17
- end
18
-
19
- it 'should generate the proper javascript' do
20
- subject.client_side_validations(@object_name,
21
- :url => @url).should == @expected_javascript
22
- end
23
- end
24
-
25
- context 'a different adapter' do
26
- before do
27
- @object_name = 'object'
28
- @url = '/objects/new.json'
29
- @adapter = 'some.other.adapter'
30
- @expected_javascript = %{<script type="text/javascript">$(document).ready(function(){$('##{@object_name}').clientSideValidations('#{@url}','#{@adapter}');});</script>}
31
- subject.should_receive(:dom_id).and_return(@object_name)
32
- end
33
-
34
- it 'should generate the proper javascript' do
35
- subject.client_side_validations(@object_name,
36
- :url => @url, :adapter => @adapter).should == @expected_javascript
37
- end
38
- end
39
-
40
- context 'not including the :url' do
41
- before do
42
- @object_name = 'object'
43
- @adapter = 'some.other.adapter'
44
- end
45
-
46
- it 'should raise an error' do
47
- expect {
48
- subject.client_side_validations(@object_name,
49
- :adapter => @some_other_adapter)
50
- }.to raise_error
51
- end
52
- end
53
-
54
- end
55
- end
@@ -1,55 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- gem 'actionpack', '~> 3.0'
3
- require 'action_pack'
4
- require 'action_view'
5
- require 'client_side_validations'
6
-
7
- describe 'ActionView 3.x Form Helper' do
8
- context 'ActionView::Base' do
9
- subject { ActionView::Base.new }
10
-
11
- context 'only the url' do
12
- before do
13
- @object_name = 'object'
14
- @url = '/objects/new.json'
15
- @expected_javascript = %{<script type="text/javascript">$(document).ready(function(){$('##{@object_name}').clientSideValidations('#{@url}','jquery.validate');});</script>}
16
- subject.should_receive(:dom_id).and_return(@object_name)
17
- end
18
-
19
- it 'should generate the proper javascript' do
20
- subject.client_side_validations(@object_name,
21
- :url => @url).should == @expected_javascript
22
- end
23
- end
24
-
25
- context 'a different adapter' do
26
- before do
27
- @object_name = 'object'
28
- @url = '/objects/new.json'
29
- @adapter = 'some.other.adapter'
30
- @expected_javascript = %{<script type="text/javascript">$(document).ready(function(){$('##{@object_name}').clientSideValidations('#{@url}','#{@adapter}');});</script>}
31
- subject.should_receive(:dom_id).and_return(@object_name)
32
- end
33
-
34
- it 'should generate the proper javascript' do
35
- subject.client_side_validations(@object_name,
36
- :url => @url, :adapter => @adapter).should == @expected_javascript
37
- end
38
- end
39
-
40
- context 'not including the :url' do
41
- before do
42
- @object_name = 'object'
43
- @adapter = 'some.other.adapter'
44
- end
45
-
46
- it 'should raise an error' do
47
- expect {
48
- subject.client_side_validations(@object_name,
49
- :adapter => @some_other_adapter)
50
- }.to raise_error
51
- end
52
- end
53
-
54
- end
55
- end
@@ -1,271 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- require 'active_model'
3
- require 'client_side_validations'
4
-
5
- describe "Validation to hash" do
6
-
7
- before do
8
- class Klass
9
- include ActiveModel::Validations
10
- end
11
- end
12
-
13
- after do
14
- Object.send(:remove_const, :Klass)
15
- end
16
-
17
- it "should support validate_presence_of" do
18
- Klass.class_eval { validates_presence_of :string }
19
- instance = Klass.new
20
- expected_hash = { "presence" => { "message" => "can't be blank"} }
21
- result_hash = instance.validation_to_hash(:string)
22
- result_hash.should == expected_hash
23
- end
24
-
25
- it "should support validates_format_of of" do
26
- Klass.class_eval { validates_format_of :string, :with => /\A\d\Z/i }
27
- instance = Klass.new
28
- expected_hash = { "format" => { "message" => "is invalid", "with" => "^\\d$" } }
29
- result_hash = instance.validation_to_hash(:string)
30
- result_hash.should == expected_hash
31
- end
32
-
33
- it "should support different ways to write regex" do
34
- Klass.class_eval do
35
- validates_format_of :string, :with => /^\d$/i
36
- validates_format_of :string_2, :with => /\d/
37
- end
38
- instance = Klass.new
39
- expected_hash_1 = { "format" => { "message" => "is invalid", "with" => "^\\d$" } }
40
- expected_hash_2 = { "format" => { "message" => "is invalid", "with" => "\\d" } }
41
- result_hash_1 = instance.validation_to_hash(:string)
42
- result_hash_2 = instance.validation_to_hash(:string_2)
43
- result_hash_1.should == expected_hash_1
44
- result_hash_2.should == expected_hash_2
45
- end
46
-
47
- it "should support minimum validates_length_of of" do
48
- Klass.class_eval { validates_length_of :string, :minimum => 10 }
49
- instance = Klass.new
50
- expected_hash = { "length" => { "message" => "is too short (minimum is 10 characters)", "minimum" => 10 } }
51
- result_hash = instance.validation_to_hash(:string)
52
- result_hash.should == expected_hash
53
- end
54
-
55
- it "should support maximum validates_length_of of" do
56
- Klass.class_eval { validates_length_of :string, :maximum => 10 }
57
- instance = Klass.new
58
- expected_hash = { "length" => { "message" => "is too long (maximum is 10 characters)", "maximum" => 10 } }
59
- result_hash = instance.validation_to_hash(:string)
60
- result_hash.should == expected_hash
61
- end
62
-
63
- it "should support validations with conditionals" do
64
- Klass.class_eval do
65
- validates_presence_of :string, :if => :need_string?
66
- validates_presence_of :string_2, :unless => :need_string?
67
- validates_presence_of :integer, :if => :need_integer?
68
-
69
- def need_string?
70
- true
71
- end
72
-
73
- def need_integer?
74
- false
75
- end
76
- end
77
-
78
- instance = Klass.new
79
- expected_hash_1 = { "presence" => { "message" => "can't be blank" } }
80
- result_hash_1 = instance.validation_to_hash(:string)
81
- result_hash_1.should == expected_hash_1
82
-
83
- expected_hash_2 = { }
84
- result_hash_2 = instance.validation_to_hash(:string_2)
85
- result_hash_2.should == expected_hash_2
86
-
87
- expected_hash_3 = { }
88
- result_hash_3 = instance.validation_to_hash(:integer)
89
- result_hash_3.should == expected_hash_3
90
- end
91
-
92
- it "should support validating the validates_numericality_of of" do
93
- Klass.class_eval { validates_numericality_of :integer }
94
- instance = Klass.new
95
- expected_hash = { "numericality" => { "message" => "is not a number" } }
96
- result_hash = instance.validation_to_hash(:integer)
97
- result_hash.should == expected_hash
98
- end
99
-
100
- it "should strip out the AR callback options" do
101
- Klass.class_eval { validates_presence_of :string, :on => :create }
102
- instance = Klass.new
103
- expected_hash = { "presence" => { "message" => "can't be blank"} }
104
- result_hash = instance.validation_to_hash(:string)
105
- result_hash.should == expected_hash
106
- end
107
-
108
- it "should support multiple validations for the same method" do
109
- Klass.class_eval do
110
- validates_presence_of :integer
111
- validates_numericality_of :integer
112
- end
113
-
114
- instance = Klass.new
115
- expected_hash = { "presence" => { "message" => "can't be blank" },
116
- "numericality" => { "message" => "is not a number" } }
117
- result_hash = instance.validation_to_hash(:integer)
118
- result_hash.should == expected_hash
119
- end
120
-
121
- context 'with custom validation messages' do
122
- before do
123
- add_translation(:en, :klass => { :attributes => { :string_2 => { :presence => "String_2" } } })
124
-
125
- Klass.class_eval do
126
- validates_presence_of :string, :message => "String"
127
- validates_presence_of :string_2, :message => :presence
128
- end
129
- end
130
-
131
- after do
132
- remove_translation(:en, :klass)
133
- end
134
-
135
- it 'should have a message of "String" for #string' do
136
- instance = Klass.new
137
- expected_hash = { "presence" => { "message" => "String" } }
138
- result_hash = instance.validation_to_hash(:string)
139
- result_hash.should == expected_hash
140
- end
141
-
142
- it 'should have a message of "String_2" for #string_2' do
143
- instance = Klass.new
144
- expected_hash = { "presence" => { "message" => "String_2" } }
145
- result_hash = instance.validation_to_hash(:string_2)
146
- result_hash.should == expected_hash
147
- end
148
- end
149
-
150
- context 'Other languages' do
151
- before do
152
- add_translation(:es, :klass => { :attributes => { :string => { :presence => "String-es" } } })
153
-
154
- Klass.class_eval do
155
- validates_presence_of :string, :message => :presence
156
- end
157
- end
158
-
159
- after do
160
- remove_translation(:es, :klass)
161
- end
162
-
163
- it 'should result in "String-es" for Spanish translations' do
164
- instance = Klass.new
165
- expected_hash = { "presence" => { "message" => "String-es" } }
166
- result_hash = instance.validation_to_hash(:string, :locale => :es)
167
- result_hash.should == expected_hash
168
- end
169
-
170
- it 'should result in "String-es" for Spanish translations when passed string "es" instead of symbol' do
171
- instance = Klass.new
172
- expected_hash = { "presence" => { "message" => "String-es" } }
173
- result_hash = instance.validation_to_hash(:string, :locale => "es")
174
- result_hash.should == expected_hash
175
- end
176
- end
177
-
178
- xit "should support the regular validate method" do
179
- Klass.class_eval do
180
- validate :do_something
181
-
182
- def do_something
183
- errors.add(:string, "test this out")
184
- end
185
- end
186
-
187
- instance = Klass.new
188
- # TODO: Unsupported right now
189
- end
190
-
191
- def add_translation(lang, hash)
192
- validations = {
193
- :errors => {
194
- :models => hash
195
- }
196
- }
197
- I18n.backend.store_translations(lang, validations)
198
- end
199
-
200
- def remove_translation(lang, key)
201
- model_validations = I18n.translate('errors.models')
202
- model_validations.delete(key)
203
- validations = {
204
- :errors => model_validations
205
- }
206
- I18n.backend.store_translations(lang, validations)
207
- end
208
- end
209
-
210
- describe "Validations to JSON" do
211
- before do
212
- class Klass
213
- include ActiveModel::Validations
214
- end
215
- end
216
-
217
- after do
218
- Object.send(:remove_const, :Klass)
219
- end
220
-
221
- it "should support a sinlgle validation" do
222
- Klass.class_eval do
223
- validates_presence_of :string
224
- end
225
-
226
- instance = Klass.new
227
- expected_json = {:string => { "presence" => { "message" => "can't be blank" } } }.to_json
228
- result_json = instance.validations_to_json(:string)
229
- result_json.should == expected_json
230
- end
231
-
232
- it "should support multiple validations on the same field" do
233
- Klass.class_eval do
234
- validates_presence_of :number
235
- validates_numericality_of :number
236
- end
237
-
238
- instance = Klass.new
239
- expected_json = {:number => { "presence" => { "message" => "can't be blank" }, "numericality" => { "message" => "is not a number" } } }.to_json
240
- result_json = instance.validations_to_json(:number)
241
- result_json.should == expected_json
242
- end
243
-
244
- it "should support single validations on different fields" do
245
- Klass.class_eval do
246
- validates_presence_of :string
247
- validates_presence_of :string_2
248
- end
249
-
250
- instance = Klass.new
251
- expected_json = {:string => { "presence" => { "message" => "can't be blank" } },
252
- :string_2 => { "presence" => { "message" => "can't be blank" } } }.to_json
253
- result_json = instance.validations_to_json(:string, :string_2)
254
- result_json.should == expected_json
255
- end
256
-
257
- it "should support multiple validations on different fields" do
258
- Klass.class_eval do
259
- validates_presence_of :number_1
260
- validates_numericality_of :number_1
261
- validates_presence_of :number_2
262
- validates_numericality_of :number_2
263
- end
264
-
265
- instance = Klass.new
266
- expected_json = {:number_1 => { "presence" => { "message" => "can't be blank" }, "numericality" => { "message" => "is not a number" } },
267
- :number_2 => { "presence" => { "message" => "can't be blank" }, "numericality" => { "message" => "is not a number" } } }.to_json
268
- result_json = instance.validations_to_json(:number_1, :number_2)
269
- result_json.should == expected_json
270
- end
271
- end