From 7d09b7ff4d4a31ec19170f961cc759bd1f23458f Mon Sep 17 00:00:00 2001 From: David Zuckerman Date: Fri, 13 Mar 2026 13:02:25 -0700 Subject: [PATCH] AP-613 convert oclc number to int if it's a float in the spreadsheet converting oclc numbers to floats in spec removed spaces at end of line for rubocop bumped nokogiri to 1.19 and ruby to 3.3 forgot to update the build and gem push files with the updated ruby version updated rubocop target to ruby 3.3 bumped rubocop version --- .github/workflows/build.yml | 2 +- .github/workflows/gem-push.yml | 2 +- .rubocop.yml | 3 ++ .ruby-version | 2 +- berkeley_library-location.gemspec | 5 ++-- lib/berkeley_library/location/xlsx_reader.rb | 2 ++ spec/.rubocop.yml | 2 +- .../location/xlsx_reader_spec.rb | 28 ++++++++++++++++++ spec/data/excel/oclc-numbers-float.xlsx | Bin 0 -> 10098 bytes 9 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 spec/data/excel/oclc-numbers-float.xlsx diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4df0f0b..7fbf996 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest, macos-latest ] - ruby: [ '3.1', '3.2' ] + ruby: [ '3.3', '3.4' ] runs-on: ${{ matrix.os }} steps: diff --git a/.github/workflows/gem-push.yml b/.github/workflows/gem-push.yml index fdc0965..9e6341e 100644 --- a/.github/workflows/gem-push.yml +++ b/.github/workflows/gem-push.yml @@ -18,7 +18,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: '3.2' + ruby-version: '3.3' bundler-cache: true - name: Publish to RubyGems diff --git a/.rubocop.yml b/.rubocop.yml index d5e423c..908b21e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -3,6 +3,9 @@ inherit_mode: - Exclude - Include +AllCops: + TargetRubyVersion: 3.3 + # Allow one line around block body (Layout/EmptyLines will still disallow two or more) Layout/EmptyLinesAroundBlockBody: Enabled: false diff --git a/.ruby-version b/.ruby-version index ef538c2..0ddaf4d 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.1.2 +~> 3.3 diff --git a/berkeley_library-location.gemspec b/berkeley_library-location.gemspec index 2e55f10..07b5b02 100644 --- a/berkeley_library-location.gemspec +++ b/berkeley_library-location.gemspec @@ -14,7 +14,7 @@ Gem::Specification.new do |spec| spec.version = BerkeleyLibrary::Location::ModuleInfo::VERSION spec.homepage = BerkeleyLibrary::Location::ModuleInfo::HOMEPAGE - spec.required_ruby_version = '>= 3.1.0' + spec.required_ruby_version = '>= 3.3.0' spec.metadata['homepage_uri'] = spec.homepage spec.metadata['source_code_uri'] = spec.homepage @@ -31,6 +31,7 @@ Gem::Specification.new do |spec| spec.add_dependency 'berkeley_library-util', '~> 0.1', '>= 0.1.9' spec.add_dependency 'jsonpath', '~> 0.5.8' spec.add_dependency 'marcel', '~> 1.0.2' + spec.add_dependency 'nokogiri', '>= 1.19.1' spec.add_dependency 'rest-client', '~> 2.1' spec.add_dependency 'rubyXL', '~> 3.4' @@ -40,7 +41,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'dotenv', '~> 2.7' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rspec', '~> 3.10' - spec.add_development_dependency 'rubocop', '= 1.39' + spec.add_development_dependency 'rubocop', '~> 1.75' spec.add_development_dependency 'rubocop-rake', '= 0.6.0' spec.add_development_dependency 'rubocop-rspec', '= 2.4.0' spec.add_development_dependency 'ruby-prof', '~> 1.7.1' diff --git a/lib/berkeley_library/location/xlsx_reader.rb b/lib/berkeley_library/location/xlsx_reader.rb index 67b4ac3..dd87c7c 100644 --- a/lib/berkeley_library/location/xlsx_reader.rb +++ b/lib/berkeley_library/location/xlsx_reader.rb @@ -19,6 +19,8 @@ def each_oclc_number return to_enum(:each_oclc_number) unless block_given? ss.each_value(oclc_col_index, include_header: false) do |v| + # convert to integer if oclc number is a float in the spreadsheet" + v = v.to_i if v.is_a?(Float) next if (v_str = v.to_s).strip == '' yield v_str diff --git a/spec/.rubocop.yml b/spec/.rubocop.yml index cc8f998..da85d02 100644 --- a/spec/.rubocop.yml +++ b/spec/.rubocop.yml @@ -123,5 +123,5 @@ RSpec/VerifiedDoubles: RSpec/IdenticalEqualityAssertion: # new in 2.4 Enabled: true -RSpec/Rails/AvoidSetupHook: # new in 2.4 +RSpecRails/AvoidSetupHook: Enabled: true diff --git a/spec/berkeley_library/location/xlsx_reader_spec.rb b/spec/berkeley_library/location/xlsx_reader_spec.rb index a8d5aa0..038e8f7 100644 --- a/spec/berkeley_library/location/xlsx_reader_spec.rb +++ b/spec/berkeley_library/location/xlsx_reader_spec.rb @@ -73,12 +73,40 @@ module Location .to yield_successive_args(*oclc_numbers_expected) end + # Added this since oclc floats in oclc-numbers-float.xlsx weren't being read + # in as floats at runtime. + it 'processes OCLC numbers converted to floats from the base spreadsheet' do + source_xlsx_path = 'spec/data/excel/oclc-numbers.xlsx' + source_oclc_numbers = XLSXReader.new(source_xlsx_path).each_oclc_number.to_a + + Dir.mktmpdir(File.basename(__FILE__)) do |tmpdir| + xlsx_path = File.join(tmpdir, 'oclc-numbers-from-source-as-floats.xlsx') + + ss = BerkeleyLibrary::Util::XLSX::Spreadsheet.new + c_index = ss.ensure_column!(BerkeleyLibrary::Location::Constants::OCLC_COL_HEADER) + source_oclc_numbers.each_with_index do |oclc_num, i| + r_index = 1 + i # skip header row + ss.set_value_at(r_index, c_index, oclc_num.to_f) + end + ss.save_as(xlsx_path) + + reader = XLSXReader.new(xlsx_path) + expect(reader.each_oclc_number.to_a).to eq(source_oclc_numbers) + end + end + it 'finds OCLC numbers as strings' do reader = XLSXReader.new('spec/data/excel/oclc-numbers-text.xlsx') expect { |b| reader.each_oclc_number(&b) } .to yield_successive_args(*oclc_numbers_expected) end + it 'finds OCLC numbers when column is formatted as Excel number' do + reader = XLSXReader.new('spec/data/excel/oclc-numbers-float.xlsx') + expect { |b| reader.each_oclc_number(&b) } + .to yield_successive_args(*oclc_numbers_expected) + end + it 'skips blank cells' do reader = XLSXReader.new('spec/data/excel/oclc-numbers-sparse.xlsx') expect { |b| reader.each_oclc_number(&b) } diff --git a/spec/data/excel/oclc-numbers-float.xlsx b/spec/data/excel/oclc-numbers-float.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..ed24d8d68febde1ab78251c5b9fd5c9037892a0e GIT binary patch literal 10098 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 literal 0 HcmV?d00001