# frozen_string_literal: true module RSpec module XlsxMatchers # Base class for sheet based machers class BaseSheet include Utils attr_reader :sheet_name, :sheet, :subject def matches?(subject) @subject = subject @sheet = find_sheet return false if sheet.nil? process_sheet.tap do finalize end end def in_sheet(name) @sheet_name = name self end private def find_sheet find_axlsx_sheet || find_roo_sheet rescue RangeError, ArgumentError nil end def find_axlsx_sheet return unless defined?(Axlsx) return subject if subject.is_a?(Axlsx::Worksheet) workbook = if subject.is_a?(Axlsx::Package) subject.workbook else subject end return unless workbook.is_a?(Axlsx::Workbook) axlsx_sheet_from_workbook(workbook) end def axlsx_sheet_from_workbook(workbook) if sheet_name.is_a?(String) workbook.sheet_by_name(sheet_name) elsif sheet_name.is_a?(Integer) workbook.worksheets[sheet_name] else raise ArgumentError, "Missing sheet name" end end def find_roo_sheet return unless defined?(Roo::Excelx) return subject if subject.is_a?(Roo::Excelx::Sheet) return unless roo_spreadsheet return unless sheet_name roo_spreadsheet.sheet_for(sheet_name) end def roo_spreadsheet return @roo_spreadsheet unless @roo_spreadsheet.nil? @roo_spreadsheet = if subject.is_a?(Roo::Excelx) subject elsif subject.is_a?(String) || subject.is_a?(File) Roo::Spreadsheet.open(subject) end end def process_sheet if defined?(Axlsx) && sheet.is_a?(Axlsx::Worksheet) process_axlsx_sheet elsif defined?(Roo::Excelx) && sheet.is_a?(Roo::Excelx::Sheet) process_roo_sheet else raise "Unsupported worksheet type: #{worksheet.class}" end end def sheet_failure_message if sheet_name "Could not find sheet #{sheet_name}" else "Sheet not provided" end end def failure_message_in_sheet(msg) if sheet_name "#{msg} in sheet #{sheet_name}" else msg end end def finalize roo_spreadsheet&.close rescue StandardError => e puts "Warning: error closing Roo Spreadsheet: #{e}" end end end end