roo 2.6.0 → 2.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.codeclimate.yml +17 -0
- data/.github/issue_template.md +16 -0
- data/.github/pull_request_template.md +14 -0
- data/.rubocop.yml +186 -0
- data/.travis.yml +14 -11
- data/CHANGELOG.md +64 -2
- data/Gemfile +2 -4
- data/LICENSE +2 -0
- data/README.md +36 -10
- data/lib/roo/base.rb +82 -225
- data/lib/roo/constants.rb +5 -3
- data/lib/roo/csv.rb +100 -97
- data/lib/roo/excelx/cell/base.rb +26 -12
- data/lib/roo/excelx/cell/boolean.rb +9 -6
- data/lib/roo/excelx/cell/date.rb +7 -7
- data/lib/roo/excelx/cell/datetime.rb +50 -44
- data/lib/roo/excelx/cell/empty.rb +3 -2
- data/lib/roo/excelx/cell/number.rb +44 -47
- data/lib/roo/excelx/cell/string.rb +3 -3
- data/lib/roo/excelx/cell/time.rb +17 -16
- data/lib/roo/excelx/cell.rb +10 -6
- data/lib/roo/excelx/comments.rb +3 -3
- data/lib/roo/excelx/coordinate.rb +11 -4
- data/lib/roo/excelx/extractor.rb +21 -3
- data/lib/roo/excelx/format.rb +38 -31
- data/lib/roo/excelx/images.rb +26 -0
- data/lib/roo/excelx/relationships.rb +12 -4
- data/lib/roo/excelx/shared.rb +10 -3
- data/lib/roo/excelx/shared_strings.rb +9 -15
- data/lib/roo/excelx/sheet.rb +49 -10
- data/lib/roo/excelx/sheet_doc.rb +89 -48
- data/lib/roo/excelx/styles.rb +3 -3
- data/lib/roo/excelx/workbook.rb +7 -3
- data/lib/roo/excelx.rb +50 -19
- data/lib/roo/formatters/base.rb +15 -0
- data/lib/roo/formatters/csv.rb +84 -0
- data/lib/roo/formatters/matrix.rb +23 -0
- data/lib/roo/formatters/xml.rb +31 -0
- data/lib/roo/formatters/yaml.rb +40 -0
- data/lib/roo/helpers/default_attr_reader.rb +20 -0
- data/lib/roo/helpers/weak_instance_cache.rb +41 -0
- data/lib/roo/open_office.rb +17 -9
- data/lib/roo/spreadsheet.rb +1 -1
- data/lib/roo/tempdir.rb +5 -10
- data/lib/roo/utils.rb +70 -20
- data/lib/roo/version.rb +1 -1
- data/lib/roo.rb +4 -1
- data/roo.gemspec +14 -11
- data/spec/lib/roo/base_spec.rb +45 -3
- data/spec/lib/roo/excelx/relationships_spec.rb +43 -0
- data/spec/lib/roo/excelx/sheet_doc_spec.rb +11 -0
- data/spec/lib/roo/excelx_spec.rb +150 -31
- data/spec/lib/roo/strict_spec.rb +43 -0
- data/spec/lib/roo/utils_spec.rb +25 -3
- data/spec/lib/roo/weak_instance_cache_spec.rb +92 -0
- data/spec/lib/roo_spec.rb +0 -0
- data/spec/spec_helper.rb +2 -6
- data/test/excelx/cell/test_attr_reader_default.rb +72 -0
- data/test/excelx/cell/test_base.rb +5 -0
- data/test/excelx/cell/test_datetime.rb +6 -6
- data/test/excelx/cell/test_empty.rb +11 -0
- data/test/excelx/cell/test_number.rb +9 -0
- data/test/excelx/cell/test_string.rb +20 -0
- data/test/excelx/cell/test_time.rb +5 -5
- data/test/excelx/test_coordinate.rb +51 -0
- data/test/formatters/test_csv.rb +136 -0
- data/test/formatters/test_matrix.rb +76 -0
- data/test/formatters/test_xml.rb +78 -0
- data/test/formatters/test_yaml.rb +20 -0
- data/test/helpers/test_accessing_files.rb +60 -0
- data/test/helpers/test_comments.rb +43 -0
- data/test/helpers/test_formulas.rb +9 -0
- data/test/helpers/test_labels.rb +103 -0
- data/test/helpers/test_sheets.rb +55 -0
- data/test/helpers/test_styles.rb +62 -0
- data/test/roo/test_base.rb +182 -0
- data/test/roo/test_csv.rb +88 -0
- data/test/roo/test_excelx.rb +330 -0
- data/test/roo/test_libre_office.rb +9 -0
- data/test/roo/test_open_office.rb +289 -0
- data/test/test_helper.rb +129 -14
- data/test/test_roo.rb +32 -1787
- metadata +81 -29
- data/.github/ISSUE_TEMPLATE +0 -10
- data/Gemfile_ruby2 +0 -29
    
        data/spec/lib/roo/excelx_spec.rb
    CHANGED
    
    | @@ -151,6 +151,22 @@ describe Roo::Excelx do | |
| 151 151 | 
             
                it 'returns the expected result' do
         | 
| 152 152 | 
             
                  expect(subject.sheet_for("Tabelle1").instance_variable_get("@name")).to eq "Tabelle1"
         | 
| 153 153 | 
             
                end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                it 'returns the expected result when passed a number' do
         | 
| 156 | 
            +
                  expect(subject.sheet_for(0).instance_variable_get("@name")).to eq "Tabelle1"
         | 
| 157 | 
            +
                end
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                it 'returns the expected result when passed a number that is not the first sheet' do
         | 
| 160 | 
            +
                  expect(subject.sheet_for(1).instance_variable_get("@name")).to eq "Name of Sheet 2"
         | 
