excel_templating 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.document +3 -0
  3. data/.gitignore +4 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.hound.yml +261 -0
  6. data/.rubocop.ph.yml +44 -0
  7. data/.rubocop.yml +3 -0
  8. data/.yardopts +1 -0
  9. data/ChangeLog.md +8 -0
  10. data/Gemfile +10 -0
  11. data/LICENSE.txt +3 -0
  12. data/README.md +133 -0
  13. data/Rakefile +43 -0
  14. data/excel_templating.gemspec +32 -0
  15. data/lib/excel_templating/document/data_source_registry/registry_list.rb +48 -0
  16. data/lib/excel_templating/document/data_source_registry/registry_renderer.rb +74 -0
  17. data/lib/excel_templating/document/data_source_registry.rb +64 -0
  18. data/lib/excel_templating/document/sheet/repeated_row.rb +39 -0
  19. data/lib/excel_templating/document/sheet.rb +133 -0
  20. data/lib/excel_templating/document.rb +71 -0
  21. data/lib/excel_templating/document_dsl.rb +85 -0
  22. data/lib/excel_templating/excel_abstraction/active_cell_reference.rb +59 -0
  23. data/lib/excel_templating/excel_abstraction/cell.rb +23 -0
  24. data/lib/excel_templating/excel_abstraction/cell_range.rb +26 -0
  25. data/lib/excel_templating/excel_abstraction/cell_reference.rb +39 -0
  26. data/lib/excel_templating/excel_abstraction/date.rb +36 -0
  27. data/lib/excel_templating/excel_abstraction/row.rb +29 -0
  28. data/lib/excel_templating/excel_abstraction/sheet.rb +102 -0
  29. data/lib/excel_templating/excel_abstraction/spread_sheet.rb +28 -0
  30. data/lib/excel_templating/excel_abstraction/time.rb +42 -0
  31. data/lib/excel_templating/excel_abstraction/work_book.rb +47 -0
  32. data/lib/excel_templating/excel_abstraction.rb +16 -0
  33. data/lib/excel_templating/render_helper.rb +14 -0
  34. data/lib/excel_templating/renderer.rb +251 -0
  35. data/lib/excel_templating/rspec_excel_matcher.rb +129 -0
  36. data/lib/excel_templating/version.rb +4 -0
  37. data/lib/excel_templating.rb +4 -0
  38. data/spec/assets/alphalist_7_4.mustache.xlsx +0 -0
  39. data/spec/assets/alphalist_seven_four_expected.xlsx +0 -0
  40. data/spec/assets/valid_cell.mustache.xlsx +0 -0
  41. data/spec/assets/valid_cell_expected.xlsx +0 -0
  42. data/spec/assets/valid_cell_expected_inline.xlsx +0 -0
  43. data/spec/assets/valid_column_expected.xlsx +0 -0
  44. data/spec/cell_validation_spec.rb +114 -0
  45. data/spec/column_validation_spec.rb +47 -0
  46. data/spec/excel_abstraction/active_cell_reference_spec.rb +73 -0
  47. data/spec/excel_abstraction/cell_range_spec.rb +36 -0
  48. data/spec/excel_abstraction/cell_reference_spec.rb +69 -0
  49. data/spec/excel_abstraction/cell_spec.rb +54 -0
  50. data/spec/excel_abstraction/date_spec.rb +27 -0
  51. data/spec/excel_abstraction/row_spec.rb +42 -0
  52. data/spec/excel_abstraction/sheet_spec.rb +83 -0
  53. data/spec/excel_abstraction/spread_sheet_spec.rb +35 -0
  54. data/spec/excel_abstraction/time_spec.rb +27 -0
  55. data/spec/excel_abstraction/work_book_spec.rb +22 -0
  56. data/spec/excel_helper.rb +16 -0
  57. data/spec/excel_templating_spec.rb +141 -0
  58. data/spec/spec_helper.rb +13 -0
  59. metadata +281 -0
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'cell validation' do
4
+ context "rendered to the data sheet" do
5
+ class SimpleCellValidatedDocument < ExcelTemplating::Document
6
+ template "spec/assets/valid_cell.mustache.xlsx"
7
+ title "Valid cell test"
8
+ organization "Unimportant"
9
+ default_styling(
10
+ text_wrap: 0,
11
+ font: "Calibri",
12
+ size: 10,
13
+ align: :left,
14
+ )
15
+ list_source :valid_foos, title: "Foos", list: ["foo", "bar"]
16
+ sheet 1 do
17
+ validate_cell row: 2, column: 1, with: :valid_foos
18
+ end
19
+ end
20
+
21
+ subject { SimpleCellValidatedDocument.new(data) }
22
+
23
+ let(:data) {
24
+ {
25
+ all_sheets:
26
+ {
27
+ valid_value: "foo",
28
+ }
29
+ }
30
+ }
31
+
32
+ describe "#render" do
33
+ it do
34
+ expect do
35
+ subject.render do |path|
36
+ expect(path).to match_excel_content('spec/assets/valid_cell_expected.xlsx')
37
+ end
38
+ end.not_to raise_error
39
+ end
40
+ end
41
+ end
42
+
43
+ context "list taken from the data" do
44
+ class SimpleFromDataValidatedDocument < ExcelTemplating::Document
45
+ template "spec/assets/valid_cell.mustache.xlsx"
46
+ title "Valid cell test"
47
+ organization "Unimportant"
48
+ default_styling(
49
+ text_wrap: 0,
50
+ font: "Calibri",
51
+ size: 10,
52
+ align: :left,
53
+ )
54
+ list_source :valid_foos, title: "Foos"
55
+ sheet 1 do
56
+ validate_cell row: 2, column: 1, with: :valid_foos
57
+ end
58
+ end
59
+
60
+ subject { SimpleFromDataValidatedDocument.new(data) }
61
+
62
+ let(:data) {
63
+ {
64
+ all_sheets:
65
+ {
66
+ valid_foos: ["foo","bar"],
67
+ valid_value: "foo",
68
+ }
69
+ }
70
+ }
71
+
72
+ describe "#render" do
73
+ it do
74
+ expect do
75
+ subject.render do |path|
76
+ expect(path).to match_excel_content('spec/assets/valid_cell_expected.xlsx')
77
+ end
78
+ end.not_to raise_error
79
+ end
80
+ end
81
+ end
82
+
83
+ context "rendered inline" do
84
+ class InlineCellValidatedDocument < ExcelTemplating::Document
85
+ template "spec/assets/valid_cell.mustache.xlsx"
86
+ title "Valid cell test"
87
+ list_source :valid_foos, title: "Foos", list: ["foo", "bar"], inline: true
88
+ sheet 1 do
89
+ validate_cell row: 2, column: 1, with: :valid_foos
90
+ end
91
+ end
92
+
93
+ subject { InlineCellValidatedDocument.new(data) }
94
+
95
+ let(:data) {
96
+ {
97
+ all_sheets:
98
+ {
99
+ valid_value: "foo",
100
+ }
101
+ }
102
+ }
103
+
104
+ describe "#render" do
105
+ it do
106
+ expect do
107
+ subject.render do |path|
108
+ expect(path).to match_excel_content('spec/assets/valid_cell_expected_inline.xlsx')
109
+ end
110
+ end.not_to raise_error
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'column validation' do
4
+ context "rendered to the data sheet" do
5
+ class SimpleColumnValidatedDocument < ExcelTemplating::Document
6
+ template "spec/assets/valid_cell.mustache.xlsx"
7
+ title "Valid cell test"
8
+ organization "Unimportant"
9
+ default_styling(
10
+ text_wrap: 0,
11
+ font: "Calibri",
12
+ size: 10,
13
+ align: :left,
14
+ )
15
+ list_source :valid_foos, title: "Foos", list: ["foo", "bar"]
16
+ sheet 1 do
17
+ repeat_row 2, with: :foo_data do
18
+ validate_column 1, with: :valid_foos
19
+ end
20
+ end
21
+ end
22
+
23
+ subject { SimpleColumnValidatedDocument.new(data) }
24
+
25
+ let(:data) {
26
+ {
27
+ all_sheets: {},
28
+ 1 => {
29
+ foo_data: [
30
+ { valid_value: 'foo'},
31
+ { valid_value: 'bar'}
32
+ ]
33
+ }
34
+ }
35
+ }
36
+
37
+ describe "#render" do
38
+ it do
39
+ expect do
40
+ subject.render do |path|
41
+ expect(path).to match_excel_content('spec/assets/valid_column_expected.xlsx')
42
+ end
43
+ end.not_to raise_error
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe ExcelAbstraction::ActiveCellReference do
4
+ subject { described_class.new(row: 2, col: 3) }
5
+
6
+ describe "#up" do
7
+ it "moves to the cell above" do
8
+ expect(subject.up).to eq(ExcelAbstraction::CellReference.new(row: 1, col: 3))
9
+ end
10
+ end
11
+
12
+ describe "#down" do
13
+ it "moves to the cell above" do
14
+ expect(subject.down).to eq(ExcelAbstraction::CellReference.new(row: 3, col: 3))
15
+ end
16
+ end
17
+
18
+ describe "#left" do
19
+ it "moves to the cell above" do
20
+ expect(subject.left).to eq(ExcelAbstraction::CellReference.new(row: 2, col: 2))
21
+ end
22
+ end
23
+
24
+ describe "#right" do
25
+ it "moves to the cell above" do
26
+ expect(subject.right).to eq(ExcelAbstraction::CellReference.new(row: 2, col: 4))
27
+ end
28
+ end
29
+
30
+ describe "#move" do
31
+ context "when the movement commands are supported" do
32
+ it "moves to the cell position specified" do
33
+ expect(subject.move(right: 2)).to eq(ExcelAbstraction::CellReference.new(row: 2, col: 5))
34
+ end
35
+ end
36
+
37
+ context "when the movement commands are not supported" do
38
+ it "moves to the cell above" do
39
+ expect { subject.move(diagonal: 2) }.to raise_exception(ArgumentError)
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "#carriage_return" do
45
+ it "moves to the cell at the beginning of the row" do
46
+ expect(subject.carriage_return).to eq(ExcelAbstraction::CellReference.new(row: 2, col: 0))
47
+ end
48
+ end
49
+
50
+ describe "#linefeed" do
51
+ it "moves to the cell in the next row" do
52
+ expect(subject.linefeed).to eq(ExcelAbstraction::CellReference.new(row: 3, col: 3))
53
+ end
54
+ end
55
+
56
+ describe "#newline" do
57
+ it "moves to the cell above" do
58
+ expect(subject.newline).to eq(ExcelAbstraction::CellReference.new(row: 3, col: 0))
59
+ end
60
+ end
61
+
62
+ describe "#goto" do
63
+ it "moves to the cell above" do
64
+ expect(subject.goto(5, 5)).to eq(ExcelAbstraction::CellReference.new(row: 5, col: 5))
65
+ end
66
+ end
67
+
68
+ describe "#reset" do
69
+ it "moves to the cell above" do
70
+ expect(subject.reset).to eq(ExcelAbstraction::CellReference.new(row: 0, col: 0))
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe ExcelAbstraction::CellRange do
4
+ subject { described_class.new }
5
+
6
+ describe "enumeration" do
7
+ before :each do
8
+ subject << {row: 1, col: 0}
9
+ subject << {row: 1, col: 1}
10
+ subject << {row: 1, col: 2}
11
+ end
12
+
13
+ it "enumerates over the cell references in the range" do
14
+ expect(subject.inject(0) { |sum, cell| sum + (cell.row * cell.col) }).to eq 3
15
+ end
16
+ end
17
+
18
+ describe "#<<" do
19
+ before :each do
20
+ subject << {row: 1, col: 0}
21
+ end
22
+
23
+ context "when the cell to be inserted is not in the same row" do
24
+ it "raises an exception" do
25
+ expect { subject << {row: 2, col: 1} }.to raise_exception(ArgumentError)
26
+ end
27
+ end
28
+
29
+ context "when the cell to be inserted is in the same row" do
30
+ it "inserts the cell" do
31
+ subject << {row: 1, col: 1}
32
+ expect(subject.last).to eq(ExcelAbstraction::CellReference.new(row: 1, col: 1))
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe ExcelAbstraction::CellReference do
4
+ subject { described_class.new(row: 1, col: 1) }
5
+
6
+ describe "#<=>" do
7
+ context "when the row of the other cell reference is same" do
8
+ context "when the other cell reference is before" do
9
+ let(:other){ described_class.new(row: 1, col: 0) }
10
+
11
+ it "returns 1" do
12
+ expect(subject <=> other).to eq 1
13
+ end
14
+ end
15
+
16
+ context "when the other cell reference is same" do
17
+ let(:other){ described_class.new(row: 1, col: 1) }
18
+
19
+ it "returns 0" do
20
+ expect(subject <=> other).to eq 0
21
+ end
22
+ end
23
+
24
+ context "when the other cell reference is after" do
25
+ let(:other){ described_class.new(row: 1, col: 2) }
26
+
27
+ it "returns -1" do
28
+ expect(subject <=> other).to eq -1
29
+ end
30
+ end
31
+ end
32
+
33
+ context "when the row of the other cell reference is before" do
34
+ let(:other){ described_class.new(row: 0, col: 0) }
35
+
36
+ it "returns 1" do
37
+ expect(subject <=> other).to eq 1
38
+ end
39
+ end
40
+
41
+ context "when the row of the other cell reference is after" do
42
+ let(:other){ described_class.new(row: 2, col: 0) }
43
+
44
+ it "returns -1" do
45
+ expect(subject <=> other).to eq -1
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "#succ" do
51
+ its(:succ){ is_expected.to eq described_class.new(row: 1, col: 2) }
52
+ end
53
+
54
+ describe "#to_s" do
55
+ its(:to_s){ is_expected.to eq "B2"}
56
+ end
57
+
58
+ describe "#to_cell_reference" do
59
+ its(:to_cell_reference){ is_expected.to eq subject }
60
+ end
61
+
62
+ describe "#to_ary" do
63
+ its(:to_ary){ is_expected.to eq [1, 1] }
64
+ end
65
+
66
+ describe "#to_a" do
67
+ its(:to_a){ is_expected.to eq [1, 1] }
68
+ end
69
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe ExcelAbstraction::Cell do
4
+ subject { described_class.new(position: 1, val: "CellValue", style: {bold: true}) }
5
+
6
+ describe "#<=>" do
7
+ context "when the other position is before" do
8
+ let(:other){ described_class.new(position: 0, val: nil) }
9
+
10
+ it "return 1" do
11
+ expect(subject <=> other).to eq 1
12
+ end
13
+ end
14
+
15
+ context "when the other position is same" do
16
+ let(:other){ described_class.new(position: 1, val: nil) }
17
+
18
+ it "return 0" do
19
+ expect(subject <=> other).to eq 0
20
+ end
21
+ end
22
+
23
+ context "when the other position is after" do
24
+ let(:other){ described_class.new(position: 2, val: nil) }
25
+
26
+ it "return -1" do
27
+ expect(subject <=> other).to eq -1
28
+ end
29
+ end
30
+ end
31
+
32
+ describe "#==" do
33
+ context "when the cells are equal" do
34
+ let(:other){ described_class.new(position: 1, val: "CellValue", style: {bold: true}) }
35
+
36
+ it "returns true" do
37
+ expect(subject == other).to be_truthy
38
+ end
39
+ end
40
+
41
+ context "when the cells are not equal" do
42
+ let(:other){ described_class.new(position: 1, val: "OtherCellValue", style: {bold: true}) }
43
+
44
+ it "returns false" do
45
+ expect(subject == other).to be_falsey
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "#to_cell" do
51
+ its(:to_cell){ is_expected.to eq subject }
52
+ end
53
+
54
+ end
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+
3
+ describe ExcelAbstraction::Date do
4
+ context "when date is before REFERENCE date" do
5
+ subject { described_class.new(Date.parse("1900-01-01")) }
6
+
7
+ it "returns 1.0" do
8
+ expect(subject).to eq 1.0
9
+ end
10
+ end
11
+
12
+ context "when date is after REFERENCE date" do
13
+ subject { described_class.new(Date.parse("2000-01-19")) }
14
+
15
+ it "should return 36544.50 for Jan 19, 2000 12:00" do
16
+ expect(subject).to eq 36544.0
17
+ end
18
+ end
19
+
20
+ describe "#to_excel_date" do
21
+ subject { described_class.new(Date.parse("2012-01-23")) }
22
+
23
+ it "returns the same object" do
24
+ expect(subject.to_excel_date).to eq(subject)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe ExcelAbstraction::Row do
4
+ subject { described_class.new }
5
+
6
+ describe "enumeration" do
7
+ before :each do
8
+ subject << {position: 0, val: "foo"}
9
+ subject << {position: 1, val: "bar"}
10
+ subject << {position: 2, val: "baz"}
11
+ end
12
+
13
+ it "enumerates over the cell references in the range" do
14
+ expect(subject.reduce(""){ |str, cell| str += cell.val }).to eq "foobarbaz"
15
+ end
16
+ end
17
+
18
+ describe "#[]" do
19
+ before :each do
20
+ subject << {position: 0, val: "foo"}
21
+ subject << {position: 1, val: "bar"}
22
+ subject << {position: 2, val: "baz"}
23
+ end
24
+
25
+ it "returns the cell with the given position" do
26
+ expect(subject[1].val).to eq("bar")
27
+ end
28
+ end
29
+
30
+ describe "#<<" do
31
+ before :each do
32
+ subject << {position: 0, val: "foo"}
33
+ end
34
+
35
+ context "when the cell to be inserted is in the same row" do
36
+ it "inserts the cell" do
37
+ subject << {position: 1, val: "bar"}
38
+ expect(subject.count).to eq 2
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe ExcelAbstraction::Sheet do
4
+ let(:spreadsheet) { ExcelAbstraction::SpreadSheet.new }
5
+
6
+ subject { spreadsheet.workbook.active_sheet }
7
+
8
+ describe "#header" do
9
+ it "sets the header" do
10
+ test_excel_file do |file|
11
+ excel = create_excel(file, spreadsheet) do
12
+ subject.header("Foo")
13
+ end
14
+
15
+ expect(excel.cell("A", 1)).to eq "Foo"
16
+ expect(excel.font("A", 1)).to be_bold
17
+ end
18
+ end
19
+ end
20
+
21
+ describe "#headers" do
22
+ it "sets the headers" do
23
+ test_excel_file do |file|
24
+ excel = create_excel(file, spreadsheet) do
25
+ subject.header(["Foo", "Bar"])
26
+ end
27
+
28
+ expect(excel.cell("A", 1)).to eq "Foo"
29
+ expect(excel.font("A", 1)).to be_bold
30
+ expect(excel.cell("B", 1)).to eq "Bar"
31
+ expect(excel.font("B", 1)).to be_bold
32
+ end
33
+ end
34
+ end
35
+
36
+ describe "#cell" do
37
+ it "sets the cell value" do
38
+ test_excel_file do |file|
39
+ excel = create_excel(file, spreadsheet) do
40
+ subject.cell("Foo")
41
+ end
42
+
43
+ expect(excel.cell("A", 1)).to eq "Foo"
44
+ end
45
+ end
46
+ end
47
+
48
+ describe "#cells" do
49
+ it "sets the cell values" do
50
+ test_excel_file do |file|
51
+ excel = create_excel(file, spreadsheet) do
52
+ subject.cells(["Foo", "Bar"])
53
+ end
54
+
55
+ expect(excel.cell("A", 1)).to eq "Foo"
56
+ expect(excel.cell("B", 1)).to eq "Bar"
57
+ end
58
+ end
59
+ end
60
+
61
+ describe "#merge" do
62
+ it "merges the cells" do
63
+ test_excel_file do |file|
64
+ excel = create_excel(file, spreadsheet) do
65
+ subject.merge(1, "Foo")
66
+ subject.cell("Bar")
67
+ end
68
+
69
+ expect(excel.cell("A", 1)).to eq "Foo"
70
+ expect(excel.cell("B", 1)).to be_nil
71
+ expect(excel.cell("C", 1)).to eq "Bar"
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "#style_row" do
77
+ # hard to test; already tested manually
78
+ end
79
+
80
+ describe "#style_col" do
81
+ # hard to test; already tested manually
82
+ end
83
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'roo'
3
+
4
+ describe ExcelAbstraction::SpreadSheet do
5
+ describe "#close" do
6
+ it "closes the excel file" do
7
+ subject.close
8
+ expect(subject).to be_closed
9
+ end
10
+
11
+ context "when a block is passed" do
12
+ it "executes the block before closing the excel file" do
13
+ test = 0
14
+ subject.close { test += 1 }
15
+ expect(test).to eq(1)
16
+ expect(subject).to be_closed
17
+ end
18
+ end
19
+ end
20
+
21
+ describe "#to_s" do
22
+ it "closes the file and returns it's data" do
23
+ file = Tempfile.new('xls')
24
+ file.write subject.to_s
25
+ file.close
26
+
27
+ expect {
28
+ Roo::Excel.new(file.path, packed: nil, file_warning: :ignore)
29
+ }.to_not raise_exception
30
+
31
+ File.unlink(file.path)
32
+ expect(subject).to be_closed
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+
3
+ describe ExcelAbstraction::Time do
4
+ context "when date is before REFERENCE date" do
5
+ subject { described_class.new(Time.parse("1900-01-01 00:00 +00:00")) }
6
+
7
+ it "returns 1.0" do
8
+ expect(subject).to eq 1.0
9
+ end
10
+ end
11
+
12
+ context "when date is after REFERENCE date" do
13
+ subject { described_class.new(Time.parse("2000-01-19 12:00 +00:00")) }
14
+
15
+ it "should return 36544.50 for Jan 19, 2000 12:00" do
16
+ expect(subject).to eq 36544.5
17
+ end
18
+ end
19
+
20
+ describe "#to_excel_time" do
21
+ subject { described_class.new(Time.parse("2012-01-23 14:00")) }
22
+
23
+ it "returns the same object" do
24
+ expect(subject.to_excel_time).to eq(subject)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+ require 'roo'
3
+
4
+ describe ExcelAbstraction::WorkBook do
5
+ let(:spreadsheet) { ExcelAbstraction::SpreadSheet.new }
6
+
7
+ subject { spreadsheet.workbook }
8
+
9
+ describe "#title" do
10
+ it "sets the title property" do
11
+ expect(subject).to receive(:set_properties).with(title: 'Foo')
12
+ subject.title('Foo')
13
+ end
14
+ end
15
+
16
+ describe "#organization" do
17
+ it "sets the company property" do
18
+ expect(subject).to receive(:set_properties).with(company: 'Foo')
19
+ subject.organization('Foo')
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ require 'tempfile'
2
+
3
+ module ExcelHelper
4
+ def create_excel(file, spreadsheet)
5
+ yield if block_given?
6
+ file.puts spreadsheet.to_s
7
+ file.close
8
+ Roo::Excel.new(file.path, packed: nil, file_warning: :ignore)
9
+ end
10
+
11
+ def test_excel_file
12
+ file = Tempfile.new('test_xls')
13
+ yield(file) if block_given?
14
+ file.unlink
15
+ end
16
+ end