zapnap-isbn_validation 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README +27 -0
- data/Rakefile +51 -0
- data/lib/isbn_validation.rb +84 -0
- data/rails/init.rb +2 -0
- data/test/isbn_validation_test.rb +92 -0
- data/test/models.rb +13 -0
- data/test/schema.rb +5 -0
- data/test/test_helper.rb +13 -0
- metadata +72 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
IsbnValidation
|
2
|
+
==============
|
3
|
+
|
4
|
+
Custom ActiveRecord Validation for International Standard Book Number (ISBN) fields.
|
5
|
+
Supports both ISBN-10 and ISBN-13. Will guarantee that validated fields contain valid
|
6
|
+
ISBNs.
|
7
|
+
|
8
|
+
Default behavior is to allow either ISBN-10 or ISBN-13, but this can be altered by
|
9
|
+
specifying the :with option as shown in the example below.
|
10
|
+
|
11
|
+
For more information on ISBN, see http://en.wikipedia.org/wiki/Isbn
|
12
|
+
|
13
|
+
Installation
|
14
|
+
============
|
15
|
+
|
16
|
+
ruby script/plugin install git://github.com/zapnap/isbn_validation
|
17
|
+
|
18
|
+
Example
|
19
|
+
=======
|
20
|
+
|
21
|
+
class Book < ActiveRecord::Base
|
22
|
+
validates_isbn :isbn
|
23
|
+
validates_isbn :isbn10, :with => :isbn10
|
24
|
+
validates_isbn :isbn13, :with => :isbn13
|
25
|
+
end
|
26
|
+
|
27
|
+
Copyright (c) 2008 Nick Plante, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the isbn_validation plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate documentation for the isbn_validation plugin.'
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'IsbnValidation'
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
+
rdoc.rdoc_files.include('README')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
23
|
+
|
24
|
+
spec = Gem::Specification.new do |s|
|
25
|
+
s.name = %q{isbn_validation}
|
26
|
+
s.name = %q{isbn_validation}
|
27
|
+
s.version = "0.1.0"
|
28
|
+
s.summary = %q{isbn_validation adds an isbn validation routine to active record models.}
|
29
|
+
s.description = %q{isbn_validation adds an isbn validation routine to active record models.}
|
30
|
+
|
31
|
+
s.files = FileList['[A-Z]*', '{lib,test,rails}/**/*.rb']
|
32
|
+
s.require_path = 'lib'
|
33
|
+
s.test_files = Dir[*['test/**/*_test.rb']]
|
34
|
+
|
35
|
+
s.has_rdoc = true
|
36
|
+
s.extra_rdoc_files = ["README"]
|
37
|
+
s.rdoc_options = ['--line-numbers', '--inline-source', "--main", "README"]
|
38
|
+
|
39
|
+
s.authors = ["Nick Plante"]
|
40
|
+
s.email = %q{nap@zerosum.org}
|
41
|
+
|
42
|
+
s.platform = Gem::Platform::RUBY
|
43
|
+
s.add_dependency(%q<activerecord>, [">= 2.1.2"])
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Generate a gemspec file"
|
47
|
+
task :gemspec do
|
48
|
+
File.open("#{spec.name}.gemspec", 'w') do |f|
|
49
|
+
f.write spec.to_ruby
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Zerosum
|
2
|
+
module ValidationExtensions
|
3
|
+
module IsbnValidation
|
4
|
+
ISBN10_REGEX = /^(?:\d[\ |-]?){9}[\d|X]$/
|
5
|
+
ISBN13_REGEX = /^(?:\d[\ |-]?){13}$/
|
6
|
+
|
7
|
+
# Validates whether the value of the specified attribute is a proper ISBN number.
|
8
|
+
# Defaults to verifying that the value is either a valid ISBN-10 or ISBN-13 number
|
9
|
+
# but this behavior can be modified using configuration options (as shown below).
|
10
|
+
#
|
11
|
+
# class Book < ActiveRecord::Base
|
12
|
+
# validates_isbn :isbn
|
13
|
+
# #validates_isbn :isbn10, :with => :isbn10
|
14
|
+
# #validates_isbn :isbn13, :with => :isbn13
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# Configuration options:
|
18
|
+
# * <tt>:message</tt> - A custom error message (default is: "is not a valid ISBN")
|
19
|
+
# * <tt>:with</tt> - A symbol referencing the type of ISBN to validate (:isbn10 or :isbn13)
|
20
|
+
# * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
|
21
|
+
# * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
|
22
|
+
# * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
|
23
|
+
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
24
|
+
# occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
|
25
|
+
# method, proc or string should return or evaluate to a true or false value.
|
26
|
+
# * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
|
27
|
+
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
28
|
+
# method, proc or string should return or evaluate to a true or false value.
|
29
|
+
def validates_isbn(*attr_names)
|
30
|
+
configuration = {
|
31
|
+
:message => "is not a valid ISBN code"
|
32
|
+
}
|
33
|
+
|
34
|
+
configuration.update(attr_names.extract_options!)
|
35
|
+
validates_each(attr_names, configuration) do |record, attr_name, value|
|
36
|
+
valid = case configuration[:with]
|
37
|
+
when :isbn10
|
38
|
+
validate_with_isbn10(value)
|
39
|
+
when :isbn13
|
40
|
+
validate_with_isbn13(value)
|
41
|
+
else
|
42
|
+
validate_with_isbn10(value) || validate_with_isbn13(value)
|
43
|
+
end
|
44
|
+
record.errors.add(attr_name, configuration[:message]) unless valid
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def validate_with_isbn10(isbn) #:nodoc:
|
49
|
+
if isbn.match(ISBN10_REGEX)
|
50
|
+
isbn_values = isbn.upcase.gsub(/\ |-/, '').split('')
|
51
|
+
check_digit = isbn_values.pop # last digit is check digit
|
52
|
+
check_digit = (check_digit == 'X') ? 10 : check_digit.to_i
|
53
|
+
|
54
|
+
sum = 0
|
55
|
+
isbn_values.each_with_index do |value, index|
|
56
|
+
sum += (index + 1) * value.to_i
|
57
|
+
end
|
58
|
+
|
59
|
+
(sum % 11) == check_digit
|
60
|
+
else
|
61
|
+
false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def validate_with_isbn13(isbn) #:nodoc:
|
66
|
+
if isbn.match(ISBN13_REGEX)
|
67
|
+
isbn_values = isbn.upcase.gsub(/\ |-/, '').split('')
|
68
|
+
check_digit = isbn_values.pop.to_i # last digit is check digit
|
69
|
+
|
70
|
+
sum = 0
|
71
|
+
isbn_values.each_with_index do |value, index|
|
72
|
+
multiplier = (index % 2 == 0) ? 1 : 3
|
73
|
+
sum += multiplier * value.to_i
|
74
|
+
end
|
75
|
+
|
76
|
+
(10 - (sum % 10)) == check_digit
|
77
|
+
else
|
78
|
+
false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
data/rails/init.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require File.dirname(__FILE__) + '/models'
|
3
|
+
|
4
|
+
class IsbnValidationTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@book = Book.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_isbn10_should_match_regex
|
10
|
+
isbn = '1590599934'
|
11
|
+
assert isbn.match(Zerosum::ValidationExtensions::IsbnValidation::ISBN10_REGEX)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_isbn10_should_not_match_regex
|
15
|
+
isbn = 'abc123ab3344'
|
16
|
+
assert !isbn.match(Zerosum::ValidationExtensions::IsbnValidation::ISBN10_REGEX)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_isbn10_with_dashes_and_spaces_should_match_regex
|
20
|
+
isbn = '159-059 9934'
|
21
|
+
assert isbn.match(Zerosum::ValidationExtensions::IsbnValidation::ISBN10_REGEX)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_isbn13_should_match_regex
|
25
|
+
isbn = '9781590599938'
|
26
|
+
assert isbn.match(Zerosum::ValidationExtensions::IsbnValidation::ISBN13_REGEX)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_isbn13_should_not_match_regex
|
30
|
+
isbn = '9991a9010599938'
|
31
|
+
assert !isbn.match(Zerosum::ValidationExtensions::IsbnValidation::ISBN13_REGEX)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_isbn13_with_dashes_and_spaces_should_match_regex
|
35
|
+
isbn = '978-159059 9938'
|
36
|
+
assert isbn.match(Zerosum::ValidationExtensions::IsbnValidation::ISBN13_REGEX)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_isbn10_should_pass_check_digit_verification
|
40
|
+
@book.isbn = '159059993-4'
|
41
|
+
assert @book.valid?
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_isbn10_should_fail_check_digit_verification
|
45
|
+
@book.isbn = '159059993-0'
|
46
|
+
assert !@book.valid?
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_isbn10_should_handle_x_character_checksum
|
50
|
+
@book.isbn = '0-9722051-1-X'
|
51
|
+
assert @book.valid?
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_isbn13_should_pass_check_digit_verification
|
55
|
+
@book.isbn = '978-1590599938'
|
56
|
+
assert @book.valid?
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_isbn13_should_fail_check_digit_verification
|
60
|
+
@book.isbn = '978-1590599934'
|
61
|
+
assert !@book.valid?
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_isbn_should_be_valid_if_either_isbn10_or_isbn13
|
65
|
+
@book.isbn = '978-1590599938'
|
66
|
+
assert @book.valid?
|
67
|
+
@book.isbn = '1590599934'
|
68
|
+
assert @book.valid?
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_isbn_should_validate_only_isbn10
|
72
|
+
@book = Book10.new
|
73
|
+
@book.isbn = '978-1590599938'
|
74
|
+
assert !@book.valid?
|
75
|
+
@book.isbn = '1590599934'
|
76
|
+
assert @book.valid?
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_isbn_should_validate_only_isbn13
|
80
|
+
@book = Book13.new
|
81
|
+
@book.isbn = '1590599934'
|
82
|
+
assert !@book.valid?
|
83
|
+
@book.isbn = '978-1590599938'
|
84
|
+
assert @book.valid?
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_should_have_custom_error_message
|
88
|
+
@book.isbn = '978-159059AAAAAA'
|
89
|
+
@book.valid?
|
90
|
+
assert_equal 'is too fantastical!', @book.errors.on(:isbn)
|
91
|
+
end
|
92
|
+
end
|
data/test/models.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
class Book < ActiveRecord::Base
|
2
|
+
validates_isbn :isbn, :message => 'is too fantastical!'
|
3
|
+
end
|
4
|
+
|
5
|
+
class Book10 < ActiveRecord::Base
|
6
|
+
set_table_name 'books'
|
7
|
+
validates_isbn :isbn, :with => :isbn10
|
8
|
+
end
|
9
|
+
|
10
|
+
class Book13 < ActiveRecord::Base
|
11
|
+
set_table_name 'books'
|
12
|
+
validates_isbn :isbn, :with => :isbn13
|
13
|
+
end
|
data/test/schema.rb
ADDED
data/test/test_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
RAILS_ROOT = File.dirname(__FILE__)
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'test/unit'
|
6
|
+
require 'active_record'
|
7
|
+
require "#{File.dirname(__FILE__)}/../init"
|
8
|
+
|
9
|
+
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
10
|
+
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
11
|
+
ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'sqlite3'])
|
12
|
+
|
13
|
+
load(File.dirname(__FILE__) + "/schema.rb") if File.exist?(File.dirname(__FILE__) + "/schema.rb")
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: zapnap-isbn_validation
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nick Plante
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-11-03 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activerecord
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.1.2
|
23
|
+
version:
|
24
|
+
description: isbn_validation adds an isbn validation routine to active record models.
|
25
|
+
email: nap@zerosum.org
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README
|
32
|
+
files:
|
33
|
+
- MIT-LICENSE
|
34
|
+
- Rakefile
|
35
|
+
- README
|
36
|
+
- lib/isbn_validation.rb
|
37
|
+
- test/isbn_validation_test.rb
|
38
|
+
- test/models.rb
|
39
|
+
- test/schema.rb
|
40
|
+
- test/test_helper.rb
|
41
|
+
- rails/init.rb
|
42
|
+
has_rdoc: true
|
43
|
+
homepage:
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options:
|
46
|
+
- --line-numbers
|
47
|
+
- --inline-source
|
48
|
+
- --main
|
49
|
+
- README
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.2.0
|
68
|
+
signing_key:
|
69
|
+
specification_version: 2
|
70
|
+
summary: isbn_validation adds an isbn validation routine to active record models.
|
71
|
+
test_files:
|
72
|
+
- test/isbn_validation_test.rb
|