| 161 | 
            +
                end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                it "should raise an error if passed a sheet that does not exist as an integer" do
         | 
| 164 | 
            +
                  expect { subject.sheet_for(10) }.to raise_error RangeError
         | 
| 165 | 
            +
                end
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                it "should raise an error if passed a sheet that does not exist as a string" do
         | 
| 168 | 
            +
                  expect { subject.sheet_for("does_not_exist") }.to raise_error RangeError
         | 
| 169 | 
            +
                end
         | 
| 154 170 | 
             
              end
         | 
| 155 171 |  | 
| 156 172 | 
             
              describe '#row' do
         | 
| @@ -304,6 +320,18 @@ describe Roo::Excelx do | |
| 304 320 | 
             
                end
         | 
| 305 321 | 
             
              end
         | 
| 306 322 |  | 
| 323 | 
            +
              describe '#row' do
         | 
| 324 | 
            +
                context 'integers with leading zero'
         | 
| 325 | 
            +
                  let(:path) { 'test/files/number_with_zero_prefix.xlsx' }
         | 
| 326 | 
            +
             | 
| 327 | 
            +
                  it 'returns base 10 integer' do
         | 
| 328 | 
            +
                    (1..50).each do |row_index|
         | 
| 329 | 
            +
                      range_start = (row_index - 1) * 20 + 1
         | 
| 330 | 
            +
                      expect(subject.row(row_index)).to eq (range_start..(range_start+19)).to_a
         | 
| 331 | 
            +
                    end
         | 
| 332 | 
            +
                  end
         | 
| 333 | 
            +
              end
         | 
| 334 | 
            +
             | 
| 307 335 | 
             
              describe '#excelx_format' do
         | 
| 308 336 | 
             
                let(:path) { 'test/files/style.xlsx' }
         | 
| 309 337 |  | 
| @@ -351,14 +379,50 @@ describe Roo::Excelx do | |
| 351 379 | 
             
                  expect(subject.hyperlink?(1, 1)).to eq true
         | 
| 352 380 | 
             
                  expect(subject.hyperlink?(1, 2)).to eq false
         | 
| 353 381 | 
             
                end
         | 
| 382 | 
            +
             | 
| 383 | 
            +
                context 'defined on cell range' do
         | 
| 384 | 
            +
                 let(:path) { 'test/files/cell-range-link.xlsx' }
         | 
| 385 | 
            +
             | 
| 386 | 
            +
                  it 'returns the expected result' do
         | 
| 387 | 
            +
                    [[false]*3, *[[true, true, false]]*4, [false]*3].each.with_index(1) do |row, row_index|
         | 
| 388 | 
            +
                      row.each.with_index(1) do |value, col_index|
         | 
| 389 | 
            +
                        expect(subject.hyperlink?(row_index, col_index)).to eq(value)
         | 
| 390 | 
            +
                      end
         | 
| 391 | 
            +
                    end
         | 
| 392 | 
            +
                  end
         | 
| 393 | 
            +
                end
         | 
| 354 394 | 
             
              end
         | 
| 355 395 |  | 
| 356 396 | 
             
              describe '#hyperlink' do
         | 
| 357 | 
            -
                 | 
| 397 | 
            +
                context 'defined on cell range' do
         | 
| 398 | 
            +
                 let(:path) { 'test/files/cell-range-link.xlsx' }
         | 
| 358 399 |  | 
| 359 | 
            -
             | 
| 360 | 
            -
             | 
| 361 | 
            -
             | 
| 400 | 
            +
                  it 'returns the expected result' do
         | 
| 401 | 
            +
                    link = "http://www.google.com"
         | 
| 402 | 
            +
                    [[nil]*3, *[[link, link, nil]]*4, [nil]*3].each.with_index(1) do |row, row_index|
         | 
| 403 | 
            +
                      row.each.with_index(1) do |value, col_index|
         | 
| 404 | 
            +
                        expect(subject.hyperlink(row_index, col_index)).to eq(value)
         | 
| 405 | 
            +
                      end
         | 
| 406 | 
            +
                    end
         | 
| 407 | 
            +
                  end
         | 
| 408 | 
            +
                end
         | 
| 409 | 
            +
             | 
| 410 | 
            +
                context 'without location' do
         | 
| 411 | 
            +
                  let(:path) { 'test/files/link.xlsx' }
         | 
| 412 | 
            +
             | 
| 413 | 
            +
                  it 'returns the expected result' do
         | 
| 414 | 
            +
                    expect(subject.hyperlink(1, 1)).to eq "http://www.google.com"
         | 
| 415 | 
            +
                    expect(subject.hyperlink(1, 2)).to eq nil
         | 
| 416 | 
            +
                  end
         | 
| 417 | 
            +
                end
         | 
| 418 | 
            +
             | 
| 419 | 
            +
                context 'with location' do
         | 
| 420 | 
            +
                  let(:path) { 'test/files/link_with_location.xlsx' }
         | 
| 421 | 
            +
             | 
| 422 | 
            +
                  it 'returns the expected result' do
         | 
| 423 | 
            +
                    expect(subject.hyperlink(1, 1)).to eq "http://www.google.com/#hey"
         | 
| 424 | 
            +
                    expect(subject.hyperlink(1, 2)).to eq nil
         | 
| 425 | 
            +
                  end
         | 
| 362 426 | 
             
                end
         | 
| 363 427 | 
             
              end
         | 
| 364 428 |  | 
| @@ -480,34 +544,36 @@ describe Roo::Excelx do | |
| 480 544 | 
             
              end
         | 
| 481 545 |  | 
| 482 546 | 
             
              describe '#html_strings' do
         | 
| 483 | 
            -
                 | 
| 547 | 
            +
                describe "HTML Parsing Enabling" do
         | 
