can_has_validations 0.6.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +50 -4
- data/lib/can_has_validations.rb +1 -1
- data/lib/can_has_validations/locale/en.yml +3 -1
- data/lib/can_has_validations/validators/email_validator.rb +42 -2
- data/lib/can_has_validations/validators/grandparent_validator.rb +2 -1
- data/lib/can_has_validations/validators/hostname_validator.rb +9 -4
- data/lib/can_has_validations/validators/ipaddr_validator.rb +91 -0
- data/lib/can_has_validations/validators/url_validator.rb +8 -2
- data/lib/can_has_validations/version.rb +1 -1
- metadata +30 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b8c22fcbf2964d57091e6b566e5d05a1b501f286722ae26e4c63be5d42989f9
|
4
|
+
data.tar.gz: c2cdd19af9fa8459007d506f93e4dec5b1311c173d4fdf087c7438a1d387d97f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 115570baed1e6a8061612de3f6428599ab4b76afab032756db8a7df5d5aa8bf8ec76f91d52849b5a28b154349965028c5f295350e4fd8f62d86b7f298e046cf2
|
7
|
+
data.tar.gz: fa601d54efefa5ee3d83299b9838ba6684450009ef3f782e3904de6405ea6ecd05869e79e89daadf42904f8cfe8c791a2f397a1fb24ec08cd9ff1ced1bd269a9
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -10,6 +10,7 @@ Validations provided:
|
|
10
10
|
* Existence
|
11
11
|
* Grandparent
|
12
12
|
* Hostname
|
13
|
+
* IP address
|
13
14
|
* Ordering
|
14
15
|
* URL
|
15
16
|
* Write Once
|
@@ -147,14 +148,48 @@ TLD, so as to not fail as ICANN continues to add TLDs.
|
|
147
148
|
# allows '_abc.example.com'
|
148
149
|
validates :domain, hostname: {allow_underscore: true}
|
149
150
|
|
151
|
+
# allows '4.0/25.3.2.1.example.com'
|
152
|
+
validates :domain, hostname: {allow_slash: true}
|
153
|
+
|
150
154
|
# allows 'a.example.com', but not 'example.com'
|
151
155
|
validates :domain, hostname: {segments: 3..100}
|
152
156
|
|
157
|
+
# allows 'subdomain'
|
158
|
+
validates :subdomain, hostname: {segments: 1, skip_tld: true}
|
159
|
+
|
153
160
|
# allows '1.2.3.4' or 'a.example.com'
|
154
161
|
validates :domain, hostname: {allow_ip: true}
|
155
162
|
# use 4 or 6 for ipv4 or ipv6 only
|
156
163
|
|
157
164
|
|
165
|
+
## IP address validator ##
|
166
|
+
|
167
|
+
Ensures an attribute is generally formatted as a IP or IP block.
|
168
|
+
|
169
|
+
# allows '1.2.3.4' or '::1'
|
170
|
+
validates :ip, ipaddr: true
|
171
|
+
|
172
|
+
# allows '1.2.3.0/24' or '2001:db8::/64'
|
173
|
+
validates :cidr, ipaddr: {allow_block: true}
|
174
|
+
|
175
|
+
# if an ip block, the attribute must be fully contained within an allowed block.
|
176
|
+
# allows '10.0.0.1' and '10.0.0.0/24', but not '10.0.0.0/15'
|
177
|
+
validates :private_ip, ipaddr: {
|
178
|
+
allow_block: true,
|
179
|
+
within: [IPAddr.new('10.0.0.0/16'), '127.0.0.1']
|
180
|
+
# allowed IPs and blocks may be IPAddrs or Strings
|
181
|
+
}
|
182
|
+
|
183
|
+
# the inverse of :within
|
184
|
+
validates :public_ip6, ipaddr: {without: ['fc00::/7']]}
|
185
|
+
|
186
|
+
# :within and :without may also be procs or method names
|
187
|
+
validates :ip, ipaddr: {
|
188
|
+
within: :some_method,
|
189
|
+
without: ->(record){ ... }
|
190
|
+
}
|
191
|
+
|
192
|
+
|
158
193
|
## Ordering validators ##
|
159
194
|
|
160
195
|
Ensures two attribute values maintain a relative order to one another. This is
|
@@ -180,13 +215,17 @@ Always skips over nil values; use `:presence` to validate those.
|
|
180
215
|
|
181
216
|
## URL validator ##
|
182
217
|
|
183
|
-
|
218
|
+
Ensures an attribute is generally formatted as a URL. If `addressable/uri` is
|
184
219
|
already loaded, it will be used to parse IDN's. Additionally, allowed schemes
|
185
220
|
can be specified; they default to ['http','https'].
|
186
221
|
|
187
222
|
validates :website, url: true
|
188
223
|
validates :secure_url, url: {scheme: 'https'}
|
189
224
|
|
225
|
+
# Dynamic list of schemes. *Must* return an array.
|
226
|
+
validates :git, url: {scheme: :some_method}
|
227
|
+
validates :old_school, url: {scheme: ->(record){ %w(ftp gopher) }}
|
228
|
+
|
190
229
|
# With IDN parsing:
|
191
230
|
require 'addressable/uri'
|
192
231
|
validates :website, url: true
|
@@ -198,8 +237,8 @@ can be specified; they default to ['http','https'].
|
|
198
237
|
|
199
238
|
## Write Once validator ##
|
200
239
|
|
201
|
-
|
202
|
-
for this.
|
240
|
+
Ensures that once a value is written, it becomes readonly. There are a few
|
241
|
+
uses for this.
|
203
242
|
|
204
243
|
The first is as an equivalent to `attr_readonly :user_id` except that it also
|
205
244
|
produces a validation error instead of silently ignoring the change as
|
@@ -214,6 +253,10 @@ sorts.
|
|
214
253
|
|
215
254
|
validates :user_id, allow_nil: true, write_once: true
|
216
255
|
|
256
|
+
The third use is to allow a nil value, and treat the nil also as write-once.
|
257
|
+
|
258
|
+
validates :source, write_once: {immutable_nil: true}
|
259
|
+
|
217
260
|
|
218
261
|
## Error messages
|
219
262
|
|
@@ -225,6 +268,9 @@ Default messages are as follows:
|
|
225
268
|
messages:
|
226
269
|
invalid_email: "is an invalid email"
|
227
270
|
invalid_hostname: "is an invalid hostname"
|
271
|
+
invalid_ip: "is an invalid IP"
|
272
|
+
ip_not_allowed: "is not an allowed IP"
|
273
|
+
single_ip_required: "must be a single IP"
|
228
274
|
invalid_url: "is an invalid URL"
|
229
275
|
unchangeable: "cannot be changed"
|
230
276
|
before: "must be before %{attribute2}"
|
@@ -233,4 +279,4 @@ Default messages are as follows:
|
|
233
279
|
|
234
280
|
## Compatibility ##
|
235
281
|
|
236
|
-
|
282
|
+
The current version is tested with Ruby 2.5-2.6 and ActiveModel 5.2-6.0.
|
data/lib/can_has_validations.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'active_model/validations'
|
2
2
|
|
3
|
-
%w(array email existence grandparent hostname ordering url write_once).each do |validator|
|
3
|
+
%w(array email existence grandparent hostname ipaddr ordering url write_once).each do |validator|
|
4
4
|
require "can_has_validations/validators/#{validator}_validator"
|
5
5
|
end
|
6
6
|
|
@@ -3,8 +3,10 @@ en:
|
|
3
3
|
messages:
|
4
4
|
invalid_email: "is an invalid email"
|
5
5
|
invalid_hostname: "is an invalid hostname"
|
6
|
+
invalid_ip: "is an invalid IP"
|
7
|
+
ip_not_allowed: "is not an allowed IP"
|
8
|
+
single_ip_required: "must be a single IP"
|
6
9
|
invalid_url: "is an invalid URL"
|
7
10
|
unchangeable: "cannot be changed"
|
8
11
|
before: "must be before %{attribute2}"
|
9
12
|
after: "must be after %{attribute2}"
|
10
|
-
|
@@ -1,15 +1,55 @@
|
|
1
1
|
# Ensure an attribute is generally formatted as an email.
|
2
2
|
# eg: validates :user_email, email: true
|
3
3
|
|
4
|
+
require_relative 'hostname_validator'
|
5
|
+
|
4
6
|
module ActiveModel::Validations
|
5
7
|
class EmailValidator < ActiveModel::EachValidator
|
6
8
|
|
7
|
-
EMAIL_REGEXP
|
9
|
+
EMAIL_REGEXP = /\A([a-z0-9._+-]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
|
10
|
+
SEGMENT_REGEXP = /\A[a-z0-9+_-]+\z/i
|
11
|
+
LABEL_REGEXP = HostnameValidator::LABEL_REGEXP
|
12
|
+
FINAL_LABEL_REGEXP = HostnameValidator::FINAL_LABEL_REGEXP
|
8
13
|
|
9
14
|
def validate_each(record, attribute, value)
|
10
|
-
unless value
|
15
|
+
unless email_valid?(value)
|
11
16
|
record.errors.add(attribute, :invalid_email, options.merge(value: value))
|
12
17
|
end
|
13
18
|
end
|
19
|
+
|
20
|
+
def email_valid?(value)
|
21
|
+
return unless value
|
22
|
+
recipient, domain = value.split('@', 2)
|
23
|
+
is_valid = true
|
24
|
+
|
25
|
+
recipient ||= ''
|
26
|
+
is_valid &&= recipient.length <= 255
|
27
|
+
is_valid &&= recipient !~ /\.\./
|
28
|
+
is_valid &&= !recipient.starts_with?('.')
|
29
|
+
is_valid &&= !recipient.ends_with?('.')
|
30
|
+
recipient.split('.').each do |segment|
|
31
|
+
is_valid &&= segment =~ SEGMENT_REGEXP
|
32
|
+
end
|
33
|
+
|
34
|
+
domain ||= ''
|
35
|
+
if defined?(Addressable::IDNA)
|
36
|
+
domain &&= Addressable::IDNA.to_ascii(domain)
|
37
|
+
end
|
38
|
+
labels = domain.split('.')
|
39
|
+
is_valid &&= domain.length <= 255
|
40
|
+
is_valid &&= domain !~ /\.\./
|
41
|
+
is_valid &&= labels.size.in? 2..100
|
42
|
+
labels.each_with_index do |label, idx|
|
43
|
+
is_valid &&= label.length <= 63
|
44
|
+
if idx+1==labels.size
|
45
|
+
is_valid &&= label =~ FINAL_LABEL_REGEXP
|
46
|
+
else
|
47
|
+
is_valid &&= label =~ LABEL_REGEXP
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
is_valid
|
52
|
+
end
|
53
|
+
|
14
54
|
end
|
15
55
|
end
|
@@ -16,7 +16,8 @@ module ActiveModel::Validations
|
|
16
16
|
if cousin.nil?
|
17
17
|
options[:allow_nil]
|
18
18
|
else
|
19
|
-
association
|
19
|
+
association &&
|
20
|
+
association.send(options[:parent]) == cousin.send(options[:parent])
|
20
21
|
end
|
21
22
|
end
|
22
23
|
unless all_match
|
@@ -18,19 +18,23 @@
|
|
18
18
|
# allows '*.example.com'
|
19
19
|
# validates :domain, hostname: {allow_underscore: true}
|
20
20
|
# allows '_abc.example.com'
|
21
|
+
# validates :domain, hostname: {allow_slash: true}
|
22
|
+
# allows '4.0/25.3.2.1.example.com' # rfc2317
|
21
23
|
# validates :domain, hostname: {segments: 3..100}
|
22
24
|
# allows 'a.example.com', but not 'example.com'
|
23
25
|
# validates :domain, hostname: {allow_ip: true} # or 4 or 6 for ipv4 or ipv6 only
|
24
26
|
# allows '1.2.3.4' or 'a.example.com'
|
27
|
+
# validates :subdomain, hostname: {skip_tld: true, segments: 1}
|
28
|
+
# allows 'subdomain1'
|
25
29
|
|
26
30
|
require 'resolv'
|
27
31
|
|
28
32
|
module ActiveModel::Validations
|
29
33
|
class HostnameValidator < ActiveModel::EachValidator
|
30
34
|
|
31
|
-
LABEL_REGEXP =
|
32
|
-
FINAL_LABEL_REGEXP =
|
33
|
-
RESERVED_OPTIONS = %i(allow_ip allow_underscore allow_wildcard)
|
35
|
+
LABEL_REGEXP = %r{\A([a-zA-Z0-9_]([a-zA-Z0-9_/-]+)?)?[a-zA-Z0-9]\z}
|
36
|
+
FINAL_LABEL_REGEXP = %r{\A(xn--[a-zA-Z0-9]{2,}|[a-zA-Z]{2,})\z}
|
37
|
+
RESERVED_OPTIONS = %i(allow_ip allow_slash allow_underscore allow_wildcard)
|
34
38
|
|
35
39
|
def validate_each(record, attribute, value)
|
36
40
|
case options[:allow_ip]
|
@@ -53,10 +57,11 @@ module ActiveModel::Validations
|
|
53
57
|
is_valid &&= value.length <= 255
|
54
58
|
is_valid &&= value !~ /\.\./
|
55
59
|
is_valid &&= value !~ /_/ unless options[:allow_underscore]
|
60
|
+
is_valid &&= value !~ %r{/} unless options[:allow_slash]
|
56
61
|
is_valid &&= labels.size.in? segments
|
57
62
|
labels.each_with_index do |label, idx|
|
58
63
|
is_valid &&= label.length <= 63
|
59
|
-
if idx+1==labels.size
|
64
|
+
if !options[:skip_tld] && idx+1==labels.size
|
60
65
|
is_valid &&= label =~ FINAL_LABEL_REGEXP
|
61
66
|
elsif options[:allow_wildcard] && idx==0
|
62
67
|
is_valid &&= label=='*' || label =~ LABEL_REGEXP
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# Ensure an attribute is generally formatted as a IP or IP block.
|
2
|
+
# eg: validates :ip, ipaddr: true
|
3
|
+
# validates :cidr, ipaddr: {allow_block: true}
|
4
|
+
# validates :private_ip, ipaddr: {within: [IPAddr.new('10.0.0.0/8'), '127.0.0.1']}
|
5
|
+
# ip must be within any one of the provided ips/blocks
|
6
|
+
# if ip is block, it must be fully contained within any one of the provided blocks
|
7
|
+
# validates :public_ip6, ipaddr: {without: ['fc00::/7']]}
|
8
|
+
# ip must be outside all of the provided ips/blocks
|
9
|
+
# if ip is block, it must be fully outside all of the provided blocks
|
10
|
+
|
11
|
+
require 'ipaddr'
|
12
|
+
|
13
|
+
module ActiveModel::Validations
|
14
|
+
class IpaddrValidator < ActiveModel::EachValidator
|
15
|
+
|
16
|
+
def initialize(options)
|
17
|
+
options[:within] = normalize_within options[:within], :within
|
18
|
+
options[:without] = normalize_within options[:without], :without
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate_each(record, attribute, value)
|
23
|
+
allowed_ips = resolve_array record, options[:within]
|
24
|
+
disallowed_ips = resolve_array record, options[:without]
|
25
|
+
|
26
|
+
ip = case value
|
27
|
+
when IPAddr
|
28
|
+
ip
|
29
|
+
when String
|
30
|
+
IPAddr.new(value) rescue nil
|
31
|
+
end
|
32
|
+
unless ip
|
33
|
+
record.errors.add(attribute, :invalid_ip, options.merge(value: value))
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
if !options[:allow_block] && (ip.ipv4? && ip.prefix!=32 or ip.ipv6? && ip.prefix!=128)
|
38
|
+
record.errors.add(attribute, :single_ip_required, options.merge(value: value))
|
39
|
+
end
|
40
|
+
if allowed_ips && allowed_ips.none?{|blk| blk.include? ip}
|
41
|
+
record.errors.add(attribute, :ip_not_allowed, options.merge(value: value))
|
42
|
+
elsif disallowed_ips && disallowed_ips.any?{|blk| blk.include? ip}
|
43
|
+
record.errors.add(attribute, :ip_not_allowed, options.merge(value: value))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def normalize_within(val, key)
|
51
|
+
if val.nil? || val.respond_to?(:call) || val.is_a?(Symbol)
|
52
|
+
val
|
53
|
+
else
|
54
|
+
Array(val).flatten.map do |i|
|
55
|
+
case i
|
56
|
+
when IPAddr
|
57
|
+
i
|
58
|
+
when String
|
59
|
+
IPAddr.new i
|
60
|
+
else
|
61
|
+
raise "Unexpected value for #{key.inspect} : #{i}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def resolve_array(record, val)
|
68
|
+
res = if val.respond_to?(:call)
|
69
|
+
val.call(record)
|
70
|
+
elsif val.is_a?(Symbol)
|
71
|
+
record.send(val)
|
72
|
+
else
|
73
|
+
val
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# tests for & fixes broken IPAddr <= 1.2.2
|
81
|
+
if IPAddr.new('192.168.2.0/32').include? '192.168.2.0/24'
|
82
|
+
# warn 'IPAddr <= 1.2.2 is broken; monkey-patching'
|
83
|
+
class IPAddr
|
84
|
+
def include?(other)
|
85
|
+
range = to_range
|
86
|
+
other = coerce_other(other).to_range
|
87
|
+
range.begin <= other.begin && range.end >= other.end
|
88
|
+
end
|
89
|
+
alias === include?
|
90
|
+
end
|
91
|
+
end
|
@@ -7,7 +7,13 @@
|
|
7
7
|
module ActiveModel::Validations
|
8
8
|
class UrlValidator < ActiveModel::EachValidator
|
9
9
|
def validate_each(record, attribute, value)
|
10
|
-
allowed_schemes =
|
10
|
+
allowed_schemes = if options[:scheme].respond_to?(:call)
|
11
|
+
options[:scheme].call(record)
|
12
|
+
elsif options[:scheme].is_a?(Symbol)
|
13
|
+
record.send(options[:scheme])
|
14
|
+
else
|
15
|
+
Array.wrap(options[:scheme] || %w(http https))
|
16
|
+
end
|
11
17
|
|
12
18
|
if defined?(Addressable::URI)
|
13
19
|
u = Addressable::URI.parse(value) rescue nil
|
@@ -16,7 +22,7 @@ module ActiveModel::Validations
|
|
16
22
|
u2 = u = URI.parse(value) rescue nil
|
17
23
|
end
|
18
24
|
if !u || !u2 || u.relative? || allowed_schemes.exclude?(u.scheme)
|
19
|
-
record.errors.add(attribute, :invalid_url, options.merge(value: value))
|
25
|
+
record.errors.add(attribute, :invalid_url, options.merge(value: value, scheme: allowed_schemes))
|
20
26
|
end
|
21
27
|
end
|
22
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: can_has_validations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thomas morgan
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '5.0'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '6'
|
22
|
+
version: '6.1'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
29
|
+
version: '5.0'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '6'
|
32
|
+
version: '6.1'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: sqlite3
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
|
-
description: Assorted Rails
|
47
|
+
description: Assorted Rails 5.x-6.x validators.
|
48
48
|
email:
|
49
49
|
- tm@iprog.com
|
50
50
|
executables: []
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- lib/can_has_validations/validators/existence_validator.rb
|
62
62
|
- lib/can_has_validations/validators/grandparent_validator.rb
|
63
63
|
- lib/can_has_validations/validators/hostname_validator.rb
|
64
|
+
- lib/can_has_validations/validators/ipaddr_validator.rb
|
64
65
|
- lib/can_has_validations/validators/ordering_validator.rb
|
65
66
|
- lib/can_has_validations/validators/url_validator.rb
|
66
67
|
- lib/can_has_validations/validators/write_once_validator.rb
|
@@ -100,7 +101,7 @@ files:
|
|
100
101
|
homepage: https://github.com/zarqman/can_has_validations
|
101
102
|
licenses: []
|
102
103
|
metadata: {}
|
103
|
-
post_install_message:
|
104
|
+
post_install_message:
|
104
105
|
rdoc_options: []
|
105
106
|
require_paths:
|
106
107
|
- lib
|
@@ -115,40 +116,39 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
116
|
- !ruby/object:Gem::Version
|
116
117
|
version: '0'
|
117
118
|
requirements: []
|
118
|
-
|
119
|
-
|
120
|
-
signing_key:
|
119
|
+
rubygems_version: 3.0.8
|
120
|
+
signing_key:
|
121
121
|
specification_version: 4
|
122
|
-
summary: Assorted Rails
|
122
|
+
summary: Assorted Rails 5.x-6.x validators
|
123
123
|
test_files:
|
124
|
-
- test/
|
124
|
+
- test/dummy/app/controllers/application_controller.rb
|
125
|
+
- test/dummy/app/views/layouts/application.html.erb
|
125
126
|
- test/dummy/app/assets/javascripts/application.js
|
126
127
|
- test/dummy/app/assets/stylesheets/application.css
|
127
|
-
- test/dummy/app/controllers/application_controller.rb
|
128
128
|
- test/dummy/app/helpers/application_helper.rb
|
129
|
-
- test/dummy/
|
130
|
-
- test/dummy/config/
|
131
|
-
- test/dummy/config/boot.rb
|
132
|
-
- test/dummy/config/database.yml
|
133
|
-
- test/dummy/config/environment.rb
|
134
|
-
- test/dummy/config/environments/development.rb
|
129
|
+
- test/dummy/config/routes.rb
|
130
|
+
- test/dummy/config/locales/en.yml
|
135
131
|
- test/dummy/config/environments/production.rb
|
132
|
+
- test/dummy/config/environments/development.rb
|
136
133
|
- test/dummy/config/environments/test.rb
|
134
|
+
- test/dummy/config/environment.rb
|
135
|
+
- test/dummy/config/application.rb
|
136
|
+
- test/dummy/config/database.yml
|
137
|
+
- test/dummy/config/boot.rb
|
137
138
|
- test/dummy/config/initializers/backtrace_silencers.rb
|
138
|
-
- test/dummy/config/initializers/inflections.rb
|
139
139
|
- test/dummy/config/initializers/mime_types.rb
|
140
|
-
- test/dummy/config/initializers/secret_token.rb
|
141
140
|
- test/dummy/config/initializers/session_store.rb
|
142
141
|
- test/dummy/config/initializers/wrap_parameters.rb
|
143
|
-
- test/dummy/config/
|
144
|
-
- test/dummy/config/
|
142
|
+
- test/dummy/config/initializers/secret_token.rb
|
143
|
+
- test/dummy/config/initializers/inflections.rb
|
145
144
|
- test/dummy/config.ru
|
146
|
-
- test/dummy/
|
147
|
-
- test/dummy/
|
145
|
+
- test/dummy/script/rails
|
146
|
+
- test/dummy/Rakefile
|
147
|
+
- test/dummy/public/favicon.ico
|
148
148
|
- test/dummy/public/422.html
|
149
149
|
- test/dummy/public/500.html
|
150
|
-
- test/dummy/public/
|
151
|
-
- test/dummy/
|
150
|
+
- test/dummy/public/404.html
|
151
|
+
- test/dummy/log/test.log
|
152
152
|
- test/dummy/README.rdoc
|
153
|
-
- test/
|
153
|
+
- test/can_has_validations_test.rb
|
154
154
|
- test/test_helper.rb
|