marc_alephsequential 0.1.0 → 0.1.1
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.
- checksums.yaml +5 -13
- data/ChangeLog.md +4 -0
- data/Gemfile +4 -2
- data/README.md +1 -1
- data/Rakefile +0 -2
- data/lib/marc_alephsequential/asline.rb +53 -56
- data/lib/marc_alephsequential/asline_group.rb +25 -26
- data/lib/marc_alephsequential/asline_reader.rb +2 -2
- data/lib/marc_alephsequential/buffered_linereader.rb +33 -34
- data/lib/marc_alephsequential/error.rb +4 -4
- data/lib/marc_alephsequential/log.rb +6 -6
- data/lib/marc_alephsequential/reader.rb +17 -18
- data/lib/marc_alephsequential/version.rb +2 -1
- data/spec/asline_group_spec.rb +13 -12
- data/spec/asline_spec.rb +11 -11
- data/spec/helper.rb +2 -4
- data/spec/reader_spec.rb +9 -10
- data/spec/version_spec.rb +0 -1
- metadata +11 -12
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NmMwMWQzMTIzMmQ3ZmNlOTM5YjRiMGFmZTI2MTA3NmM0Njk0ZTJiYg==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9fa0b67408536b4221359c3a268ea99925ba55c9
|
4
|
+
data.tar.gz: 5ab21aa3f34c6b24af9fddc7e64c4eeab7f5ddac
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
OTM4ZDBhMTA3ZDZiYmY0YWU3M2I5NWM5MzBlYjhkY2QxNGZhNDdhMDAyM2Qx
|
11
|
-
MjQ4YWFiNTkxMjhmODk3Mzc0YjIzMGVlMzVmYzRlOTc0Y2Y3YmE=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
OWZmOGVkYWVkZTM4ZGQ1YmM1NGMzNzBkM2IwY2I4NmZmMmI1OTYzN2FhMTQw
|
14
|
-
NDcwMDQ0Zjk3MzdiZWQxN2M1ZmQzMGRhYWFkNTg5NGFiNTY4Yjk4N2JiMTFi
|
15
|
-
ZWEyZjJkMThkY2RlM2VjYmZhNTQ1NmYxYzM5NDhlN2QyOGY3MGE=
|
6
|
+
metadata.gz: 85513438e1ba85f181543bf83b67b9f34f7d09b06f262c6f890a7d4bce95014e00cfded966a1294d9a9de341883e1f55a41d881e5c7c2cd4ee7e7fbb35f6776a
|
7
|
+
data.tar.gz: 901c12d9c9830fccc112ebe89f9d77cc4708dad2f91dff6c685902c92921975a5c32eaa3cc4f4118ffd31a0de17c58f38ea22c4ce39cc44a41070d540f3668f1
|
data/ChangeLog.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
data/Rakefile
CHANGED
@@ -4,64 +4,64 @@ require_relative 'log'
|
|
4
4
|
|
5
5
|
module MARC
|
6
6
|
module AlephSequential
|
7
|
-
|
8
|
-
|
7
|
+
|
8
|
+
|
9
9
|
# A model of a line (field) in an alephsequential file.
|
10
10
|
class ASLine
|
11
|
-
|
11
|
+
|
12
12
|
include Log
|
13
13
|
|
14
14
|
# Characters in leader/control fields that need to be turned (back) into spaces
|
15
|
-
TURN_TO_SPACE
|
15
|
+
TURN_TO_SPACE = /\^/
|
16
16
|
|
17
|
-
# Pattern used to split data field values into subfield code/value pairs
|
17
|
+
# Pattern used to split data field values into subfield code/value pairs
|
18
18
|
SUBFIELD_SPLIT_PATTERN = /\$\$([a-zA-Z0-9])/
|
19
|
-
|
19
|
+
|
20
20
|
# How to know if we have a valid id? Must be 9 digits
|
21
|
-
VALID_ID
|
22
|
-
|
21
|
+
VALID_ID = /^\d{9}$/
|
22
|
+
|
23
23
|
# The passed in raw string, used for post-processing later on
|
24
24
|
attr_accessor :rawstr
|
25
|
-
|
25
|
+
|
26
26
|
# The line number in the file/stream, for error reporting
|
27
27
|
attr_accessor :line_number
|
28
|
-
|
28
|
+
|
29
29
|
# Either the value of a control/fiexed field, or a string representation of a datafield's subfield
|
30
30
|
attr_accessor :value
|
31
|
-
|
31
|
+
|
32
32
|
# The type of field (:leader, :control, :data, or :invalid_id)
|
33
33
|
attr_accessor :type
|
34
|
-
|
35
|
-
attr_accessor :id,
|
34
|
+
|
35
|
+
attr_accessor :id, :tag, :ind1, :ind2
|
36
36
|
|
37
37
|
# The MARC field's tag
|
38
38
|
attr_reader :tag
|
39
|
-
|
40
|
-
|
39
|
+
|
40
|
+
|
41
41
|
# Given a raw string and a line number, construct the appropriate ASLine.
|
42
|
-
#
|
43
|
-
# @param [String] rawstr The raw string from the file
|
42
|
+
#
|
43
|
+
# @param [String] rawstr The raw string from the file
|
44
44
|
# @param [Number] line_number The line number from the file/stream, for error reporting
|
45
|
-
|
45
|
+
|
46
46
|
def initialize(rawstr, line_number)
|
47
|
-
@rawstr
|
47
|
+
@rawstr = rawstr.chomp
|
48
48
|
@line_number = line_number
|
49
|
-
|
50
|
-
(self.id,self.tag,self.ind1,self.ind2,self.value) = *(parseline(@rawstr))
|
51
|
-
|
49
|
+
|
50
|
+
(self.id, self.tag, self.ind1, self.ind2, self.value) = *(parseline(@rawstr))
|
51
|
+
|
52
52
|
# clean up the leader or fixed fields
|
53
53
|
if [:leader, :control].include? self.type
|
54
54
|
self.value = cleanup_fixed(self.value)
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
end
|
58
|
-
|
59
|
-
# Does this line have a valid (-looking) id?
|
58
|
+
|
59
|
+
# Does this line have a valid (-looking) id?
|
60
60
|
def valid_id?
|
61
61
|
return VALID_ID.match(id) ? true : false
|
62
62
|
end
|
63
|
-
|
64
|
-
|
63
|
+
|
64
|
+
|
65
65
|
# Turn it into an actual MARC field (control or data)
|
66
66
|
# Throw an error if called on a leader (LDR) line
|
67
67
|
# @return [MARC::ControlField, MARC::DataField]
|
@@ -72,16 +72,16 @@ module MARC
|
|
72
72
|
when :data
|
73
73
|
self.to_data_field
|
74
74
|
else
|
75
|
-
raise MARC::AlephSequential::Error.new(id, line_number
|
75
|
+
raise MARC::AlephSequential::Error.new(id, line_number), "Tried to call #to_field on line type '#{self.type}'", nil
|
76
76
|
end
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
# Turn the current object into a control field, without doing any checks
|
80
80
|
# @return [MARC::ControlField]
|
81
81
|
def to_control_field
|
82
82
|
MARC::ControlField.new(tag, cleanup_fixed(self.value))
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
# Turn the current object into a datafield, without doing any checks
|
86
86
|
# @return [MARC::DataField]
|
87
87
|
def to_data_field
|
@@ -90,38 +90,38 @@ module MARC
|
|
90
90
|
self.value = '$$a' + self.value
|
91
91
|
end
|
92
92
|
|
93
|
-
subfields
|
94
|
-
f
|
93
|
+
subfields = parse_string_into_subfields(value)
|
94
|
+
f = MARC::DataField.new(tag, ind1, ind2)
|
95
95
|
f.subfields = subfields
|
96
96
|
return f
|
97
|
-
end
|
98
|
-
|
97
|
+
end
|
98
|
+
|
99
99
|
# Parse out a non-controlfield value string into a set of subfields
|
100
100
|
# @param [String] val the value string, of the form "$$athis is the a$$band the b"
|
101
101
|
# @return [Array<Subfield>] An array of MARC subfields
|
102
102
|
#
|
103
103
|
# If the first value in the array returned by the split isn't the empty string, then
|
104
|
-
# the string didn't start with '$$' and we should throw a warning
|
104
|
+
# the string didn't start with '$$' and we should throw a warning
|
105
105
|
# (and put the value into a subfield 'a' if we're running in flexible mode)
|
106
|
-
|
106
|
+
|
107
107
|
def parse_string_into_subfields(val)
|
108
|
-
sfpairs
|
108
|
+
sfpairs = val.split(SUBFIELD_SPLIT_PATTERN)
|
109
109
|
initial_null_string = sfpairs.shift
|
110
110
|
unless initial_null_string == ''
|
111
111
|
# do something about the error
|
112
112
|
end
|
113
|
-
|
114
|
-
sfpairs.each_slice(2).map {|code, val| MARC::Subfield.new(code, val) }
|
115
|
-
|
113
|
+
|
114
|
+
sfpairs.each_slice(2).map { |code, val| MARC::Subfield.new(code, val) }
|
115
|
+
|
116
116
|
end
|
117
|
-
|
117
|
+
|
118
118
|
# Clean up fixed fields/leader, turning Ex Libris characters back into normal characters
|
119
119
|
# @param [String] val The string to clean
|
120
120
|
# @return [String] The cleaned string
|
121
121
|
def cleanup_fixed(val)
|
122
122
|
return val.gsub(TURN_TO_SPACE, ' ')
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
# Set the tag. As a side effect, set the type when we set the tag
|
126
126
|
# type will end up as :leader, :control, :data, or :invalid_id
|
127
127
|
def tag=(t)
|
@@ -136,26 +136,23 @@ module MARC
|
|
136
136
|
self.type = :invalid_id
|
137
137
|
end
|
138
138
|
end
|
139
|
-
|
140
|
-
|
139
|
+
|
140
|
+
|
141
141
|
# Get a line and parse it out into its componant parts
|
142
142
|
# @param [String] line the line to parse
|
143
143
|
# @return [Array] An array of the form [id, tag, ind1, ind2, value]
|
144
|
-
|
144
|
+
|
145
145
|
def parseline(line)
|
146
|
-
id
|
147
|
-
tag
|
148
|
-
ind1
|
149
|
-
ind2
|
146
|
+
id = line[0, 9]
|
147
|
+
tag = line[10, 3]
|
148
|
+
ind1 = line[13, 1]
|
149
|
+
ind2 = line[14, 1]
|
150
150
|
value = line[18..-1]
|
151
|
-
return [id,tag,ind1,ind2,value]
|
151
|
+
return [id, tag, ind1, ind2, value]
|
152
152
|
end
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
153
|
+
|
154
|
+
|
157
155
|
end # ASLine
|
158
156
|
end
|
159
157
|
end
|
160
|
-
|
161
|
-
|
158
|
+
|
@@ -5,48 +5,47 @@ require_relative 'log'
|
|
5
5
|
|
6
6
|
module MARC
|
7
7
|
module AlephSequential
|
8
|
-
|
8
|
+
|
9
9
|
# A group of ASLine objects with logic to correctly turn them into a MARC::Record object
|
10
10
|
# @see ASLine
|
11
|
-
|
11
|
+
|
12
12
|
class ASLineGroup
|
13
|
-
|
13
|
+
|
14
14
|
include Log
|
15
|
-
|
15
|
+
|
16
16
|
# @!attribute aslines
|
17
17
|
# @return [Array<MARC::Field>] Internal list of MARC field object
|
18
18
|
attr_accessor :aslines
|
19
|
-
|
19
|
+
|
20
20
|
# @!attribute [r] leader
|
21
21
|
# @return [String] The leader string, pulled from whatever was passed in with a LDR tag
|
22
|
-
attr_reader
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
attr_reader :leader
|
23
|
+
|
24
|
+
|
26
25
|
def initialize
|
27
26
|
@aslines = []
|
28
|
-
@leader
|
27
|
+
@leader = nil
|
29
28
|
end
|
30
|
-
|
29
|
+
|
31
30
|
# Number of aslines already added
|
32
31
|
# @return Integer
|
33
32
|
def size
|
34
33
|
aslines.size
|
35
34
|
end
|
36
|
-
|
35
|
+
|
37
36
|
# Is this group empty?
|
38
37
|
def empty?
|
39
38
|
aslines.empty?
|
40
39
|
end
|
41
|
-
|
42
|
-
|
40
|
+
|
41
|
+
|
43
42
|
# Add an ASLine object, turning it into the appropriate type of field as we go
|
44
43
|
# An ASLine object with type :invalid_id will be treated as a string and appended to
|
45
44
|
# the previous field (to deal with not-uncommon spurious newlines in data fields)
|
46
45
|
# @return [Undefined] side effect only
|
47
46
|
# @raise MARC::AlephSequential::Error when there's an invalid ID _and_ there's no previous
|
48
47
|
# field to concatentate it to.
|
49
|
-
|
48
|
+
|
50
49
|
def add(asline)
|
51
50
|
case asline.type
|
52
51
|
when :leader
|
@@ -57,23 +56,23 @@ module MARC
|
|
57
56
|
when :invalid_id
|
58
57
|
lastfield = @aslines.pop
|
59
58
|
unless lastfield
|
60
|
-
raise MARC::AlephSequential::Error.new('unknown', asline.line_number),
|
59
|
+
raise MARC::AlephSequential::Error.new('unknown', asline.line_number),
|
61
60
|
"#{asline.line_number} has invalid id and no preivous line to concat it to (file starts bad?)"
|
62
|
-
|
61
|
+
nil
|
63
62
|
end
|
64
63
|
log.info "#{asline.line_number} #{lastfield.id} / #{lastfield.tag} Concatenating line #{asline.line_number} to previous line"
|
65
|
-
@aslines.push ASLine.new(lastfield.rawstr +
|
64
|
+
@aslines.push ASLine.new(lastfield.rawstr + asline.rawstr, lastfield.line_number)
|
66
65
|
else
|
67
66
|
@aslines.push asline
|
68
67
|
end
|
69
68
|
end
|
70
|
-
|
71
|
-
|
69
|
+
|
70
|
+
|
72
71
|
# Add an asline as a raw string
|
73
72
|
def add_string(asline_string, line_number)
|
74
73
|
self.add(ASLine.new(asline_string, line_number))
|
75
74
|
end
|
76
|
-
|
75
|
+
|
77
76
|
# Turn this object into a MARC::Record
|
78
77
|
# @return [MARC::Record]
|
79
78
|
# @raise MARC::AlephSequential::Error if this object is empty
|
@@ -82,20 +81,20 @@ module MARC
|
|
82
81
|
if empty?
|
83
82
|
raise MARC::AlephSequential::Error.new('unknown', 'unknown'), "Can't turn an empty group into a record", nil
|
84
83
|
end
|
85
|
-
|
84
|
+
|
86
85
|
unless leader
|
87
86
|
raise MARC::AlephSequential::Error.new(@aslines[0].id, @aslines[0].line_number),
|
88
87
|
"Record #{@aslines[0].id} (near line #{ @aslines[0].line_number}) has no leader; can't turn into a record",
|
89
88
|
nil
|
90
89
|
end
|
91
|
-
r
|
90
|
+
r = MARC::Record.new
|
92
91
|
r.leader = leader
|
93
|
-
aslines.map {|f| r << f.to_field}
|
92
|
+
aslines.map { |f| r << f.to_field }
|
94
93
|
return r
|
95
94
|
end
|
96
|
-
|
95
|
+
|
97
96
|
alias_method :to_record, :as_record
|
98
97
|
end
|
99
98
|
end
|
100
99
|
end
|
101
|
-
|
100
|
+
|
@@ -3,52 +3,52 @@ require 'zlib'
|
|
3
3
|
module MARC
|
4
4
|
module AlephSequential
|
5
5
|
|
6
|
-
# AlephSequential is a line-oriented format, with the first field of each line
|
6
|
+
# AlephSequential is a line-oriented format, with the first field of each line
|
7
7
|
# indicating the record number. Rather than try to screw around with keeping track of
|
8
8
|
# the last line read, checking to see if we have one, blah blah blah, I'm going to use
|
9
|
-
# a buffered line reader class so I can #peek at the next line to know if its id
|
10
|
-
# is different than the current record.
|
11
|
-
|
9
|
+
# a buffered line reader class so I can #peek at the next line to know if its id
|
10
|
+
# is different than the current record.
|
11
|
+
|
12
12
|
class BufferedLineReader
|
13
|
-
|
13
|
+
|
14
14
|
include Enumerable
|
15
|
-
|
15
|
+
|
16
16
|
attr_accessor :buffer_size
|
17
17
|
attr_reader :underlying_line_number
|
18
|
-
|
18
|
+
|
19
19
|
def initialize(filename_or_io)
|
20
|
-
|
20
|
+
|
21
21
|
@passed_in = filename_or_io
|
22
|
-
|
22
|
+
|
23
23
|
@underlying_line_number = 0
|
24
|
-
@buffer_size
|
25
|
-
@buffer
|
26
|
-
|
24
|
+
@buffer_size = 10
|
25
|
+
@buffer = []
|
26
|
+
|
27
27
|
if filename_or_io.is_a? String
|
28
28
|
@handle = File.open(filename_or_io, 'r:utf-8')
|
29
29
|
if filename_or_io =~ /\.gz$/
|
30
30
|
@handle = Zlib::GzipReader.new(@handle)
|
31
31
|
end
|
32
|
-
elsif filename_or_io.respond_to?("read"
|
32
|
+
elsif filename_or_io.respond_to?("read")
|
33
33
|
@handle = filename_or_io
|
34
34
|
else
|
35
35
|
raise ArgumentError.new("BufferedLineReader needs an IO object or filename, got #{filename_or_io} (#{filename_or_io.inspect})")
|
36
36
|
end
|
37
|
-
|
38
|
-
@iter
|
37
|
+
|
38
|
+
@iter = @handle.enum_for(:each_line)
|
39
39
|
@finished = false
|
40
40
|
# Fill up the buffer
|
41
41
|
self.fillbuffer
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
def has_next?
|
45
45
|
return !(@finished && @buffer.size == 0)
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def fillbuffer(buffer_size = @buffer_size)
|
49
49
|
begin
|
50
50
|
buffer_size.times do
|
51
|
-
raw
|
51
|
+
raw = @iter.next
|
52
52
|
@underlying_line_number += 1
|
53
53
|
@buffer.push process_raw(raw, @underlying_line_number)
|
54
54
|
end
|
@@ -56,25 +56,25 @@ module MARC
|
|
56
56
|
@finished = true
|
57
57
|
end
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
# Empty version here; can override for processing lines on the fly
|
61
61
|
def process_raw(raw, line_number)
|
62
62
|
raw
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
def next
|
66
66
|
raise StopIteration, "End of #{@passed_in}", nil if @buffer.size == 0
|
67
67
|
rv = @buffer.shift
|
68
68
|
fillbuffer if @buffer.size == 0
|
69
69
|
rv
|
70
70
|
end
|
71
|
-
|
72
|
-
|
71
|
+
|
72
|
+
|
73
73
|
def peek
|
74
74
|
fillbuffer unless @buffer.size > 0
|
75
75
|
@buffer[0]
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
def each
|
79
79
|
begin
|
80
80
|
while true
|
@@ -83,18 +83,17 @@ module MARC
|
|
83
83
|
rescue StopIteration
|
84
84
|
end
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
alias_method :each_line, :each
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module MARC
|
2
2
|
module AlephSequential
|
3
|
-
|
3
|
+
|
4
4
|
class Error < RuntimeError
|
5
5
|
attr_accessor :record_id, :line_number
|
6
|
-
|
6
|
+
|
7
7
|
def initialize(record_id, line_number)
|
8
|
-
@record_id
|
8
|
+
@record_id = record_id
|
9
9
|
@line_number = line_number
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
13
|
-
end
|
13
|
+
end
|
@@ -1,20 +1,20 @@
|
|
1
1
|
module MARC
|
2
2
|
module AlephSequential
|
3
|
-
|
3
|
+
|
4
4
|
module Log
|
5
|
-
|
5
|
+
|
6
6
|
def self.log
|
7
7
|
@log
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
def self.log=(log)
|
11
11
|
@log = log
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def log
|
15
|
-
Log.log ||= Yell.new STDERR, :level => [
|
15
|
+
Log.log ||= Yell.new STDERR, :level => [:warn, :error], :name => 'MAS'
|
16
16
|
Log.log
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
20
|
-
end
|
20
|
+
end
|
@@ -6,32 +6,32 @@ require 'marc_alephsequential/log'
|
|
6
6
|
|
7
7
|
module MARC
|
8
8
|
module AlephSequential
|
9
|
-
|
9
|
+
|
10
10
|
class Reader
|
11
11
|
|
12
12
|
include Enumerable
|
13
13
|
include Log
|
14
|
-
|
14
|
+
|
15
15
|
attr_reader :lines
|
16
16
|
attr_accessor :current_id
|
17
|
-
|
17
|
+
|
18
18
|
def initialize(filename_or_io, opts={})
|
19
19
|
@areader = ASLineReader.new(filename_or_io)
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def each
|
23
|
-
|
23
|
+
|
24
24
|
unless block_given?
|
25
25
|
return enum_for(:each)
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
agroup = ASLineGroup.new
|
29
|
-
|
29
|
+
|
30
30
|
while @areader.has_next?
|
31
31
|
nextid = @areader.peek.id
|
32
|
-
if nextid != @current_id && @areader.peek.valid_id?
|
32
|
+
if nextid != @current_id && @areader.peek.valid_id?
|
33
33
|
yield agroup.to_record unless agroup.empty?
|
34
|
-
agroup
|
34
|
+
agroup = ASLineGroup.new
|
35
35
|
@current_id = nextid
|
36
36
|
else
|
37
37
|
agroup.add @areader.next
|
@@ -43,12 +43,11 @@ module MARC
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
|
data/spec/asline_group_spec.rb
CHANGED
@@ -8,16 +8,17 @@ describe "ASLineGroup" do
|
|
8
8
|
@single_lines.each_with_index {|l,i| @full.add_string(l,i ) }
|
9
9
|
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
|
+
|
12
13
|
describe "Create Group" do
|
13
14
|
before do
|
14
15
|
@ag = MARC::AlephSequential::ASLineGroup.new
|
15
16
|
end
|
16
|
-
|
17
|
+
|
17
18
|
it "should start empty" do
|
18
19
|
@ag.must_be_empty
|
19
20
|
end
|
20
|
-
|
21
|
+
|
21
22
|
it "should read in a valid record" do
|
22
23
|
@ag = MARC::AlephSequential::ASLineGroup.new
|
23
24
|
File.open('spec/data/single.seq').each_with_index {|l,i| @ag.add_string(l,i ) }
|
@@ -27,7 +28,7 @@ describe "ASLineGroup" do
|
|
27
28
|
@ag.aslines[1].tag.must_equal '003'
|
28
29
|
@ag.aslines[1].type.must_equal :control
|
29
30
|
end
|
30
|
-
|
31
|
+
|
31
32
|
it "should deal with embedded newlines" do
|
32
33
|
tinyrec = [
|
33
34
|
"000000794 LDR L ^^^^^nam^a22003011^^4500",
|
@@ -37,23 +38,23 @@ describe "ASLineGroup" do
|
|
37
38
|
"Curtis,$$d1859-1937.",
|
38
39
|
"000000794 24514 L $$aThe descent of manuscripts"
|
39
40
|
]
|
40
|
-
|
41
|
+
|
41
42
|
tinyrec.each_with_index {|l,i| @ag.add_string(l,i) }
|
42
43
|
field = @ag.aslines[2].to_field
|
43
44
|
field.tag.must_equal '100'
|
44
45
|
field['a'].must_equal 'Clark, Albert Curtis,'
|
45
46
|
end
|
46
|
-
|
47
|
+
|
47
48
|
it "should produce a good record" do
|
48
49
|
rec = @full.to_record
|
49
50
|
rec['001'].value.must_equal '000000794'
|
50
51
|
rec['998'].value.must_equal '9665'
|
51
52
|
end
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
|
54
|
+
|
55
|
+
|
55
56
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
|
58
|
+
|
59
|
+
|
59
60
|
end
|
data/spec/asline_spec.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'helper'
|
2
2
|
require 'marc_alephsequential'
|
3
3
|
|
4
|
+
|
4
5
|
describe 'ASLine' do
|
5
6
|
before do
|
6
7
|
@leader = '000000794 LDR L ^^^^^nam^a22003011^^4500'
|
@@ -9,27 +10,27 @@ describe 'ASLine' do
|
|
9
10
|
@d1 = '000000794 1001 L $$aClark, Albert Curtis,$$d1859-1937.'
|
10
11
|
@d2 = '000000794 60000 L $$aPlato.$$tCritias$$xManuscripts.'
|
11
12
|
end
|
12
|
-
|
13
|
-
|
13
|
+
|
14
|
+
|
14
15
|
it "correctly parses a leader" do
|
15
16
|
aline = MARC::AlephSequential::ASLine.new(@leader, 1)
|
16
17
|
aline.type.must_equal :leader
|
17
18
|
aline.value.must_equal ' nam a22003011 4500'
|
18
19
|
end
|
19
|
-
|
20
|
+
|
20
21
|
it "parses control fields" do
|
21
22
|
aline = MARC::AlephSequential::ASLine.new(@c1, 1)
|
22
23
|
aline.tag.must_equal '008'
|
23
24
|
aline.value.must_equal '880715r19701918enk b |00100 eng '
|
24
25
|
end
|
25
|
-
|
26
|
-
it "parses datafield basics" do
|
26
|
+
|
27
|
+
it "parses datafield basics" do
|
27
28
|
aline = MARC::AlephSequential::ASLine.new(@d1, 1)
|
28
29
|
aline.tag.must_equal '100'
|
29
30
|
aline.ind1.must_equal '1'
|
30
31
|
aline.ind2.must_equal ' '
|
31
32
|
end
|
32
|
-
|
33
|
+
|
33
34
|
it "parses subfields" do
|
34
35
|
aline = MARC::AlephSequential::ASLine.new(@d1, 1)
|
35
36
|
subfields = aline.parse_string_into_subfields(aline.value)
|
@@ -37,10 +38,9 @@ describe 'ASLine' do
|
|
37
38
|
subfields[1].code.must_equal 'd'
|
38
39
|
subfields[0].value.must_equal 'Clark, Albert Curtis,'
|
39
40
|
subfields[1].value.must_equal '1859-1937.'
|
40
|
-
|
41
|
+
|
41
42
|
end
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
|
44
|
+
|
45
|
+
|
45
46
|
end
|
46
|
-
|
data/spec/helper.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
|
3
1
|
begin
|
4
2
|
require 'bundler'
|
5
3
|
rescue LoadError => e
|
@@ -18,5 +16,5 @@ end
|
|
18
16
|
|
19
17
|
require "minitest/autorun"
|
20
18
|
# require 'minitest/reporters'
|
21
|
-
# MiniTest::Reporters.use!
|
22
|
-
require 'minitest/hell' # parallelize testing
|
19
|
+
# MiniTest::Reporters.use!
|
20
|
+
require 'minitest/hell' # parallelize testing
|
data/spec/reader_spec.rb
CHANGED
@@ -8,29 +8,29 @@ describe 'Reader' do
|
|
8
8
|
@newline = 'spec/data/newline.seq'
|
9
9
|
@noleader = 'spec/data/noleader.seq'
|
10
10
|
@nosubfieldindicator = 'spec/data/no_initial_subfield.seq'
|
11
|
-
|
11
|
+
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
describe "empty reader" do
|
15
15
|
it "doesn't blow up on an empty file" do
|
16
16
|
iter = MARC::AlephSequential::Reader.new('/dev/null').each
|
17
17
|
lambda{iter.next}.must_raise StopIteration
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
it "reads a single record from a single-record file" do
|
22
22
|
iter = MARC::AlephSequential::Reader.new(@single).each
|
23
23
|
r = iter.next
|
24
24
|
r['998'].value.must_equal '9665'
|
25
25
|
r['100']['a'].must_equal 'Clark, Albert Curtis,'
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
it "reads a batch of records" do
|
29
29
|
count = 0
|
30
30
|
MARC::AlephSequential::Reader.new(@batch).each_with_index{|r, i| count = i + 1}
|
31
31
|
count.must_equal 31
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
it "yells when there's no leader" do
|
35
35
|
error = nil
|
36
36
|
begin
|
@@ -41,13 +41,13 @@ describe 'Reader' do
|
|
41
41
|
error.wont_be_nil
|
42
42
|
error.message.must_match /leader/
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
it "deals ok with embedded newline" do
|
46
46
|
r = MARC::AlephSequential::Reader.new(@newline).first
|
47
47
|
r['600']['a'].must_equal 'Cicero, Marcus Tullius'
|
48
48
|
r['600']['x'].must_equal 'Manuscripts.'
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
it "works with lack of beginning '$$'" do
|
52
52
|
r = nil # capture_io creates a lexical closure, so we need to define it out here
|
53
53
|
out,err = capture_io do
|
@@ -56,7 +56,6 @@ describe 'Reader' do
|
|
56
56
|
err.must_match /Variable field 245 doesn\'t start with \'\$\$/m
|
57
57
|
r['245']['a'].must_equal 'The descent of manuscripts.'
|
58
58
|
end
|
59
|
-
|
60
|
-
|
59
|
+
|
60
|
+
|
61
61
|
end
|
62
|
-
|
data/spec/version_spec.rb
CHANGED
metadata
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marc_alephsequential
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bill Dueber
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10-
|
11
|
+
date: 2013-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: A ruby-marc reader for Aleph sequential files, a MARC serialization supported
|
14
|
-
by Ex Libris' Aleph
|
13
|
+
description: A ruby-marc reader for Aleph sequential files, a MARC serialization supported by Ex Libris' Aleph
|
15
14
|
email: bill@dueber.com
|
16
15
|
executables: []
|
17
16
|
extensions: []
|
@@ -50,24 +49,24 @@ homepage: https://github.com/billdueber/marc_alephsequential#readme
|
|
50
49
|
licenses:
|
51
50
|
- MIT
|
52
51
|
metadata: {}
|
53
|
-
post_install_message:
|
52
|
+
post_install_message:
|
54
53
|
rdoc_options: []
|
55
54
|
require_paths:
|
56
55
|
- lib
|
57
56
|
required_ruby_version: !ruby/object:Gem::Requirement
|
58
57
|
requirements:
|
59
|
-
- -
|
58
|
+
- - '>='
|
60
59
|
- !ruby/object:Gem::Version
|
61
60
|
version: '0'
|
62
61
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
62
|
requirements:
|
64
|
-
- -
|
63
|
+
- - '>='
|
65
64
|
- !ruby/object:Gem::Version
|
66
65
|
version: '0'
|
67
66
|
requirements: []
|
68
|
-
rubyforge_project:
|
69
|
-
rubygems_version: 2.1.
|
70
|
-
signing_key:
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 2.1.9
|
69
|
+
signing_key:
|
71
70
|
specification_version: 4
|
72
71
|
summary: ruby-marc reader for Aleph sequential files
|
73
72
|
test_files:
|
@@ -81,4 +80,4 @@ test_files:
|
|
81
80
|
- spec/helper.rb
|
82
81
|
- spec/reader_spec.rb
|
83
82
|
- spec/version_spec.rb
|
84
|
-
has_rdoc:
|
83
|
+
has_rdoc:
|