| 548 | 
            +
                  let(:path) { 'test/files/html_strings_formatting.xlsx' }
         | 
| 484 549 |  | 
| 485 | 
            -
             | 
| 486 | 
            -
             | 
| 487 | 
            -
             | 
| 488 | 
            -
             | 
| 489 | 
            -
             | 
| 490 | 
            -
             | 
| 491 | 
            -
             | 
| 492 | 
            -
             | 
| 493 | 
            -
             | 
| 494 | 
            -
             | 
| 495 | 
            -
             | 
| 496 | 
            -
             | 
| 497 | 
            -
             | 
| 498 | 
            -
             | 
| 499 | 
            -
             | 
| 500 | 
            -
             | 
| 501 | 
            -
             | 
| 502 | 
            -
             | 
| 503 | 
            -
             | 
| 504 | 
            -
             | 
| 505 | 
            -
             | 
| 506 | 
            -
             | 
| 507 | 
            -
             | 
| 508 | 
            -
             | 
| 509 | 
            -
             | 
| 510 | 
            -
             | 
| 550 | 
            +
                  it 'returns the expected result' do
         | 
| 551 | 
            +
                    expect(subject.excelx_value(1, 1, "Sheet1")).to eq("This has no formatting.")
         | 
| 552 | 
            +
                    expect(subject.excelx_value(2, 1, "Sheet1")).to eq("<html>This has<b> bold </b>formatting.</html>")
         | 
| 553 | 
            +
                    expect(subject.excelx_value(2, 2, "Sheet1")).to eq("<html>This has <i>italics</i> formatting.</html>")
         | 
| 554 | 
            +
                    expect(subject.excelx_value(2, 3, "Sheet1")).to eq("<html>This has <u>underline</u> format.</html>")
         | 
| 555 | 
            +
                    expect(subject.excelx_value(2, 4, "Sheet1")).to eq("<html>Superscript. x<sup>123</sup></html>")
         | 
| 556 | 
            +
                    expect(subject.excelx_value(2, 5, "Sheet1")).to eq("<html>SubScript.  T<sub>j</sub></html>")
         | 
| 557 | 
            +
             | 
| 558 | 
            +
                    expect(subject.excelx_value(3, 1, "Sheet1")).to eq("<html>Bold, italics <b><i>together</i></b>.</html>")
         | 
| 559 | 
            +
                    expect(subject.excelx_value(3, 2, "Sheet1")).to eq("<html>Bold, Underline <b><u>together</u></b>.</html>")
         | 
| 560 | 
            +
                    expect(subject.excelx_value(3, 3, "Sheet1")).to eq("<html>Bold, Superscript. <b>x</b><sup><b>N</b></sup></html>")
         | 
| 561 | 
            +
                    expect(subject.excelx_value(3, 4, "Sheet1")).to eq("<html>Bold, Subscript. <b>T</b><sub><b>abc</b></sub></html>")
         | 
| 562 | 
            +
                    expect(subject.excelx_value(3, 5, "Sheet1")).to eq("<html>Italics, Underline <i><u>together</u></i>.</html>")
         | 
| 563 | 
            +
                    expect(subject.excelx_value(3, 6, "Sheet1")).to eq("<html>Italics, Superscript.  <i>X</i><sup><i>abc</i></sup></html>")
         | 
| 564 | 
            +
                    expect(subject.excelx_value(3, 7, "Sheet1")).to eq("<html>Italics, Subscript.  <i>B</i><sub><i>efg</i></sub></html>")
         | 
| 565 | 
            +
                    expect(subject.excelx_value(4, 1, "Sheet1")).to eq("<html>Bold, italics underline,<b><i><u> together</u></i></b>.</html>")
         | 
| 566 | 
            +
                    expect(subject.excelx_value(4, 2, "Sheet1")).to eq("<html>Bold, italics, superscript. <b>X</b><sup><b><i>abc</i></b></sup><b><i>123</i></b></html>")
         | 
| 567 | 
            +
                    expect(subject.excelx_value(4, 3, "Sheet1")).to eq("<html>Bold, Italics, subscript. <b><i>Mg</i></b><sub><b><i>ha</i></b></sub><b><i>2</i></b></html>")
         | 
| 568 | 
            +
                    expect(subject.excelx_value(4, 4, "Sheet1")).to eq("<html>Bold, Underline, superscript. <b><u>AB</u></b><sup><b><u>C12</u></b></sup><b><u>3</u></b></html>")
         | 
| 569 | 
            +
                    expect(subject.excelx_value(4, 5, "Sheet1")).to eq("<html>Bold, Underline, subscript. <b><u>Good</u></b><sub><b><u>XYZ</u></b></sub></html>")
         | 
| 570 | 
            +
                    expect(subject.excelx_value(4, 6, "Sheet1")).to eq("<html>Italics, Underline, superscript. <i><u>Up</u></i><sup><i><u>swing</u></i></sup></html>")
         | 
| 571 | 
            +
                    expect(subject.excelx_value(4, 7, "Sheet1")).to eq("<html>Italics, Underline, subscript. <i><u>T</u></i><sub><i><u>swing</u></i></sub></html>")
         | 
| 572 | 
            +
                    expect(subject.excelx_value(5, 1, "Sheet1")).to eq("<html>Bold, italics, underline, superscript.  <b><i><u>GHJK</u></i></b><sup><b><i><u>190</u></i></b></sup><b><i><u>4</u></i></b></html>")
         | 
| 573 | 
            +
                    expect(subject.excelx_value(5, 2, "Sheet1")).to eq("<html>Bold, italics, underline, subscript. <b><i><u>Mike</u></i></b><sub><b><i><u>drop</u></i></b></sub></html>")
         | 
