Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate worksheet name using Libxlsxwriter #83

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ GEM
ruby-progressbar
nokogiri (1.13.3-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.13.3-x86_64-linux)
racc (~> 1.4)
racc (1.6.0)
rake (13.0.6)
ruby-progressbar (1.11.0)
Expand All @@ -57,6 +59,7 @@ GEM

PLATFORMS
x86_64-darwin-20
x86_64-linux

DEPENDENCIES
axlsx!
Expand Down
10 changes: 6 additions & 4 deletions lib/fast_excel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ def self.print_ffi_obj(value)
end


ERROR_ENUM = Libxlsxwriter.enum_type(:error)
COLOR_ENUM = Libxlsxwriter.enum_type(:defined_colors)
EXTRA_COLORS = {
alice_blue: 0xF0F8FF,
Expand Down Expand Up @@ -366,10 +367,11 @@ def number_format(pattern)

def add_worksheet(sheetname = nil)
if !sheetname.nil?
if sheetname.length > Libxlsxwriter::SHEETNAME_MAX
raise ArgumentError, "Worksheet name '#{sheetname}' exceeds Excel's limit of #{Libxlsxwriter::SHEETNAME_MAX} characters"
elsif @sheet_names.include?(sheetname)
raise ArgumentError, "Worksheet name '#{sheetname}' is already in use"
error = validate_worksheet_name(sheetname)
if error != :no_error
error_code = ERROR_ENUM.find(error)
error_str = error_code ? Libxlsxwriter.strerror(error_code) : ''
raise ArgumentError, "Invalid worksheet name '#{sheetname}': (#{error_code} - #{error}) #{error_str}"
end
end

Expand Down
6 changes: 3 additions & 3 deletions lib/fast_excel/binding/workbook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def get_worksheet_by_name(name)
# @param [String] sheetname
# @return [Symbol from _enum_error_]
def validate_worksheet_name(sheetname)
Libxlsxwriter.workbook_validate_worksheet_name(self, sheetname)
Libxlsxwriter.workbook_validate_sheet_name(self, sheetname)
end

# @return [nil]
Expand Down Expand Up @@ -319,12 +319,12 @@ class Workbook < FFI::Struct
# @scope class
attach_function :workbook_get_worksheet_by_name, :workbook_get_worksheet_by_name, [Workbook, :string], Worksheet

# @method workbook_validate_worksheet_name(workbook, sheetname)
# @method workbook_validate_sheet_name(workbook, sheetname)
# @param [Workbook] workbook
# @param [String] sheetname
# @return [Symbol from _enum_error_]
# @scope class
attach_function :workbook_validate_worksheet_name, :workbook_validate_worksheet_name, [Workbook, :string], :error
attach_function :workbook_validate_sheet_name, :workbook_validate_sheet_name, [Workbook, :string], :error

# @method workbook_free(workbook)
# @param [Workbook] workbook
Expand Down
15 changes: 13 additions & 2 deletions test/validations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
end

assert_equal(ArgumentError, error.class)
assert_equal("Worksheet name 'Payments Report' is already in use", error.message)
assert_equal("Invalid worksheet name 'Payments Report': (16 - error_sheetname_already_used) Worksheet name is already in use.", error.message)
end

it "should not raise error when worksheet name is null" do
Expand All @@ -33,7 +33,7 @@
end

assert_equal(ArgumentError, error.class)
assert_equal("Worksheet name 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345' exceeds Excel's limit of 31 characters", error.message)
assert_equal("Invalid worksheet name 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345': (13 - error_sheetname_length_exceeded) Worksheet name exceeds Excel's limit of 31 characters.", error.message)
end

it "should not raise error when the sheet name is at maximum length" do
Expand All @@ -44,4 +44,15 @@

assert_equal("ABCDEFGHIJKLMNOPQRSTUVWXYZ01234", worksheet[:name])
end

it "should validate using Libxlsxwriter validation" do
workbook = FastExcel.open(constant_memory: true)
error = assert_raises do
worksheet = workbook.add_worksheet('a?')
worksheet.write_value(1, 1, 'a') # without the validation, this method will crash the process
end

assert_equal(ArgumentError, error.class)
assert_equal("Invalid worksheet name 'a?': (14 - error_invalid_sheetname_character) Worksheet name cannot contain invalid characters: '[ ] : * ? / \\'", error.message)
end
end