Skip to content

Commit

Permalink
test ParsedCallNum class and clean up marc_data_spec
Browse files Browse the repository at this point in the history
  • Loading branch information
mzelesky committed Nov 22, 2024
1 parent 4f7bc32 commit e9128f2
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 124 deletions.
51 changes: 13 additions & 38 deletions lib/lsp-data/marc_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,16 @@
module LspData
### If specified as an LC call number, break it up into parts;
### if not, return first subfield as full class and item subfield as Cutter
def parse_call_number(primary_subfield:, item_subfields:, assume_lc: true)
cutters = item_subfields.map(&:value)
full_call_num = "#{primary_subfield.value} #{cutters.join(' ')}".strip
is_lc = false
if assume_lc
main_lc_class = nil
sub_lc_class = nil
if primary_subfield.value[0] =~ /[A-Z]/
is_lc = true
main_lc_class = primary_subfield.value[0]
sub_lc_class = primary_subfield.value.gsub(/^([A-Z]+)[^A-Z].*$/, '\1')
end
{ is_lc: is_lc,
main_lc_class: main_lc_class,
sub_lc_class: sub_lc_class,
classification: primary_subfield.value,
full_call_num: full_call_num,
cutters: cutters }
else
{ is_lc: is_lc,
main_lc_class: nil,
sub_lc_class: nil,
classification: primary_subfield.value,
full_call_num: full_call_num,
cutters: cutters }
end
end

def call_num_from_bib_field(record:, field_tag:)
def call_num_from_bib_field(record:, field_tag:, assume_lc: true)
return [] unless record[field_tag]

call_nums = []
record.fields(field_tag).each do |field|
call_num = field.subfields.select do |subfield|
%w[a b].include?(subfield.code)
end.map(&:value).join(' ')
call_num.strip!
call_nums << call_num
primary_subfield = field.subfields.select { |s| s.code == 'a' }.first
item_subfields = field.subfields.select { |s| s.code == 'b' }
call_nums << LspData::ParsedCallNumber.new(primary_subfield: primary_subfield,
item_subfields: item_subfields,
assume_lc: assume_lc)
end
call_nums
end
Expand All @@ -56,10 +28,13 @@ def call_num_from_alma_holding_field(record:, field_tag:, inst_suffix:, lc_only:
next if lc_only && field.indicator1 != '0'

holding_id = field['8']
call_num = field.subfields.select do |subfield|
%w[h i].include?(subfield.code)
end.map(&:value).join(' ')
call_num.strip!
primary_subfield = field.subfields.select { |s| s.code == 'h' }.first
item_subfields = field.subfields.select { |s| s.code == 'i' }
assume_lc = field.indicator1 == '0' ? true : false

call_num = LspData::ParsedCallNumber.new(primary_subfield: primary_subfield,
item_subfields: item_subfields,
assume_lc: assume_lc)
hash[holding_id] ||= []
hash[holding_id] << call_num
end
Expand Down
41 changes: 33 additions & 8 deletions lib/lsp-data/parsed_call_num.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,40 @@ def initialize(primary_subfield:, item_subfields:, assume_lc:)
@assume_lc = assume_lc
end

def lc?
if assume_lc
primary_subfield.value[0] =~ /[A-Z]/ ? true : false
else
false
end
end

def primary_lc_class
@primary_lc_class ||= begin
if assume_lc
primary_subfield.value[0] =~ /[A-Z]/ ? primary_subfield.value[0] : nil
else
nil
end
end
@primary_lc_class
if lc?
primary_subfield.value[0]
else
nil
end
end

def sub_lc_class
if lc?
primary_subfield.value.gsub(/^([A-Z]+)[^A-Z].*$/, '\1')
else
nil
end
end

def classification
primary_subfield.value.strip
end

def cutters
item_subfields.map(&:value)
end

def full_call_num
"#{primary_subfield.value} #{cutters.join(' ')}".strip
end
end
end
99 changes: 21 additions & 78 deletions spec/marc_data_spec.rb
Original file line number Diff line number Diff line change
@@ -1,72 +1,7 @@
# frozen_string_literal: true

require_relative './../lib/lsp-data'

RSpec.describe 'parse_call_number' do

context 'non-LC field has multiple Cutters' do
let(:primary_subfield) { MARC::Subfield.new('a', 'PS3556.S32') }
let(:item_subfields) { [
MARC::Subfield.new('b', '.F2'),
MARC::Subfield.new('b', '.G312')
] }
it 'returns all parts of the call number' do
target_hash = {
is_lc: false,
main_lc_class: nil,
sub_lc_class: nil,
classification: primary_subfield.value,
full_call_num: 'PS3556.S32 .F2 .G312',
cutters: ['.F2', '.G312']
}
expect(LspData.parse_call_number(primary_subfield: primary_subfield,
item_subfields: item_subfields,
assume_lc: false)).to eq target_hash
end
end

context 'LC primary field does not start with a letter' do
let(:primary_subfield) { MARC::Subfield.new('a', '1PS3556.S32') }
let(:item_subfields) { [
MARC::Subfield.new('b', '.F2'),
MARC::Subfield.new('b', '.G312')
] }
it 'does not provide an LC class' do
target_hash = {
is_lc: false,
main_lc_class: nil,
sub_lc_class: nil,
classification: primary_subfield.value,
full_call_num: '1PS3556.S32 .F2 .G312',
cutters: ['.F2', '.G312']
}
expect(LspData.parse_call_number(primary_subfield: primary_subfield,
item_subfields: item_subfields,
assume_lc: true)).to eq target_hash
end
end

context 'LC call number field is well-formed' do
let(:primary_subfield) { MARC::Subfield.new('a', 'PS3556.S32') }
let(:item_subfields) { [
MARC::Subfield.new('b', '.F2')
] }
it 'parses the LC call number correctly' do
target_hash = {
is_lc: true,
main_lc_class: 'P',
sub_lc_class: 'PS',
classification: primary_subfield.value,
full_call_num: 'PS3556.S32 .F2',
cutters: ['.F2']
}
expect(LspData.parse_call_number(primary_subfield: primary_subfield,
item_subfields: item_subfields,
assume_lc: true)).to eq target_hash
end
end
end

require 'byebug'
RSpec.describe 'call_num_from_bib_field' do
let(:leader) { '01104naa a2200289 i 4500' }
let(:record) { MARC::Record.new_from_hash('fields' => fields, 'leader' => leader) }
Expand All @@ -84,8 +19,9 @@
end
it 'returns all LC call numbers' do
target_array = ['M269 .C69', 'M3.1 .C69 2012']
expect(LspData.call_num_from_bib_field(record: record,
field_tag: '050')).to eq target_array
call_nums = LspData.call_num_from_bib_field(record: record,
field_tag: '050')
expect(call_nums.map(&:full_call_num)).to eq target_array
end
end
context 'record has 090 field and 050 field and 090 is target field' do
Expand All @@ -101,8 +37,9 @@
end
it 'returns LC call numbers from 090 field' do
target_array = ['M3.1 .C69 2012']
expect(LspData.call_num_from_bib_field(record: record,
field_tag: '090')).to eq target_array
call_nums = LspData.call_num_from_bib_field(record: record,
field_tag: '090')
expect(call_nums.map(&:full_call_num)).to eq target_array
end
end
end
Expand Down Expand Up @@ -166,11 +103,13 @@
]
end
it 'returns correct call numbers' do
target_hash = { '2216124' => ['M269 .C69'] }
expect(LspData.call_num_from_alma_holding_field(record: record,
holding_id = '2216124'
target_array = ['M269 .C69']
call_nums = LspData.call_num_from_alma_holding_field(record: record,
field_tag: field_tag,
inst_suffix: inst_suffix,
lc_only: false)).to eq target_hash
lc_only: false)
expect(call_nums[holding_id].map(&:full_call_num)).to eq target_array
end
end