| 574 | 
            +
                    expect(subject.excelx_value(6, 1, "Sheet1")).to eq("See that regular html tags do not create html tags.\n<ol>\n  <li> Denver Broncos </li>\n  <li> Carolina Panthers </li>\n  <li> New England Patriots</li>\n  <li>Arizona Panthers</li>\n</ol>")
         | 
| 575 | 
            +
                    expect(subject.excelx_value(7, 1, "Sheet1")).to eq("<html>Does create html tags when formatting is used..\n<ol>\n  <li> <b>Denver Broncos</b> </li>\n  <li> <i>Carolina Panthers </i></li>\n  <li> <u>New England Patriots</u></li>\n  <li>Arizona Panthers</li>\n</ol></html>")
         | 
| 576 | 
            +
                  end
         | 
| 511 577 | 
             
                end
         | 
| 512 578 | 
             
              end
         | 
| 513 579 |  | 
| @@ -534,4 +600,57 @@ describe Roo::Excelx do | |
| 534 600 | 
             
                  expect(subject.sheet(0).excelx_format(2,1)).to eq 'm/d/yyyy" "h:mm:ss" "AM/PM'
         | 
| 535 601 | 
             
                end
         | 
| 536 602 | 
             
              end
         | 
| 603 | 
            +
             | 
| 604 | 
            +
              describe 'images' do
         | 
| 605 | 
            +
                let(:path) { 'test/files/images.xlsx' }
         | 
| 606 | 
            +
             | 
| 607 | 
            +
                it 'returns array of images from default sheet' do
         | 
| 608 | 
            +
                  expect(subject.images).to be_kind_of(Array)
         | 
| 609 | 
            +
                  expect(subject.images.size).to eql(19)
         | 
| 610 | 
            +
                end
         | 
| 611 | 
            +
             | 
| 612 | 
            +
                it 'returns empty array if there is no images on the sheet' do
         | 
| 613 | 
            +
                  expect(subject.images("Sheet2")).to eql([])
         | 
| 614 | 
            +
                end
         | 
| 615 | 
            +
              end
         | 
| 537 616 | 
             
            end
         | 
| 617 | 
            +
             | 
| 618 | 
            +
            describe 'Roo::Excelx with options set' do
         | 
| 619 | 
            +
              subject(:xlsx) do
         | 
| 620 | 
            +
                Roo::Excelx.new(path, disable_html_wrapper: true)
         | 
| 621 | 
            +
              end
         | 
| 622 | 
            +
             | 
| 623 | 
            +
              describe '#html_strings' do
         | 
| 624 | 
            +
                describe "HTML Parsing Disabled" do
         | 
| 625 | 
            +
                  let(:path) { 'test/files/html_strings_formatting.xlsx' }
         | 
| 626 | 
            +
             | 
| 627 | 
            +
                  it 'returns the expected result' do
         | 
| 628 | 
            +
                    expect(subject.excelx_value(1, 1, "Sheet1")).to eq("This has no formatting.")
         | 
| 629 | 
            +
                    expect(subject.excelx_value(2, 1, "Sheet1")).to eq("This has bold formatting.")
         | 
| 630 | 
            +
                    expect(subject.excelx_value(2, 2, "Sheet1")).to eq("This has italics formatting.")
         | 
| 631 | 
            +
                    expect(subject.excelx_value(2, 3, "Sheet1")).to eq("This has underline format.")
         | 
| 632 | 
            +
                    expect(subject.excelx_value(2, 4, "Sheet1")).to eq("Superscript. x123")
         | 
| 633 | 
            +
                    expect(subject.excelx_value(2, 5, "Sheet1")).to eq("SubScript.  Tj")
         | 
| 634 | 
            +
             | 
| 635 | 
            +
                    expect(subject.excelx_value(3, 1, "Sheet1")).to eq("Bold, italics together.")
         | 
| 636 | 
            +
                    expect(subject.excelx_value(3, 2, "Sheet1")).to eq("Bold, Underline together.")
         | 
| 637 | 
            +
                    expect(subject.excelx_value(3, 3, "Sheet1")).to eq("Bold, Superscript. xN")
         | 
| 638 | 
            +
                    expect(subject.excelx_value(3, 4, "Sheet1")).to eq("Bold, Subscript. Tabc")
         | 
| 639 | 
            +
                    expect(subject.excelx_value(3, 5, "Sheet1")).to eq("Italics, Underline together.")
         | 
| 640 | 
            +
                    expect(subject.excelx_value(3, 6, "Sheet1")).to eq("Italics, Superscript.  Xabc")
         | 
| 641 | 
            +
                    expect(subject.excelx_value(3, 7, "Sheet1")).to eq("Italics, Subscript.  Befg")
         | 
| 642 | 
            +
                    expect(subject.excelx_value(4, 1, "Sheet1")).to eq("Bold, italics underline, together.")
         | 
| 643 | 
            +
                    expect(subject.excelx_value(4, 2, "Sheet1")).to eq("Bold, italics, superscript. Xabc123")
         | 
| 644 | 
            +
                    expect(subject.excelx_value(4, 3, "Sheet1")).to eq("Bold, Italics, subscript. Mgha2")
         | 
| 645 | 
            +
                    expect(subject.excelx_value(4, 4, "Sheet1")).to eq("Bold, Underline, superscript. ABC123")
         | 
| 646 | 
            +
                    expect(subject.excelx_value(4, 5, "Sheet1")).to eq("Bold, Underline, subscript. GoodXYZ")
         | 
| 647 | 
            +
                    expect(subject.excelx_value(4, 6, "Sheet1")).to eq("Italics, Underline, superscript. Upswing")
         | 
| 648 | 
            +
                    expect(subject.excelx_value(4, 7, "Sheet1")).to eq("Italics, Underline, subscript. Tswing")
         | 
