bookland 0.1.0 → 0.2.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/.gitignore +3 -3
- data/History.md +6 -0
- data/README.md +6 -4
- data/VERSION +1 -1
- data/lib/bookland.rb +37 -24
- data/spec/bookland_spec.rb +59 -49
- metadata +4 -3
data/.gitignore
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
.DS_Store
|
2
|
-
pkg
|
3
|
-
|
1
|
+
.DS_Store
|
2
|
+
pkg
|
3
|
+
|
data/History.md
ADDED
data/README.md
CHANGED
@@ -6,10 +6,12 @@ Bookland provides a simple ISBN class in Ruby.
|
|
6
6
|
>> include Bookland
|
7
7
|
>> book = ISBN.new("0262011530")
|
8
8
|
>> book.to_isbn13
|
9
|
-
=> 9780262011532
|
10
|
-
>> book.to_s(1,3,5)
|
9
|
+
=> "9780262011532"
|
10
|
+
>> book.to_s(1, 3, 5)
|
11
11
|
=> "0-262-01153-0"
|
12
12
|
>> ISBN.new("9780262011532") == book
|
13
13
|
=> true
|
14
|
-
>> ISBN.new("0262011531") # This is an invalid ISBN
|
15
|
-
|
14
|
+
>> invalid_book = ISBN.new("0262011531") # This is an invalid ISBN
|
15
|
+
=> false
|
16
|
+
>> invalid_book.to_isbn13
|
17
|
+
=> Bookland::ISBNError: ISBN not valid
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/bookland.rb
CHANGED
@@ -1,45 +1,67 @@
|
|
1
1
|
module Bookland
|
2
|
+
|
3
|
+
# A simple ISBN class
|
2
4
|
class ISBN
|
3
|
-
def
|
4
|
-
|
5
|
-
raise ISBNError unless valid?
|
5
|
+
def ==(other)
|
6
|
+
self.to_isbn13.to_s == other.to_isbn13.to_s
|
6
7
|
end
|
7
|
-
|
8
|
+
|
9
|
+
def initialize(seed=nil)
|
10
|
+
self.seed = seed
|
11
|
+
end
|
12
|
+
|
8
13
|
def inspect
|
9
14
|
to_s
|
10
15
|
end
|
11
16
|
|
17
|
+
def seed=(seed)
|
18
|
+
@raw = seed.gsub(/[^Xx0-9]/, '').split(//) rescue @raw = []
|
19
|
+
end
|
20
|
+
|
12
21
|
def to_isbn10
|
22
|
+
raise ISBNError unless valid?
|
23
|
+
|
13
24
|
if isbn13?
|
14
25
|
raw = @raw[3..11]
|
15
|
-
ISBN.new((raw <<
|
26
|
+
ISBN.new((raw << check_digit_10(raw)).to_s)
|
16
27
|
else
|
17
28
|
self.dup
|
18
29
|
end
|
19
30
|
end
|
20
31
|
|
21
32
|
def to_isbn13
|
33
|
+
raise ISBNError unless valid?
|
34
|
+
|
22
35
|
if isbn10?
|
23
36
|
raw = @raw[0..8].unshift('9', '7', '8')
|
24
|
-
ISBN.new((raw <<
|
37
|
+
ISBN.new((raw << check_digit_13(raw)).to_s)
|
25
38
|
else
|
26
39
|
self.dup
|
27
40
|
end
|
28
41
|
end
|
29
42
|
|
30
|
-
def ==(other)
|
31
|
-
self.to_isbn13.to_s == other.to_isbn13.to_s
|
32
|
-
end
|
33
|
-
|
34
43
|
def to_s(*blocks)
|
44
|
+
return false unless valid?
|
45
|
+
|
35
46
|
raw = @raw.dup
|
36
47
|
blocks.any? ? (blocks.map { |i| raw.shift(i).to_s } << raw.to_s).delete_if(&:empty?).join('-') : raw.to_s
|
37
48
|
end
|
38
49
|
|
50
|
+
def valid?
|
51
|
+
if isbn10?
|
52
|
+
@raw[9] == check_digit_10(@raw)
|
53
|
+
elsif isbn13?
|
54
|
+
@raw[12] == check_digit_13(@raw)
|
55
|
+
else
|
56
|
+
false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
39
60
|
private
|
40
61
|
|
41
|
-
def
|
42
|
-
cd = 11 -
|
62
|
+
def check_digit_10(raw)
|
63
|
+
cd = 11 - 10.downto(2).to_a.zip(raw[0..8].map(&:to_i)).map { |n,m| n * m }.inject(0) { |i,j| i + j } % 11
|
64
|
+
|
43
65
|
case cd
|
44
66
|
when 0..9 then cd.to_s
|
45
67
|
when 10 then 'X'
|
@@ -47,8 +69,8 @@ module Bookland
|
|
47
69
|
end
|
48
70
|
end
|
49
71
|
|
50
|
-
def
|
51
|
-
((10 - [1, 3
|
72
|
+
def check_digit_13(raw)
|
73
|
+
((10 - ([1, 3] * 6).zip(raw[0..11].map(&:to_i)).map { |n,m| n * m }.inject(0) { |i,j| i + j } % 10) % 10).to_s
|
52
74
|
end
|
53
75
|
|
54
76
|
def isbn10?
|
@@ -58,18 +80,9 @@ module Bookland
|
|
58
80
|
def isbn13?
|
59
81
|
@raw.length == 13
|
60
82
|
end
|
61
|
-
|
62
|
-
def valid?
|
63
|
-
if isbn10?
|
64
|
-
@raw[9] == cd10(@raw)
|
65
|
-
elsif isbn13?
|
66
|
-
@raw[12] == cd13(@raw)
|
67
|
-
else
|
68
|
-
false
|
69
|
-
end
|
70
|
-
end
|
71
83
|
end
|
72
84
|
|
85
|
+
# A simple error wrapper for a simple ISBN class
|
73
86
|
class ISBNError < StandardError
|
74
87
|
def initialize(msg='ISBN not valid')
|
75
88
|
super
|
data/spec/bookland_spec.rb
CHANGED
@@ -9,65 +9,75 @@ module Bookland
|
|
9
9
|
end
|
10
10
|
|
11
11
|
it "should convert an ISBN-13 to ISBN-10" do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
isbns do |isbn10, isbn13|
|
13
|
+
ISBN.new(isbn13).to_isbn10.should == ISBN.new(isbn10)
|
14
|
+
end
|
15
|
+
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
it "should equate ISBN-10 and ISBN-13" do
|
18
|
+
isbns do |isbn10, isbn13|
|
19
|
+
ISBN.new(isbn10).should == ISBN.new(isbn13)
|
20
|
+
end
|
21
|
+
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
it "should validate ISBN-10s" do
|
24
|
+
isbns do |isbn10, isbn13|
|
25
|
+
ISBN.new(isbn10).valid?.should be_true
|
26
|
+
end
|
27
|
+
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
it "should validate ISBN-13s" do
|
30
|
+
isbns do |isbn10, isbn13|
|
31
|
+
ISBN.new(isbn13).valid?.should be_true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should not validate if seed looks like an ISBN-13 but has an invalid check digit" do
|
36
|
+
isbns do |isbn10, isbn13|
|
37
|
+
invalid = isbn13.gsub(/(.)$/, "#{(isbn13.split(//).last.to_i - 2) % 10}")
|
38
|
+
ISBN.new(invalid).valid?.should be_false
|
39
|
+
end
|
40
|
+
end
|
34
41
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
42
|
+
it "should not validate if seed looks like an ISBN-10 but has an invalid check digit" do
|
43
|
+
isbns do |isbn10, isbn13|
|
44
|
+
invalid = isbn10.gsub(/(.)$/, "#{(isbn10.split(//).last.to_i - 2) % 10}")
|
45
|
+
ISBN.new(invalid).valid?.should be_false
|
46
|
+
end
|
47
|
+
end
|
41
48
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
lambda { ISBN.new(inv) }.should raise_error ISBNError
|
46
|
-
end
|
47
|
-
end
|
49
|
+
it "should not validate if seed is not an ISBN" do
|
50
|
+
['foo', 1, '', nil].each { |seed| ISBN.new(seed).valid?.should be_false }
|
51
|
+
end
|
48
52
|
|
49
|
-
|
50
|
-
|
51
|
-
|
53
|
+
it "should cast as string" do
|
54
|
+
Bookland::ISBN.new('0262011530').to_s.should == '0262011530'
|
55
|
+
end
|
52
56
|
|
53
|
-
|
54
|
-
|
55
|
-
|
57
|
+
it "should cast as string and hyphenate an ISBN-13" do
|
58
|
+
ISBN.new("9780485113358").to_s(3, 10).should == '978-0485113358'
|
59
|
+
end
|
56
60
|
|
57
|
-
|
58
|
-
|
59
|
-
|
61
|
+
it "should cast as string and hyphenate an ISBN-10" do
|
62
|
+
ISBN.new("048511335X").to_s(1, 3, 5, 1).should == '0-485-11335-X'
|
63
|
+
end
|
60
64
|
|
61
|
-
|
62
|
-
|
63
|
-
|
65
|
+
it "should return false if an invalid ISBN is cast as string" do
|
66
|
+
['foo', 1, '', nil].each { |seed| ISBN.new(seed).to_s.should be_false }
|
67
|
+
end
|
64
68
|
|
65
|
-
|
66
|
-
|
67
|
-
|
69
|
+
it "should raise an error if an invalid ISBN-13 is converted to ISBN-10" do
|
70
|
+
isbns do |isbn10, isbn13|
|
71
|
+
invalid = isbn13.gsub(/(.)$/, "#{(isbn13.split(//).last.to_i - 2) % 10}")
|
72
|
+
lambda { ISBN.new(invalid).to_isbn10 }.should raise_error ISBNError
|
73
|
+
end
|
74
|
+
end
|
68
75
|
|
69
|
-
|
70
|
-
|
71
|
-
|
76
|
+
it "should raise an error if an invalid ISBN-10 is converted to ISBN-13" do
|
77
|
+
isbns do |isbn10, isbn13|
|
78
|
+
invalid = isbn10.gsub(/(.)$/, "#{(isbn10.split(//).last.to_i - 2) % 10}")
|
79
|
+
lambda { ISBN.new(invalid).to_isbn13 }.should raise_error ISBNError
|
80
|
+
end
|
81
|
+
end
|
72
82
|
end
|
73
83
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 2
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Hakan Ensari
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-04-
|
18
|
+
date: 2010-04-28 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -30,6 +30,7 @@ extra_rdoc_files:
|
|
30
30
|
- README.md
|
31
31
|
files:
|
32
32
|
- .gitignore
|
33
|
+
- History.md
|
33
34
|
- LICENSE
|
34
35
|
- README.md
|
35
36
|
- Rakefile
|