Expand Down Expand Up @@ -221,12 +160,16 @@
end

it 'returns correct call numbers' do
target_hash = { f050: ['M269 .C69'],
f090: ['M3.1 .C69 2012'],
holdings: { '2216124' => ['M3.1 .C69'] } }
expect(LspData.all_call_nums_from_merged_bib(record: record,
target_f050 = ['M269 .C69']
target_f090 = ['M3.1 .C69 2012']
holding_id = '2216124'
target_holding_call_nums = ['M3.1 .C69']
call_nums = LspData.all_call_nums_from_merged_bib(record: record,
inst_suffix: inst_suffix,
lc_only: true,
holding_field_tag: holding_field_tag)).to eq target_hash
holding_field_tag: holding_field_tag)
expect(call_nums[:f050].map(&:full_call_num)).to eq target_f050
expect(call_nums[:f090].map(&:full_call_num)).to eq target_f090
expect(call_nums[:holdings][holding_id].map(&:full_call_num)).to eq target_holding_call_nums
end
end
59 changes: 59 additions & 0 deletions spec/parsed_call_num_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# frozen_string_literal: true

require_relative './../lib/lsp-data'

RSpec.describe LspData::ParsedCallNumber do
subject(:call_num) do
described_class.new(primary_subfield: primary_subfield, item_subfields: item_subfields, assume_lc: assume_lc)
end

context 'non-LC field has multiple Cutters' do
let(:assume_lc) { false }
let(:primary_subfield) { MARC::Subfield.new('a', 'PS3556.S32') }
let(:item_subfields) { [
MARC::Subfield.new('b', '.F2'),
MARC::Subfield.new('b', '.G312')
] }

it 'does not parse call number as an LC call number' do
expect(call_num.primary_lc_class).to be_nil
expect(call_num.sub_lc_class).to be_nil
expect(call_num.classification).to eq primary_subfield.value
expect(call_num.cutters).to eq ['.F2', '.G312']
expect(call_num.lc?).to be false
end
end

context 'LC primary field does not start with a letter' do
let(:assume_lc) { true }
let(:primary_subfield) { MARC::Subfield.new('a', '1PS3556.S32') }
let(:item_subfields) { [
MARC::Subfield.new('b', '.F2'),
MARC::Subfield.new('b', '.G312')
] }

it 'does not parse call number as an LC call number' do
expect(call_num.primary_lc_class).to be_nil
expect(call_num.sub_lc_class).to be_nil
expect(call_num.classification).to eq primary_subfield.value
expect(call_num.cutters).to eq ['.F2', '.G312']
expect(call_num.lc?).to be false
end
end

context 'LC call number field is well-formed' do
let(:assume_lc) { true }
let(:primary_subfield) { MARC::Subfield.new('a', 'PS3556.S32') }
let(:item_subfields) { [
MARC::Subfield.new('b', '.F2')
] }

it 'parses the LC call number correctly' do
expect(call_num.primary_lc_class).to eq 'P'
expect(call_num.sub_lc_class).to eq 'PS'
expect(call_num.classification).to eq primary_subfield.value
expect(call_num.cutters).to eq ['.F2']
expect(call_num.lc?).to be true
end
end
end

0 comments on commit e9128f2

Please sign in to comment.