| 649 | 
            +
                    expect(subject.excelx_value(5, 1, "Sheet1")).to eq("Bold, italics, underline, superscript.  GHJK1904")
         | 
| 650 | 
            +
                    expect(subject.excelx_value(5, 2, "Sheet1")).to eq("Bold, italics, underline, subscript. Mikedrop")
         | 
| 651 | 
            +
                    expect(subject.excelx_value(6, 1, "Sheet1")).to eq("See that regular html tags do not create html tags.\n<ol>\n  <li> Denver Broncos </li>\n  <li> Carolina Panthers </li>\n  <li> New England Patriots</li>\n  <li>Arizona Panthers</li>\n</ol>")
         | 
| 652 | 
            +
                    expect(subject.excelx_value(7, 1, "Sheet1")).to eq("Does create html tags when formatting is used..\n<ol>\n  <li> Denver Broncos </li>\n  <li> Carolina Panthers </li>\n  <li> New England Patriots</li>\n  <li>Arizona Panthers</li>\n</ol>")
         | 
| 653 | 
            +
                  end
         | 
| 654 | 
            +
                end
         | 
| 655 | 
            +
              end
         | 
| 656 | 
            +
            end
         | 
| @@ -0,0 +1,43 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Roo::Excelx do
         | 
| 4 | 
            +
              subject { Roo::Excelx.new('test/files/strict.xlsx') }
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              example '#sheets' do
         | 
| 7 | 
            +
                expect(subject.sheets).to eq %w(Sheet1 Sheet2)
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              example '#sheet' do
         | 
| 11 | 
            +
                expect(subject.sheet('Sheet1')).to be_a(Roo::Excelx)
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              example '#cell' do
         | 
| 15 | 
            +
                expect(subject.cell(1, 1)).to eq 'Sheet 1'
         | 
| 16 | 
            +
                expect(subject.cell(1, 1, 'Sheet2')).to eq 'Sheet 2'
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              example '#row' do
         | 
| 20 | 
            +
                expect(subject.row(1)).to eq ['Sheet 1']
         | 
| 21 | 
            +
                expect(subject.row(1, 'Sheet2')).to eq ['Sheet 2']
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              example '#first_row' do
         | 
| 25 | 
            +
                expect(subject.first_row).to eq 1
         | 
| 26 | 
            +
                expect(subject.first_row('Sheet2')).to eq 1
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              example '#last_row' do
         | 
| 30 | 
            +
                expect(subject.last_row).to eq 1
         | 
| 31 | 
            +
                expect(subject.last_row('Sheet2')).to eq 1
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              example '#first_column' do
         | 
| 35 | 
            +
                expect(subject.first_column).to eq 1
         | 
| 36 | 
            +
                expect(subject.first_column('Sheet2')).to eq 1
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              example '#last_column' do
         | 
| 40 | 
            +
                expect(subject.last_column).to eq 1
         | 
| 41 | 
            +
                expect(subject.last_column('Sheet2')).to eq 1
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
            end
         | 
    
        data/spec/lib/roo/utils_spec.rb
    CHANGED
    
    | @@ -52,6 +52,15 @@ RSpec.describe ::Roo::Utils do | |
| 52 52 | 
             
                end
         | 
| 53 53 | 
             
              end
         | 
| 54 54 |  | 
| 55 | 
            +
              context '.extract_coordinate' do
         | 
| 56 | 
            +
                it "returns the expected result" do
         | 
| 57 | 
            +
                  expect(described_class.extract_coordinate('A1')).to eq [1, 1]
         | 
| 58 | 
            +
                  expect(described_class.extract_coordinate('B2')).to eq [2, 2]
         | 
| 59 | 
            +
                  expect(described_class.extract_coordinate('R2')).to eq [2, 18]
         | 
| 60 | 
            +
                  expect(described_class.extract_coordinate('AR31')).to eq [31, 18 + 26]
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
             | 
| 55 64 | 
             
              context '.split_coord' do
         | 
| 56 65 | 
             
                it "returns the expected result" do
         | 
| 57 66 | 
             
                  expect(described_class.split_coord('A1')).to eq ["A", 1]
         | 
| @@ -81,26 +90,39 @@ RSpec.describe ::Roo::Utils do | |
| 81 90 | 
             
                end
         | 
| 82 91 | 
             
              end
         | 
| 83 92 |  | 
| 93 | 
            +
              context '.coordinates_in_range' do
         | 
| 94 | 
            +
                it "returns the expected result" do
         | 
| 95 | 
            +
                  expect(described_class.coordinates_in_range('').to_a).to eq []
         | 
| 96 | 
            +
                  expect(described_class.coordinates_in_range('B2').to_a).to eq [[2, 2]]
         | 
| 97 | 
            +
                  expect(described_class.coordinates_in_range('D2:G3').to_a).to eq [[2, 4], [2, 5], [2, 6], [2, 7], [3, 4], [3, 5], [3, 6], [3, 7]]
         | 
| 98 | 
            +
                  expect(described_class.coordinates_in_range('G3:D2').to_a).to eq []
         | 
| 99 | 
            +
                end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                it "raises an error when appropriate" do
         | 
| 102 | 
            +
                  expect { described_class.coordinates_in_range('D2:G3:I5').to_a }.to raise_error(ArgumentError)
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
              end
         | 
| 105 | 
            +
             | 
| 84 106 | 
             
              context '.load_xml' do
         | 
| 85 107 | 
             
                it 'returns the expected result' do
         | 
| 86 108 | 
             
                  expect(described_class.load_xml('test/files/sheet1.xml')).to be_a(Nokogiri::XML::Document)
         | 
| 87 109 | 
             
                  expect(described_class.load_xml('test/files/sheet1.xml').
         | 
| 88 110 | 
             
                             remove_namespaces!.xpath("/worksheet/dimension").map do |dim|
         | 
| 89 | 
            -
                              dim | 
| 111 | 
            +
                              dim["ref"] end.first).to eq "A1:B11"
         | 
