library_stdnums 0.3.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +92 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/library_stdnums.rb +161 -56
- data/spec/library_stdnums_spec.rb +26 -22
- data/spec/spec_helper.rb +5 -5
- metadata +11 -42
- data/.gitignore +0 -21
- data/CHANGES +0 -9
- data/README.rdoc +0 -23
data/README.markdown
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# library_stdnums -- simple functions to check and normalize ISSN/ISBN/LCCN
|
2
|
+
|
3
|
+
These are a set of Module functions (not classes with methods!) that perform simple checksum verification and (when applicable) normalization on strings containing common library types (currently just ISBN, ISSN, and LCCN).
|
4
|
+
|
5
|
+
The code allows for some minimal crap (e.g., '1234-4568 online') will work fine. All returned ISBN/ISSN values are devoid any dashes; any trailing X for an ISBN/ISSN checkdigit will be uppercase *and will always be returned as a one-digit string*.
|
6
|
+
|
7
|
+
See the actual functions for more information than what's below.
|
8
|
+
|
9
|
+
## ISBN
|
10
|
+
|
11
|
+
````ruby
|
12
|
+
isbn = StdNum::ISBN.normalize(goodISBN)
|
13
|
+
# => a 13-digit ISBN with no dashes/spaces
|
14
|
+
|
15
|
+
isbn = StdNum::ISBN.normalize(badISBN)
|
16
|
+
# => nil (if it's not an ISBN or the checkdigit is bad)
|
17
|
+
|
18
|
+
tenDigit = StdNum::ISBN.convert_to_10(isbn13)
|
19
|
+
thirteenDigit = StdNum::ISBN.convert_to_13(isbn10)
|
20
|
+
|
21
|
+
thirteenDigit,tenDigit = StdNum::ISBN.allNormalizedValues(issn)
|
22
|
+
# => array of the ten and thirteen digit isbns if valid;
|
23
|
+
# an empty array if not
|
24
|
+
|
25
|
+
digit = StdNum::ISBN.checkdigit(isbn)
|
26
|
+
# => 0..9 (for isbn13) or 0..9,X (for isbn10)
|
27
|
+
|
28
|
+
if StdNum::ISBN.valid?(isbn)
|
29
|
+
puts "#{isbn} has a valid checkdigit"
|
30
|
+
end
|
31
|
+
|
32
|
+
````
|
33
|
+
|
34
|
+
# ISSN
|
35
|
+
|
36
|
+
````ruby
|
37
|
+
issn = StdNum::ISSN.normalize(issn)
|
38
|
+
# => the cleaned-up issn if valid; nil if not
|
39
|
+
|
40
|
+
digit = StdNum::ISSN.checkdigit(issn)
|
41
|
+
# => 0..9 or X
|
42
|
+
|
43
|
+
if StdNum::ISSN.valid?(issn)
|
44
|
+
puts "#{issn} has a valid checkdigit"
|
45
|
+
end
|
46
|
+
````
|
47
|
+
|
48
|
+
# LCCN
|
49
|
+
|
50
|
+
LCCNs are normalized according to the algorithm at http://www.loc.gov/marc/lccn-namespace.html#syntax
|
51
|
+
|
52
|
+
````ruby
|
53
|
+
|
54
|
+
lccn = StdNum::LCCN.normalize(rawlccn)
|
55
|
+
# => either the normalized lccn, or nil if it has bad syntax
|
56
|
+
|
57
|
+
if StdNum::LCCN.valid?(rawlccn) {
|
58
|
+
puts "#{rawlccn} is valid"
|
59
|
+
}
|
60
|
+
````
|
61
|
+
|
62
|
+
== CHANGES
|
63
|
+
|
64
|
+
* 1.0.0
|
65
|
+
* Added normalization all around.
|
66
|
+
* Added valid? for LCCN.
|
67
|
+
* Cleaner code all around, and better docs.
|
68
|
+
* 0.3.0
|
69
|
+
* Wow. ISBN-13 checkdigit wasn't changing '10' to '0'. Blatant error; bad coding *and* testing.
|
70
|
+
* 0.2.2
|
71
|
+
* Added ISSN.valid?
|
72
|
+
* Fixed error in ISSN.checksum when checksum was zero (was returning integer instead of string '0')
|
73
|
+
* 0.2.1
|
74
|
+
* Oops. Forgot to check to make sure there are *any* digits in the ISBN. fixed.
|
75
|
+
* 0.2.0
|
76
|
+
* Added allNormalizedValues for ISBN
|
77
|
+
* 0.1.0
|
78
|
+
* Initial release
|
79
|
+
|
80
|
+
== Note on Patches/Pull Requests
|
81
|
+
|
82
|
+
* Fork the project.
|
83
|
+
* Make your feature addition or bug fix.
|
84
|
+
* Add tests for it. This is important so I don't break it in a
|
85
|
+
future version unintentionally.
|
86
|
+
* Commit, do not mess with rakefile, version, or history.
|
87
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
88
|
+
* Send me a pull request. Bonus points for topic branches.
|
89
|
+
|
90
|
+
== Copyright
|
91
|
+
|
92
|
+
Copyright (c) 2010 Bill Dueber. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -10,7 +10,7 @@ begin
|
|
10
10
|
gem.email = "bill@dueber.com"
|
11
11
|
gem.homepage = "http://github.com/billdueber/library_stdnums"
|
12
12
|
gem.authors = ["Bill Dueber"]
|
13
|
-
gem.add_development_dependency "
|
13
|
+
gem.add_development_dependency "minitest", ">= 0" if RUBY_VERSION < "1.9"
|
14
14
|
gem.add_development_dependency "yard", ">= 0"
|
15
15
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
16
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0
|
data/lib/library_stdnums.rb
CHANGED
@@ -1,30 +1,53 @@
|
|
1
1
|
module StdNum
|
2
|
-
|
3
|
-
STDNUMPAT = /^.*?(\d[\d\-]+[xX]?)/
|
4
|
-
|
5
|
-
# Extract the most likely looking number from the string. This will be the first
|
6
|
-
# string of digits-and-hyphens-and-maybe-a-trailing-X, with the hypens removed
|
7
|
-
def self.extractNumber str
|
8
|
-
match = STDNUMPAT.match str
|
9
|
-
return nil unless match
|
10
|
-
return match[1].gsub(/\-/, '').upcase
|
11
|
-
end
|
12
2
|
|
3
|
+
module Helpers
|
4
|
+
|
5
|
+
STDNUMPAT = /^.*?(\d[\d\-]+[xX]?)/
|
13
6
|
|
7
|
+
# Extract the most likely looking number from the string. This will be the first
|
8
|
+
# string of digits-and-hyphens-and-maybe-a-trailing-X, with the hypens removed
|
9
|
+
def extractNumber str
|
10
|
+
match = STDNUMPAT.match str
|
11
|
+
return nil unless match
|
12
|
+
return match[1].gsub(/\-/, '').upcase
|
13
|
+
end
|
14
|
+
|
15
|
+
def reduce_to_basics rawnum, valid_sizes = nil
|
16
|
+
return nil if rawnum.nil?
|
17
|
+
|
18
|
+
num = extractNumber rawnum
|
19
|
+
|
20
|
+
# Does it even look like a number?
|
21
|
+
return nil unless num
|
22
|
+
|
23
|
+
# Return what we've got if we don't care about the size
|
24
|
+
return num unless valid_sizes
|
25
|
+
|
26
|
+
# Check for valid size(s)
|
27
|
+
[valid_sizes].flatten.each do |s|
|
28
|
+
return num if num.size == s
|
29
|
+
end
|
30
|
+
|
31
|
+
# Didn't check out size-wise. Return nil
|
32
|
+
return nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
14
36
|
|
15
37
|
module ISBN
|
38
|
+
extend Helpers
|
16
39
|
|
17
40
|
# Compute check digits for 10 or 13-digit ISBNs. See algorithm at
|
18
41
|
# http://en.wikipedia.org/wiki/International_Standard_Book_Number
|
19
42
|
# @param [String] isbn The ISBN (we'll try to clean it up if possible)
|
20
|
-
# @
|
21
|
-
|
22
|
-
|
43
|
+
# @param [Boolean] preprocessed Set to true if the ISBN has already been through reduce_to_basics
|
44
|
+
# @return [String,nil] the one-character checkdigit, or nil if it's not an ISBN string
|
45
|
+
def self.checkdigit isbn, preprocessed = false
|
46
|
+
isbn = reduce_to_basics isbn, [10,13] unless preprocessed
|
23
47
|
return nil unless isbn
|
24
|
-
|
25
|
-
return nil unless size == 10 or size == 13
|
48
|
+
|
26
49
|
checkdigit = 0
|
27
|
-
if size == 10
|
50
|
+
if isbn.size == 10
|
28
51
|
digits = isbn[0..8].split(//).map {|i| i.to_i}
|
29
52
|
(1..9).each do |i|
|
30
53
|
checkdigit += digits[i-1] * i
|
@@ -47,66 +70,83 @@ module StdNum
|
|
47
70
|
|
48
71
|
# Check to see if the checkdigit is correct
|
49
72
|
# @param [String] isbn The ISBN (we'll try to clean it up if possible)
|
73
|
+
# @param [Boolean] preprocessed Set to true if the ISBN has already been through reduce_to_basics
|
50
74
|
# @return [Boolean] Whether or not the checkdigit is correct
|
51
|
-
def self.valid? isbn
|
52
|
-
|
75
|
+
def self.valid? isbn, preprocessed = false
|
76
|
+
return nil if isbn.nil?
|
77
|
+
isbn = reduce_to_basics(isbn, [10,13]) unless preprocessed
|
53
78
|
return false unless isbn
|
54
|
-
|
55
|
-
return
|
56
|
-
return isbn[-1..-1] == self.checkdigit(isbn)
|
79
|
+
return false unless isbn[-1..-1] == self.checkdigit(isbn, true)
|
80
|
+
return true
|
57
81
|
end
|
58
82
|
|
83
|
+
|
84
|
+
# For an ISBN normalizing it is the same as converting to ISBN 13
|
85
|
+
# and making sure it's valid
|
86
|
+
# @param [String] isbn The ISBN to normalize
|
87
|
+
# @param [Boolean] passthrough On failure, return the original passed-in value instead of nil
|
88
|
+
# @return [String, nil] the normalized (to 13 digit) ISBN, or nil on failure
|
89
|
+
def self.normalize rawisbn
|
90
|
+
isbn = convert_to_13 rawisbn
|
91
|
+
if isbn and valid?(isbn, true)
|
92
|
+
return isbn
|
93
|
+
else
|
94
|
+
return nil
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
59
98
|
# To convert to an ISBN13, throw a '978' on the front and
|
60
99
|
# compute the checkdigit
|
61
|
-
# We leave 13-digit numbers alone, figuring they're already ok
|
100
|
+
# We leave 13-digit numbers alone, figuring they're already ok. NO CHECKSUM CHECK IS DONE FOR 13-DIGIT ISBNS!
|
62
101
|
# and return nil on anything that's not the right length
|
63
102
|
# @param [String] isbn The ISBN (we'll try to clean it up if possible)
|
64
|
-
# @return [String] The converted 13-character ISBN, nil if something looks wrong, or whatever was passed in if it already looked like a 13-digit ISBN
|
103
|
+
# @return [String, nil] The converted 13-character ISBN, nil if something looks wrong, or whatever was passed in if it already looked like a 13-digit ISBN
|
65
104
|
def self.convert_to_13 isbn
|
66
|
-
isbn =
|
105
|
+
isbn = reduce_to_basics isbn, [10,13]
|
67
106
|
return nil unless isbn
|
68
|
-
|
69
|
-
return isbn if size == 13
|
70
|
-
return nil unless size == 10
|
71
|
-
|
107
|
+
return isbn if isbn.size == 13
|
72
108
|
prefix = '978' + isbn[0..8]
|
73
|
-
return prefix + self.checkdigit(prefix + '0')
|
109
|
+
return prefix + self.checkdigit(prefix + '0', true)
|
74
110
|
end
|
75
|
-
|
76
|
-
|
111
|
+
|
112
|
+
|
77
113
|
# Convert to 10 if it's 13 digits and the first three digits are 978.
|
78
114
|
# Pass through anything 10-digits, and return nil for everything else.
|
79
115
|
# @param [String] isbn The ISBN (we'll try to clean it up if possible)
|
80
116
|
# @return [String] The converted 10-character ISBN, nil if something looks wrong, or whatever was passed in if it already looked like a 10-digit ISBN
|
81
117
|
def self.convert_to_10 isbn
|
82
|
-
isbn =
|
83
|
-
|
84
|
-
|
85
|
-
return isbn if size == 10
|
86
|
-
|
118
|
+
isbn = reduce_to_basics isbn, [10,13]
|
119
|
+
|
120
|
+
# Already 10 digits? Just return
|
121
|
+
return isbn if isbn.size == 10
|
122
|
+
|
123
|
+
# Can't be converted to ISBN-10? Bail
|
87
124
|
return nil unless isbn[0..2] == '978'
|
88
125
|
|
89
126
|
prefix = isbn[3..11]
|
90
127
|
return prefix + self.checkdigit(prefix + '0')
|
91
128
|
end
|
92
129
|
|
93
|
-
# Return an array of the
|
130
|
+
# Return an array of the ISBN13 and ISBN10 (in that order) for the passed in value. You'll
|
94
131
|
# only get one value back if it's a 13-digit
|
95
132
|
# ISBN that can't be converted to an ISBN10.
|
96
133
|
# @param [String] isbn The original ISBN, in 10-character or 13-digit format
|
97
|
-
# @return [Array] Either the (one or two) normalized ISBNs, or
|
134
|
+
# @return [Array<String,String>, nil] Either the (one or two) normalized ISBNs, or nil if
|
98
135
|
# it can't be recognized.
|
136
|
+
#
|
137
|
+
# @example Get the normalized values and index them (if valid) or original value (if not)
|
138
|
+
# norms = StdNum::ISBN.allNormalizedValues(rawisbn)
|
139
|
+
# doc['isbn'] = norms ? norms : [rawisbn]
|
140
|
+
|
99
141
|
|
100
142
|
def self.allNormalizedValues isbn
|
101
|
-
isbn =
|
143
|
+
isbn = reduce_to_basics isbn, [10,13]
|
102
144
|
return [] unless isbn
|
103
145
|
case isbn.size
|
104
146
|
when 10
|
105
|
-
return [
|
147
|
+
return [self.convert_to_13(isbn), isbn]
|
106
148
|
when 13
|
107
149
|
return [isbn, self.convert_to_10(isbn)].compact
|
108
|
-
else
|
109
|
-
return []
|
110
150
|
end
|
111
151
|
end
|
112
152
|
|
@@ -114,13 +154,17 @@ module StdNum
|
|
114
154
|
end
|
115
155
|
|
116
156
|
module ISSN
|
157
|
+
extend Helpers
|
117
158
|
|
118
159
|
# Compute the checkdigit of an ISSN
|
119
160
|
# @param [String] issn The ISSN (we'll try to clean it up if possible)
|
161
|
+
# @param [Boolean] preprocessed Set to true if the number has already been through reduce_to_basic
|
120
162
|
# @return [String] the one-character checkdigit
|
121
|
-
|
122
|
-
|
123
|
-
|
163
|
+
|
164
|
+
def self.checkdigit issn, preprocessed = false
|
165
|
+
issn = reduce_to_basics issn, 8 unless preprocessed
|
166
|
+
return nil unless issn
|
167
|
+
|
124
168
|
digits = issn[0..6].split(//).map {|i| i.to_i}
|
125
169
|
checkdigit = 0
|
126
170
|
(0..6).each do |i|
|
@@ -135,32 +179,93 @@ module StdNum
|
|
135
179
|
|
136
180
|
# Check to see if the checkdigit is correct
|
137
181
|
# @param [String] isbn The ISSN (we'll try to clean it up if possible)
|
182
|
+
# @param [Boolean] preprocessed Set to true if the number has already been through reduce_to_basic
|
138
183
|
# @return [Boolean] Whether or not the checkdigit is correct
|
139
|
-
|
140
|
-
|
184
|
+
|
185
|
+
def self.valid? issn, preprocessed = false
|
186
|
+
issn = reduce_to_basics issn, 8 unless preprocessed
|
141
187
|
return false unless issn
|
142
|
-
|
143
|
-
return false unless (size == 8)
|
144
|
-
return issn[-1..-1] == self.checkdigit(issn)
|
188
|
+
return issn[-1..-1] == self.checkdigit(issn, true)
|
145
189
|
end
|
146
190
|
|
191
|
+
def self.normalize rawissn
|
192
|
+
issn = reduce_to_basics rawissn, 8
|
193
|
+
if issn and valid?(issn, true)
|
194
|
+
return issn
|
195
|
+
else
|
196
|
+
return nil
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
|
147
201
|
|
148
202
|
end
|
149
203
|
|
150
204
|
module LCCN
|
205
|
+
|
206
|
+
# The rules for validity according to http://www.loc.gov/marc/lccn-namespace.html#syntax:
|
207
|
+
#
|
208
|
+
# A normalized LCCN is a character string eight to twelve characters in length. (For purposes of this description characters are ordered from left to right -- "first" means "leftmost".)
|
209
|
+
# The rightmost eight characters are always digits.
|
210
|
+
# If the length is 9, then the first character must be alphabetic.
|
211
|
+
# If the length is 10, then the first two characters must be either both digits or both alphabetic.
|
212
|
+
# If the length is 11, then the first character must be alphabetic and the next two characters must be either both digits or both alphabetic.
|
213
|
+
# If the length is 12, then the first two characters must be alphabetic and the remaining characters digits.
|
214
|
+
#
|
215
|
+
# @param [String] lccn The lccn to attempt to validate
|
216
|
+
# @param [Boolean] preprocessed Set to true if the number has already been normalized
|
217
|
+
# @return [Boolean] Whether or not the syntax seems ok
|
218
|
+
|
219
|
+
def self.reduce_to_basic str
|
220
|
+
str.gsub!(/\s/, '') # ditch leading spaces
|
221
|
+
str.gsub!(/\/.*$/, '') # ditch everything after the first '/' (including the slash)
|
222
|
+
return str
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
def self.valid? lccn, preprocessed = false
|
227
|
+
lccn = normalize(lccn) unless preprocessed
|
228
|
+
return false unless (8..12).include? lccn.size
|
229
|
+
clean = lccn.gsub(/\-/, '')
|
230
|
+
suffix = clean[-8..-1]
|
231
|
+
prefix = clean[0..-9]
|
232
|
+
return false unless suffix =~ /^\d+$/
|
233
|
+
case clean.size
|
234
|
+
when 8
|
235
|
+
return true
|
236
|
+
when 9
|
237
|
+
return true if prefix =~ /[A-Za-z]/
|
238
|
+
when 10
|
239
|
+
return true if prefix =~ /\d{2}/ or prefix =~ /[A-Za-z]{2}/
|
240
|
+
when 11
|
241
|
+
return true if prefix =~ /[A-Za-z](\d{2}|[A-Za-z]{2})/
|
242
|
+
when 12
|
243
|
+
return true if prefix =~ /[A-Za-z]{2}\d{2}/
|
244
|
+
else
|
245
|
+
return false
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
|
250
|
+
|
151
251
|
# Normalize based on data at http://www.loc.gov/marc/lccn-namespace.html#syntax
|
152
252
|
# @param [String] str The LCCN to normalize
|
153
253
|
# @return [String] the normalized LCCN, or nil if it looks malformed
|
154
|
-
def self.normalize
|
155
|
-
|
156
|
-
|
157
|
-
if
|
254
|
+
def self.normalize rawlccn
|
255
|
+
lccn = reduce_to_basic(rawlccn)
|
256
|
+
# If there's a dash in it, deal with that.
|
257
|
+
if lccn =~ /^(.*?)\-(.+)/
|
158
258
|
pre = $1
|
159
259
|
post = $2
|
160
260
|
return nil unless post =~ /^\d+$/ # must be all digits
|
161
|
-
|
261
|
+
lccn = "%s%06d" % [pre, post.to_i]
|
262
|
+
end
|
263
|
+
|
264
|
+
if valid?(lccn, true)
|
265
|
+
return lccn
|
266
|
+
else
|
267
|
+
return nil
|
162
268
|
end
|
163
|
-
return str
|
164
269
|
end
|
165
270
|
end
|
166
271
|
|
@@ -2,31 +2,31 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe "Extract" do
|
4
4
|
it "should leave a number alone" do
|
5
|
-
StdNum.extractNumber('123456').
|
5
|
+
StdNum::ISBN.extractNumber('123456').must_equal '123456'
|
6
6
|
end
|
7
7
|
|
8
8
|
it "should skip leading and trailing crap" do
|
9
|
-
StdNum.extractNumber(' 12345 (online)').
|
9
|
+
StdNum::ISBN.extractNumber(' 12345 (online)').must_equal '12345'
|
10
10
|
end
|
11
11
|
|
12
12
|
it "should allow hyphens" do
|
13
|
-
StdNum.extractNumber(' 1-234-5').
|
13
|
+
StdNum::ISBN.extractNumber(' 1-234-5').must_equal '12345'
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should return nil on a non-match" do
|
17
|
-
StdNum.extractNumber('bill dueber').
|
17
|
+
StdNum::ISBN.extractNumber('bill dueber').must_equal nil
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should allow a trailing X" do
|
21
|
-
StdNum.extractNumber('1-234-5-X').
|
21
|
+
StdNum::ISBN.extractNumber('1-234-5-X').must_equal '12345X'
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should upcase any trailing X" do
|
25
|
-
StdNum.extractNumber('1-234-x').
|
25
|
+
StdNum::ISBN.extractNumber('1-234-x').must_equal '1234X'
|
26
26
|
end
|
27
27
|
|
28
28
|
it "only allows a single trailing X" do
|
29
|
-
StdNum.extractNumber('1234-X-X').
|
29
|
+
StdNum::ISBN.extractNumber('1234-X-X').must_equal '1234X'
|
30
30
|
end
|
31
31
|
|
32
32
|
end
|
@@ -34,52 +34,52 @@ end
|
|
34
34
|
|
35
35
|
describe "ISBN" do
|
36
36
|
it "computes 10-digit checksum" do
|
37
|
-
StdNum::ISBN.checkdigit('0-306-40615-X').
|
37
|
+
StdNum::ISBN.checkdigit('0-306-40615-X').must_equal '2'
|
38
38
|
end
|
39
39
|
|
40
40
|
it "correctly uses X for checksum" do
|
41
|
-
StdNum::ISBN.checkdigit('061871460X').
|
41
|
+
StdNum::ISBN.checkdigit('061871460X').must_equal 'X'
|
42
42
|
end
|
43
43
|
|
44
44
|
it "finds a zero checkdigit" do
|
45
|
-
StdNum::ISBN.checkdigit('0139381430').
|
45
|
+
StdNum::ISBN.checkdigit('0139381430').must_equal '0'
|
46
46
|
end
|
47
47
|
|
48
48
|
it "computes 13-digit checksum" do
|
49
|
-
StdNum::ISBN.checkdigit('9780306406157').
|
49
|
+
StdNum::ISBN.checkdigit('9780306406157').must_equal '7'
|
50
50
|
end
|
51
51
|
|
52
52
|
it "computes a 13-digit checksum that is 0" do
|
53
|
-
StdNum::ISBN.checkdigit('9783837612950').
|
53
|
+
StdNum::ISBN.checkdigit('9783837612950').must_equal '0'
|
54
54
|
end
|
55
55
|
|
56
56
|
it "finds a good number valid" do
|
57
|
-
StdNum::ISBN.valid?('9780306406157').
|
57
|
+
StdNum::ISBN.valid?('9780306406157').must_equal true
|
58
58
|
end
|
59
59
|
|
60
60
|
it "finds a bad number invalid" do
|
61
|
-
StdNum::ISBN.valid?('9780306406154').
|
61
|
+
StdNum::ISBN.valid?('9780306406154').must_equal false
|
62
62
|
end
|
63
63
|
|
64
64
|
it "returns nil when computing checksum for bad ISBN" do
|
65
|
-
StdNum::ISBN.checkdigit('12345').
|
65
|
+
StdNum::ISBN.checkdigit('12345').must_equal nil
|
66
66
|
end
|
67
67
|
|
68
68
|
it "converts 10 to 13" do
|
69
|
-
StdNum::ISBN.convert_to_13('0-306-40615-2').
|
69
|
+
StdNum::ISBN.convert_to_13('0-306-40615-2').must_equal '9780306406157'
|
70
70
|
end
|
71
71
|
|
72
72
|
it "passes through 13 digit number instead of converting to 13" do
|
73
|
-
StdNum::ISBN.convert_to_13('9780306406157').
|
73
|
+
StdNum::ISBN.convert_to_13('9780306406157').must_equal '9780306406157'
|
74
74
|
end
|
75
75
|
|
76
76
|
it "converts 13 to 10" do
|
77
|
-
StdNum::ISBN.convert_to_10('978-0-306-40615-7').
|
77
|
+
StdNum::ISBN.convert_to_10('978-0-306-40615-7').must_equal '0306406152'
|
78
78
|
end
|
79
79
|
|
80
80
|
it "gets both normalized values" do
|
81
81
|
a = StdNum::ISBN.allNormalizedValues('978-0-306-40615-7')
|
82
|
-
a.sort.
|
82
|
+
a.sort.must_equal ['9780306406157', '0306406152' ].sort
|
83
83
|
end
|
84
84
|
|
85
85
|
|
@@ -90,7 +90,11 @@ end
|
|
90
90
|
|
91
91
|
describe 'ISSN' do
|
92
92
|
it "computes checksum" do
|
93
|
-
StdNum::ISSN.checkdigit('0378-5955').
|
93
|
+
StdNum::ISSN.checkdigit('0378-5955').must_equal '5'
|
94
|
+
end
|
95
|
+
|
96
|
+
it "normalizes" do
|
97
|
+
StdNum::ISSN.normalize('0378-5955').must_equal '03785955'
|
94
98
|
end
|
95
99
|
end
|
96
100
|
|
@@ -106,12 +110,12 @@ describe 'LCCN' do
|
|
106
110
|
"85-2 " => "85000002",
|
107
111
|
"2001-000002" => "2001000002",
|
108
112
|
"75-425165//r75" => "75425165",
|
109
|
-
" 79139101 /AC/r932" => "79139101"
|
113
|
+
" 79139101 /AC/r932" => "79139101",
|
110
114
|
}
|
111
115
|
|
112
116
|
test.each do |k, v|
|
113
117
|
it "normalizes #{k}" do
|
114
|
-
StdNum::LCCN.normalize(k.dup).
|
118
|
+
StdNum::LCCN.normalize(k.dup).must_equal v
|
115
119
|
end
|
116
120
|
end
|
117
121
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require 'bacon'
|
3
2
|
begin
|
4
|
-
|
3
|
+
gem 'minitest'
|
5
4
|
rescue LoadError
|
6
5
|
end
|
7
|
-
|
8
|
-
|
6
|
+
|
7
|
+
require 'minitest/spec'
|
8
|
+
require 'minitest/autorun'
|
9
|
+
|
9
10
|
require 'library_stdnums'
|
10
11
|
|
11
|
-
Bacon.summary_on_exit
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: library_stdnums
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 3
|
9
|
-
- 0
|
10
|
-
version: 0.3.0
|
4
|
+
prerelease:
|
5
|
+
version: 1.0.0
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Bill Dueber
|
@@ -15,37 +10,20 @@ autorequire:
|
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
12
|
|
18
|
-
date: 2011-
|
13
|
+
date: 2011-05-06 00:00:00 -04:00
|
19
14
|
default_executable:
|
20
15
|
dependencies:
|
21
16
|
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
17
|
+
name: yard
|
23
18
|
prerelease: false
|
24
19
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
20
|
none: false
|
26
21
|
requirements:
|
27
22
|
- - ">="
|
28
23
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
|
-
segments:
|
31
|
-
- 0
|
32
24
|
version: "0"
|
33
25
|
type: :development
|
34
26
|
version_requirements: *id001
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: yard
|
37
|
-
prerelease: false
|
38
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
-
none: false
|
40
|
-
requirements:
|
41
|
-
- - ">="
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
hash: 3
|
44
|
-
segments:
|
45
|
-
- 0
|
46
|
-
version: "0"
|
47
|
-
type: :development
|
48
|
-
version_requirements: *id002
|
49
27
|
description: Normalization and checksum computation for ISBN (10 and 13), ISSN, and LCCN
|
50
28
|
email: bill@dueber.com
|
51
29
|
executables: []
|
@@ -54,13 +32,11 @@ extensions: []
|
|
54
32
|
|
55
33
|
extra_rdoc_files:
|
56
34
|
- LICENSE
|
57
|
-
- README.
|
35
|
+
- README.markdown
|
58
36
|
files:
|
59
37
|
- .document
|
60
|
-
- .gitignore
|
61
|
-
- CHANGES
|
62
38
|
- LICENSE
|
63
|
-
- README.
|
39
|
+
- README.markdown
|
64
40
|
- Rakefile
|
65
41
|
- VERSION
|
66
42
|
- lib/library_stdnums.rb
|
@@ -71,8 +47,8 @@ homepage: http://github.com/billdueber/library_stdnums
|
|
71
47
|
licenses: []
|
72
48
|
|
73
49
|
post_install_message:
|
74
|
-
rdoc_options:
|
75
|
-
|
50
|
+
rdoc_options: []
|
51
|
+
|
76
52
|
require_paths:
|
77
53
|
- lib
|
78
54
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -80,26 +56,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
80
56
|
requirements:
|
81
57
|
- - ">="
|
82
58
|
- !ruby/object:Gem::Version
|
83
|
-
hash: 3
|
84
|
-
segments:
|
85
|
-
- 0
|
86
59
|
version: "0"
|
87
60
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
61
|
none: false
|
89
62
|
requirements:
|
90
63
|
- - ">="
|
91
64
|
- !ruby/object:Gem::Version
|
92
|
-
hash: 3
|
93
|
-
segments:
|
94
|
-
- 0
|
95
65
|
version: "0"
|
96
66
|
requirements: []
|
97
67
|
|
98
68
|
rubyforge_project:
|
99
|
-
rubygems_version: 1.
|
69
|
+
rubygems_version: 1.5.2
|
100
70
|
signing_key:
|
101
71
|
specification_version: 3
|
102
72
|
summary: Normalize and compute checkdigits for ISBN, ISSN, and LCCN
|
103
|
-
test_files:
|
104
|
-
|
105
|
-
- spec/spec_helper.rb
|
73
|
+
test_files: []
|
74
|
+
|
data/.gitignore
DELETED
data/CHANGES
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
0.3.0
|
2
|
-
Wow. ISBN-13 checkdigit wasn't changing '10' to '0'. Blatant error; bad coding *and* testing.
|
3
|
-
0.2.2
|
4
|
-
Added ISSN.valid?
|
5
|
-
Fixed error in ISSN.checksum when checksum was zero (was returning integer instead of string '0')
|
6
|
-
0.2.1
|
7
|
-
Oops. Forgot to check to make sure there are *any* digits in the ISBN. fixed.
|
8
|
-
0.2.0
|
9
|
-
Added allNormalizedValues for ISBN
|
data/README.rdoc
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
= library_stdnums
|
2
|
-
|
3
|
-
Do common operations on ISBNs, ISSN, and LCCNs.
|
4
|
-
|
5
|
-
What's supported:
|
6
|
-
|
7
|
-
* *ISBN* Compute or validate checkdigit; convert to/from ISBN-10 and ISBN-13
|
8
|
-
* *ISSN* Compute or validate checkdigit
|
9
|
-
* *LCCN* Normalize
|
10
|
-
|
11
|
-
== Note on Patches/Pull Requests
|
12
|
-
|
13
|
-
* Fork the project.
|
14
|
-
* Make your feature addition or bug fix.
|
15
|
-
* Add tests for it. This is important so I don't break it in a
|
16
|
-
future version unintentionally.
|
17
|
-
* Commit, do not mess with rakefile, version, or history.
|
18
|
-
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
19
|
-
* Send me a pull request. Bonus points for topic branches.
|
20
|
-
|
21
|
-
== Copyright
|
22
|
-
|
23
|
-
Copyright (c) 2010 Bill Dueber. See LICENSE for details.
|