| 90 112 | 
             
                end
         | 
| 91 113 | 
             
              end
         | 
| 92 114 |  | 
| 93 115 | 
             
              context '.each_element' do
         | 
| 94 116 | 
             
                it 'returns the expected result' do
         | 
| 95 117 | 
             
                  described_class.each_element('test/files/sheet1.xml', 'dimension') do |dim|
         | 
| 96 | 
            -
                    expect(dim | 
| 118 | 
            +
                    expect(dim["ref"]).to eq "A1:B11"
         | 
| 97 119 | 
             
                  end
         | 
| 98 120 | 
             
                  rows = []
         | 
| 99 121 | 
             
                  described_class.each_element('test/files/sheet1.xml', 'row') do |row|
         | 
| 100 122 | 
             
                    rows << row
         | 
| 101 123 | 
             
                  end
         | 
| 102 124 | 
             
                  expect(rows.size).to eq 11
         | 
| 103 | 
            -
                  expect(rows[2] | 
| 125 | 
            +
                  expect(rows[2]["r"]).to eq "3"
         | 
| 104 126 | 
             
                end
         | 
| 105 127 | 
             
              end
         | 
| 106 128 | 
             
            end
         | 
| @@ -0,0 +1,92 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            if RUBY_PLATFORM == "java"
         | 
| 4 | 
            +
              require 'java'
         | 
| 5 | 
            +
              java_import 'java.lang.System'
         | 
| 6 | 
            +
            end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            describe Roo::Helpers::WeakInstanceCache do
         | 
| 9 | 
            +
              let(:klass) do
         | 
| 10 | 
            +
                Class.new do
         | 
| 11 | 
            +
                  include Roo::Helpers::WeakInstanceCache
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def memoized_data
         | 
| 14 | 
            +
                    instance_cache(:@memoized_data) do
         | 
| 15 | 
            +
                      "Some Costly Operation #{rand(1000)}" * 1_000
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              subject do
         | 
| 22 | 
            +
                klass.new
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              it 'should be lazy' do
         | 
| 26 | 
            +
                expect(subject.instance_variables).to_not include(:@memoized_data)
         | 
| 27 | 
            +
                data = subject.memoized_data
         | 
| 28 | 
            +
                expect(subject.instance_variables).to include(:@memoized_data)
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
             | 
| 32 | 
            +
              it 'should be memoized' do
         | 
| 33 | 
            +
                data = subject.memoized_data
         | 
| 34 | 
            +
                expect(subject.memoized_data).to equal(data)
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              it 'should recalculate after GC' do
         | 
| 38 | 
            +
                expect(subject.instance_variables).to_not include(:@memoized_data)
         | 
| 39 | 
            +
                GC.disable
         | 
| 40 | 
            +
                subject.memoized_data && nil
         | 
| 41 | 
            +
                expect(subject.instance_variables).to include(:@memoized_data)
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                force_gc
         | 
| 44 | 
            +
                expect(subject.instance_variables).to_not include(:@memoized_data)
         | 
| 45 | 
            +
                GC.disable
         | 
| 46 | 
            +
                subject.memoized_data && nil
         | 
| 47 | 
            +
                expect(subject.instance_variables).to include(:@memoized_data)
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              it 'must remove instance variable' do
         | 
| 51 | 
            +
                expect(subject.instance_variables).to_not include(:@memoized_data)
         | 
| 52 | 
            +
                GC.disable
         | 
| 53 | 
            +
                subject.memoized_data && nil
         | 
| 54 | 
            +
                expect(subject.instance_variables).to include(:@memoized_data)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                force_gc
         | 
| 57 | 
            +
                expect(subject.instance_variables).to_not include(:@memoized_data)
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
              context '#inspect must not raise' do
         | 
| 61 | 
            +
                it 'before calculation' do
         | 
| 62 | 
            +
                  expect{subject.inspect}.to_not raise_error
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
                it 'after calculation' do
         | 
| 65 | 
            +
                  GC.disable
         | 
| 66 | 
            +
                  subject.memoized_data && nil
         | 
| 67 | 
            +
                  expect{subject.inspect}.to_not raise_error
         | 
| 68 | 
            +
                  expect(subject.inspect).to include("Some Costly Operation")
         | 
| 69 | 
            +
                  force_gc
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
                it 'after GC' do
         | 
| 72 | 
            +
                  subject.memoized_data && nil
         | 
| 73 | 
            +
                  force_gc
         | 
| 74 | 
            +
                  expect(subject.instance_variables).to_not include(:@memoized_data)
         | 
| 75 | 
            +
                  expect{subject.inspect}.to_not raise_error
         | 
| 76 | 
            +
                  expect(subject.inspect).to_not include("Some Costly Operation")
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              if RUBY_PLATFORM == "java"
         | 
| 81 | 
            +
                def force_gc
         | 
| 82 | 
            +
                  System.gc
         | 
| 83 | 
            +
                  sleep(0.1)
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
              else
         | 
| 86 | 
            +
                def force_gc
         | 
| 87 | 
            +
                  GC.start(full_mark: true, immediate_sweep: true)
         | 
| 88 | 
            +
                  sleep(0.1)
         | 
| 89 | 
            +
                  GC.start(full_mark: true, immediate_sweep: true)
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
            end
         | 
| 
            File without changes
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -1,13 +1,9 @@ | |
| 1 1 | 
             
            require 'simplecov'
         | 
| 2 2 | 
             
            require 'roo'
         | 
| 3 | 
            -
            require 'vcr'
         | 
| 4 3 | 
             
            require 'helpers'
         | 
| 5 4 |  | 
| 6 5 | 
             
            RSpec.configure do |c|
         | 
| 7 6 | 
             
              c.include Helpers
         | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
            VCR.configure do |c|
         | 
| 11 | 
            -
              c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
         | 
| 12 | 
            -
              c.hook_into :webmock # or :fakeweb
         | 
| 7 | 
            +
              c.color = true
         | 
| 8 | 
            +
              c.formatter = :documentation if ENV["USE_REPORTERS"]
         | 
| 13 9 | 
             
            end
         | 
| @@ -0,0 +1,72 @@ | |
| 1 | 
            +
            require "test_helper"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class TestAttrReaderDefault < Minitest::Test
         | 
| 4 | 
            +
              def base
         | 
| 5 | 
            +
                Roo::Excelx::Cell::Base
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              def boolean
         | 
| 9 | 
            +
                Roo::Excelx::Cell::Boolean
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              def class_date
         | 
| 13 | 
            +
                Roo::Excelx::Cell::Date
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              def datetime
         | 
| 17 | 
            +
                Roo::Excelx::Cell::DateTime
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              def empty
         | 
| 21 | 
            +
                Roo::Excelx::Cell::Empty
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              def number
         | 
| 25 | 
            +
                Roo::Excelx::Cell::Number
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              def string
         | 
| 29 | 
            +
                Roo::Excelx::Cell::String
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              def base_date
         | 
| 33 | 
            +
                ::Date.new(1899, 12, 30)
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              def base_timestamp
         | 
| 37 | 
            +
                ::Date.new(1899, 12, 30).to_datetime.to_time.to_i
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              def class_time
         | 
| 41 | 
            +
                Roo::Excelx::Cell::Time
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              def test_cell_default_values
         | 
| 45 | 
            +
                assert_values base.new(nil, nil, [], 1, nil, nil), default_type: :base, :@default_type => nil, style: 1, :@style => nil
         | 
| 46 | 
            +
                assert_values boolean.new("1", nil, nil, nil, nil), default_type: :boolean, :@default_type => nil, cell_type: :boolean, :@cell_type => nil
         | 
| 47 | 
            +
                assert_values class_date.new("41791", nil, [:numeric_or_formula, "mm-dd-yy"], 6, nil, base_date, nil), default_type: :date, :@default_type => nil
         | 
| 48 | 
            +
                assert_values class_time.new("0.521", nil, [:numeric_or_formula, "hh:mm"], 6, nil, base_timestamp, nil), default_type: :time, :@default_type => nil
         | 
| 49 | 
            +
                assert_values datetime.new("41791.521", nil, [:numeric_or_formula, "mm-dd-yy hh:mm"], 6, nil, base_timestamp, nil), default_type: :datetime, :@default_type => nil
         | 
| 50 | 
            +
                assert_values empty.new(nil), default_type: nil, :@default_type => nil, style: nil, :@style => nil
         | 
| 51 | 
            +
                assert_values number.new("42", nil, ["0"], nil, nil, nil), default_type: :float, :@default_type => nil
         | 
| 52 | 
            +
                assert_values string.new("1", nil, nil, nil, nil), default_type: :string, :@default_type => nil, cell_type: :string, :@cell_type => nil
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                assert_values base.new(nil, nil, [], 2, nil, nil), style: 2, :@style => 2
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              def assert_values(object, value_hash)
         | 
| 58 | 
            +
                value_hash.each do |attr_name, expected_value|
         | 
| 59 | 
            +
                  value = if attr_name.to_s.include?("@")
         | 
| 60 | 
            +
                            object.instance_variable_defined?(attr_name) ? object.instance_variable_get(attr_name) : nil
         | 
| 61 | 
            +
                          else
         | 
| 62 | 
            +
                            object.public_send(attr_name)
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  if expected_value
         | 
| 66 | 
            +
                    assert_equal expected_value, value
         | 
| 67 | 
            +
                  else
         | 
| 68 | 
            +
                    assert_nil value
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
            end
         | 
| @@ -25,6 +25,11 @@ class TestRooExcelxCellBase < Minitest::Test | |
| 25 25 | 
             
                refute cell.empty?
         | 
| 26 26 | 
             
              end
         | 
| 27 27 |  | 
| 28 | 
            +
              def test_presence
         | 
| 29 | 
            +
                cell = base.new(value, nil, [], nil, nil, nil)
         | 
| 30 | 
            +
                assert_equal cell, cell.presence
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 28 33 | 
             
              def test_cell_type_is_formula
         | 
| 29 34 | 
             
                formula = true
         | 
| 30 35 | 
             
                cell = base.new(value, formula, [], nil, nil, nil)
         | 
| @@ -2,12 +2,12 @@ require 'test_helper' | |
| 2 2 |  | 
| 3 3 | 
             
            class TestRooExcelxCellDateTime < Minitest::Test
         | 
| 4 4 | 
             
              def test_cell_value_is_datetime
         | 
| 5 | 
            -
                cell = datetime.new('30000.323212', nil, ['mm-dd-yy'], nil, nil,  | 
| 5 | 
            +
                cell = datetime.new('30000.323212', nil, ['mm-dd-yy'], nil, nil, base_timestamp, nil)
         | 
| 6 6 | 
             
                assert_kind_of ::DateTime, cell.value
         | 
| 7 7 | 
             
              end
         | 
| 8 8 |  | 
| 9 9 | 
             
              def test_cell_type_is_datetime
         | 
| 10 | 
            -
                cell = datetime.new('30000.323212', nil, [], nil, nil,  | 
| 10 | 
            +
                cell = datetime.new('30000.323212', nil, [], nil, nil, base_timestamp, nil)
         | 
| 11 11 | 
             
                assert_equal :datetime, cell.type
         | 
| 12 12 | 
             
              end
         | 
| 13 13 |  | 
| @@ -19,7 +19,7 @@ class TestRooExcelxCellDateTime < Minitest::Test | |
| 19 19 | 
             
                  ['mmm-yy', 'JAN-15'],
         | 
| 20 20 | 
             
                  ['m/d/yy h:mm', '1/25/15 8:15']
         | 
| 21 21 | 
             
                ].each do |format, formatted_value|
         | 
| 22 | 
            -
                  cell = datetime.new '42029.34375', nil, [format], nil, nil,  | 
| 22 | 
            +
                  cell = datetime.new '42029.34375', nil, [format], nil, nil, base_timestamp, nil
         | 
| 23 23 | 
             
                  assert_equal formatted_value, cell.formatted_value
         | 
| 24 24 | 
             
                end
         | 
| 25 25 | 
             
              end
         | 
| @@ -30,7 +30,7 @@ class TestRooExcelxCellDateTime < Minitest::Test | |
| 30 30 | 
             
                  ['h:mm:ss000 mm/yy', '8:15:00000 01/15'],
         | 
| 31 31 | 
             
                  ['mmm yyy', '2015-01-25 08:15:00']
         | 
| 32 32 | 
             
                ].each do |format, formatted_value|
         | 
| 33 | 
            -
                  cell = datetime.new '42029.34375', nil, [format], nil, nil,  | 
| 33 | 
            +
                  cell = datetime.new '42029.34375', nil, [format], nil, nil, base_timestamp, nil
         | 
| 34 34 | 
             
                  assert_equal formatted_value, cell.formatted_value
         | 
| 35 35 | 
             
                end
         | 
| 36 36 | 
             
              end
         | 
| @@ -39,7 +39,7 @@ class TestRooExcelxCellDateTime < Minitest::Test | |
| 39 39 | 
             
                Roo::Excelx::Cell::DateTime
         | 
| 40 40 | 
             
              end
         | 
| 41 41 |  | 
| 42 | 
            -
              def  | 
| 43 | 
            -
                 | 
| 42 | 
            +
              def base_timestamp
         | 
| 43 | 
            +
                DateTime.new(1899, 12, 30).to_time.to_i
         | 
| 44 44 | 
             
              end
         | 
| 45 45 | 
             
            end
         | 
| @@ -4,4 +4,15 @@ class TestRooExcelxCellEmpty < Minitest::Test | |
| 4 4 | 
             
              def empty
         | 
| 5 5 | 
             
                Roo::Excelx::Cell::Empty
         | 
| 6 6 | 
             
              end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              def test_empty?
         | 
| 9 | 
            +
                cell = empty.new(nil)
         | 
| 10 | 
            +
                assert_same  true, cell.empty?
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              def test_nil_presence
         | 
| 14 | 
            +
                cell = empty.new(nil)
         | 
| 15 | 
            +
                assert_nil cell.presence
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 7 18 | 
             
            end
         | 
| @@ -25,6 +25,11 @@ class TestRooExcelxCellNumber < Minitest::Test | |
| 25 25 | 
             
                assert_kind_of(Float, cell.value)
         | 
| 26 26 | 
             
              end
         | 
| 27 27 |  | 
| 28 | 
            +
              def test_very_simple_scientific_notation
         | 
| 29 | 
            +
                cell = Roo::Excelx::Cell::Number.new '1e6', nil, ['0'], nil, nil, nil
         | 
| 30 | 
            +
                assert_kind_of(Float, cell.value)
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 28 33 | 
             
              def test_percent
         | 
| 29 34 | 
             
                cell = Roo::Excelx::Cell::Number.new '42.1', nil, ['0.00%'], nil, nil, nil
         | 
| 30 35 | 
             
                assert_kind_of(Float, cell.value)
         | 
| @@ -53,8 +58,12 @@ class TestRooExcelxCellNumber < Minitest::Test | |
| 53 58 | 
             
              def test_formats
         | 
| 54 59 | 
             
                [
         | 
| 55 60 | 
             
                  ['General', '1042'],
         | 
| 61 | 
            +
                  ['GENERAL', '1042'],
         | 
| 56 62 | 
             
                  ['0', '1042'],
         | 
| 63 | 
            +
                  ['000000', '001042'],
         | 
| 57 64 | 
             
                  ['0.00', '1042.00'],
         | 
| 65 | 
            +
                  ['0.0000', '1042.0000'],
         | 
| 66 | 
            +
                  ['0.000000000', '1042.000000000'],
         | 
| 58 67 | 
             
                  ['#,##0', '1,042'],
         | 
| 59 68 | 
             
                  ['#,##0.00', '1,042.00'],
         | 
| 60 69 | 
             
                  ['0%', '104200%'],
         | 
| @@ -25,4 +25,24 @@ class TestRooExcelxCellString < Minitest::Test | |
| 25 25 | 
             
                cell = string.new '0', nil, nil, nil, nil
         | 
| 26 26 | 
             
                assert_equal '0', cell.value
         | 
| 27 27 | 
             
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              def test_not_empty?
         | 
| 30 | 
            +
                cell = string.new '1', nil, nil, nil, nil
         | 
| 31 | 
            +
                assert_equal false, cell.empty?
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              def test_empty?
         | 
| 35 | 
            +
                cell = string.new '', nil, nil, nil, nil
         | 
| 36 | 
            +
                assert_equal true, cell.empty?
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              def test_presence
         | 
| 40 | 
            +
                cell = string.new '1', nil, nil, nil, nil
         | 
| 41 | 
            +
                assert_equal cell, cell.presence
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              def test_nil_presence
         | 
| 45 | 
            +
                cell = string.new '', nil, nil, nil, nil
         | 
| 46 | 
            +
                assert_nil cell.presence
         | 
| 47 | 
            +
              end
         | 
| 28 48 | 
             
            end
         |