rubyfromexcel 0.0.4

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.
Files changed (188) hide show
  1. data/README +22 -0
  2. data/bin/rubyfromexcel +20 -0
  3. data/examples/create_and_test_examples.rb +37 -0
  4. data/examples/ruby-versions/array-formulas-ruby/sheets/sheet1.rb +59 -0
  5. data/examples/ruby-versions/array-formulas-ruby/sheets/sheet2.rb +9 -0
  6. data/examples/ruby-versions/array-formulas-ruby/specs/sheet1_rspec.rb +156 -0
  7. data/examples/ruby-versions/array-formulas-ruby/specs/sheet2_rspec.rb +8 -0
  8. data/examples/ruby-versions/array-formulas-ruby/spreadsheet.rb +9 -0
  9. data/examples/ruby-versions/complex-test-ruby/sheets/sheet1.rb +305 -0
  10. data/examples/ruby-versions/complex-test-ruby/sheets/sheet2.rb +147 -0
  11. data/examples/ruby-versions/complex-test-ruby/specs/sheet1_rspec.rb +876 -0
  12. data/examples/ruby-versions/complex-test-ruby/specs/sheet2_rspec.rb +412 -0
  13. data/examples/ruby-versions/complex-test-ruby/spreadsheet.rb +9 -0
  14. data/examples/ruby-versions/namedReferenceTest-ruby/sheets/sheet1.rb +9 -0
  15. data/examples/ruby-versions/namedReferenceTest-ruby/sheets/sheet2.rb +8 -0
  16. data/examples/ruby-versions/namedReferenceTest-ruby/specs/sheet1_rspec.rb +16 -0
  17. data/examples/ruby-versions/namedReferenceTest-ruby/specs/sheet2_rspec.rb +16 -0
  18. data/examples/ruby-versions/namedReferenceTest-ruby/spreadsheet.rb +9 -0
  19. data/examples/ruby-versions/pruning-ruby/sheets/sheet1.rb +11 -0
  20. data/examples/ruby-versions/pruning-ruby/sheets/sheet2.rb +14 -0
  21. data/examples/ruby-versions/pruning-ruby/sheets/sheet3.rb +7 -0
  22. data/examples/ruby-versions/pruning-ruby/specs/sheet1_rspec.rb +20 -0
  23. data/examples/ruby-versions/pruning-ruby/specs/sheet2_rspec.rb +20 -0
  24. data/examples/ruby-versions/pruning-ruby/specs/sheet3_rspec.rb +8 -0
  25. data/examples/ruby-versions/pruning-ruby/spreadsheet.rb +9 -0
  26. data/examples/ruby-versions/sharedFormulaTest-ruby/sheets/sheet1.rb +15 -0
  27. data/examples/ruby-versions/sharedFormulaTest-ruby/specs/sheet1_rspec.rb +44 -0
  28. data/examples/ruby-versions/sharedFormulaTest-ruby/spreadsheet.rb +9 -0
  29. data/examples/ruby-versions/table-test-ruby/sheets/sheet1.rb +17 -0
  30. data/examples/ruby-versions/table-test-ruby/sheets/sheet2.rb +5 -0
  31. data/examples/ruby-versions/table-test-ruby/sheets/sheet3.rb +5 -0
  32. data/examples/ruby-versions/table-test-ruby/specs/sheet1_rspec.rb +20 -0
  33. data/examples/ruby-versions/table-test-ruby/specs/sheet2_rspec.rb +8 -0
  34. data/examples/ruby-versions/table-test-ruby/specs/sheet3_rspec.rb +8 -0
  35. data/examples/ruby-versions/table-test-ruby/spreadsheet.rb +9 -0
  36. data/examples/sheets/array-formulas.xlsx +0 -0
  37. data/examples/sheets/complex-test.xlsx +0 -0
  38. data/examples/sheets/namedReferenceTest.xlsx +0 -0
  39. data/examples/sheets/pruning.xlsx +0 -0
  40. data/examples/sheets/sharedFormulaTest.xlsx +0 -0
  41. data/examples/sheets/table-test.xlsx +0 -0
  42. data/examples/sheets/~$array-formulas.xlsx +0 -0
  43. data/examples/unzipped-sheets/array-formulas/[Content_Types].xml +2 -0
  44. data/examples/unzipped-sheets/array-formulas/docProps/app.xml +2 -0
  45. data/examples/unzipped-sheets/array-formulas/docProps/core.xml +2 -0
  46. data/examples/unzipped-sheets/array-formulas/docProps/thumbnail.jpeg +0 -0
  47. data/examples/unzipped-sheets/array-formulas/xl/_rels/workbook.xml.rels +2 -0
  48. data/examples/unzipped-sheets/array-formulas/xl/calcChain.xml +2 -0
  49. data/examples/unzipped-sheets/array-formulas/xl/sharedStrings.xml +2 -0
  50. data/examples/unzipped-sheets/array-formulas/xl/styles.xml +2 -0
  51. data/examples/unzipped-sheets/array-formulas/xl/theme/theme1.xml +2 -0
  52. data/examples/unzipped-sheets/array-formulas/xl/workbook.xml +2 -0
  53. data/examples/unzipped-sheets/array-formulas/xl/worksheets/sheet1.xml +2 -0
  54. data/examples/unzipped-sheets/array-formulas/xl/worksheets/sheet2.xml +2 -0
  55. data/examples/unzipped-sheets/complex-test/[Content_Types].xml +2 -0
  56. data/examples/unzipped-sheets/complex-test/docProps/app.xml +2 -0
  57. data/examples/unzipped-sheets/complex-test/docProps/core.xml +2 -0
  58. data/examples/unzipped-sheets/complex-test/xl/_rels/workbook.xml.rels +2 -0
  59. data/examples/unzipped-sheets/complex-test/xl/calcChain.xml +2 -0
  60. data/examples/unzipped-sheets/complex-test/xl/charts/chart1.xml +2 -0
  61. data/examples/unzipped-sheets/complex-test/xl/charts/chart2.xml +2 -0
  62. data/examples/unzipped-sheets/complex-test/xl/comments1.xml +5 -0
  63. data/examples/unzipped-sheets/complex-test/xl/comments2.xml +5 -0
  64. data/examples/unzipped-sheets/complex-test/xl/drawings/_rels/drawing1.xml.rels +2 -0
  65. data/examples/unzipped-sheets/complex-test/xl/drawings/_rels/drawing2.xml.rels +2 -0
  66. data/examples/unzipped-sheets/complex-test/xl/drawings/drawing1.xml +2 -0
  67. data/examples/unzipped-sheets/complex-test/xl/drawings/drawing2.xml +2 -0
  68. data/examples/unzipped-sheets/complex-test/xl/drawings/vmlDrawing1.vml +46 -0
  69. data/examples/unzipped-sheets/complex-test/xl/drawings/vmlDrawing2.vml +46 -0
  70. data/examples/unzipped-sheets/complex-test/xl/sharedStrings.xml +2 -0
  71. data/examples/unzipped-sheets/complex-test/xl/styles.xml +2 -0
  72. data/examples/unzipped-sheets/complex-test/xl/theme/theme1.xml +2 -0
  73. data/examples/unzipped-sheets/complex-test/xl/workbook.xml +2 -0
  74. data/examples/unzipped-sheets/complex-test/xl/worksheets/_rels/sheet1.xml.rels +2 -0
  75. data/examples/unzipped-sheets/complex-test/xl/worksheets/_rels/sheet2.xml.rels +2 -0
  76. data/examples/unzipped-sheets/complex-test/xl/worksheets/sheet1.xml +2 -0
  77. data/examples/unzipped-sheets/complex-test/xl/worksheets/sheet2.xml +2 -0
  78. data/examples/unzipped-sheets/namedReferenceTest/[Content_Types].xml +2 -0
  79. data/examples/unzipped-sheets/namedReferenceTest/docProps/app.xml +2 -0
  80. data/examples/unzipped-sheets/namedReferenceTest/docProps/core.xml +2 -0
  81. data/examples/unzipped-sheets/namedReferenceTest/docProps/thumbnail.jpeg +0 -0
  82. data/examples/unzipped-sheets/namedReferenceTest/xl/_rels/workbook.xml.rels +2 -0
  83. data/examples/unzipped-sheets/namedReferenceTest/xl/calcChain.xml +2 -0
  84. data/examples/unzipped-sheets/namedReferenceTest/xl/styles.xml +2 -0
  85. data/examples/unzipped-sheets/namedReferenceTest/xl/theme/theme1.xml +2 -0
  86. data/examples/unzipped-sheets/namedReferenceTest/xl/workbook.xml +2 -0
  87. data/examples/unzipped-sheets/namedReferenceTest/xl/worksheets/sheet1.xml +2 -0
  88. data/examples/unzipped-sheets/namedReferenceTest/xl/worksheets/sheet2.xml +2 -0
  89. data/examples/unzipped-sheets/pruning/[Content_Types].xml +2 -0
  90. data/examples/unzipped-sheets/pruning/docProps/app.xml +2 -0
  91. data/examples/unzipped-sheets/pruning/docProps/core.xml +2 -0
  92. data/examples/unzipped-sheets/pruning/docProps/thumbnail.jpeg +0 -0
  93. data/examples/unzipped-sheets/pruning/xl/_rels/workbook.xml.rels +2 -0
  94. data/examples/unzipped-sheets/pruning/xl/calcChain.xml +2 -0
  95. data/examples/unzipped-sheets/pruning/xl/sharedStrings.xml +2 -0
  96. data/examples/unzipped-sheets/pruning/xl/styles.xml +2 -0
  97. data/examples/unzipped-sheets/pruning/xl/theme/theme1.xml +2 -0
  98. data/examples/unzipped-sheets/pruning/xl/workbook.xml +2 -0
  99. data/examples/unzipped-sheets/pruning/xl/worksheets/sheet1.xml +2 -0
  100. data/examples/unzipped-sheets/pruning/xl/worksheets/sheet2.xml +2 -0
  101. data/examples/unzipped-sheets/pruning/xl/worksheets/sheet3.xml +2 -0
  102. data/examples/unzipped-sheets/sharedFormulaTest/[Content_Types].xml +2 -0
  103. data/examples/unzipped-sheets/sharedFormulaTest/docProps/app.xml +2 -0
  104. data/examples/unzipped-sheets/sharedFormulaTest/docProps/core.xml +2 -0
  105. data/examples/unzipped-sheets/sharedFormulaTest/docProps/thumbnail.jpeg +0 -0
  106. data/examples/unzipped-sheets/sharedFormulaTest/xl/_rels/workbook.xml.rels +2 -0
  107. data/examples/unzipped-sheets/sharedFormulaTest/xl/calcChain.xml +2 -0
  108. data/examples/unzipped-sheets/sharedFormulaTest/xl/styles.xml +2 -0
  109. data/examples/unzipped-sheets/sharedFormulaTest/xl/theme/theme1.xml +2 -0
  110. data/examples/unzipped-sheets/sharedFormulaTest/xl/workbook.xml +2 -0
  111. data/examples/unzipped-sheets/sharedFormulaTest/xl/worksheets/sheet1.xml +2 -0
  112. data/examples/unzipped-sheets/table-test/[Content_Types].xml +2 -0
  113. data/examples/unzipped-sheets/table-test/docProps/app.xml +2 -0
  114. data/examples/unzipped-sheets/table-test/docProps/core.xml +2 -0
  115. data/examples/unzipped-sheets/table-test/xl/_rels/workbook.xml.rels +2 -0
  116. data/examples/unzipped-sheets/table-test/xl/calcChain.xml +2 -0
  117. data/examples/unzipped-sheets/table-test/xl/printerSettings/printerSettings1.bin +0 -0
  118. data/examples/unzipped-sheets/table-test/xl/sharedStrings.xml +2 -0
  119. data/examples/unzipped-sheets/table-test/xl/styles.xml +2 -0
  120. data/examples/unzipped-sheets/table-test/xl/tables/table1.xml +2 -0
  121. data/examples/unzipped-sheets/table-test/xl/theme/theme1.xml +2 -0
  122. data/examples/unzipped-sheets/table-test/xl/workbook.xml +2 -0
  123. data/examples/unzipped-sheets/table-test/xl/worksheets/_rels/sheet1.xml.rels +2 -0
  124. data/examples/unzipped-sheets/table-test/xl/worksheets/sheet1.xml +2 -0
  125. data/examples/unzipped-sheets/table-test/xl/worksheets/sheet2.xml +2 -0
  126. data/examples/unzipped-sheets/table-test/xl/worksheets/sheet3.xml +2 -0
  127. data/lib/cells/array/array_formula_builder.rb +58 -0
  128. data/lib/cells/array/array_formula_cell.rb +27 -0
  129. data/lib/cells/array/arraying_formula_cell.rb +67 -0
  130. data/lib/cells/array/single_cell_array_formula_builder.rb +9 -0
  131. data/lib/cells/array/single_cell_array_formula_cell.rb +11 -0
  132. data/lib/cells/cell.rb +98 -0
  133. data/lib/cells/cells.rb +9 -0
  134. data/lib/cells/formula/formula_cell.rb +18 -0
  135. data/lib/cells/formula/simple_formula_cell.rb +4 -0
  136. data/lib/cells/shared/shared_formula_builder.rb +15 -0
  137. data/lib/cells/shared/shared_formula_cell.rb +20 -0
  138. data/lib/cells/shared/sharing_formula_cell.rb +36 -0
  139. data/lib/cells/value/value_cell.rb +24 -0
  140. data/lib/excelfile/excelfile.rb +6 -0
  141. data/lib/excelfile/relationships.rb +24 -0
  142. data/lib/excelfile/shared_strings.rb +21 -0
  143. data/lib/excelfile/sheet_names.rb +6 -0
  144. data/lib/excelfile/table.rb +116 -0
  145. data/lib/excelfile/workbook.rb +108 -0
  146. data/lib/excelfile/worksheet.rb +122 -0
  147. data/lib/formulae/compile/formula_builder.rb +316 -0
  148. data/lib/formulae/formulae.rb +6 -0
  149. data/lib/formulae/parse/formula_peg.rb +213 -0
  150. data/lib/formulae/parse/formula_peg.txt +40 -0
  151. data/lib/formulae/run/excel_functions.rb +375 -0
  152. data/lib/formulae/run/excel_matrix.rb +114 -0
  153. data/lib/formulae/run/excel_range.rb +256 -0
  154. data/lib/formulae/run/reference.rb +79 -0
  155. data/lib/optimiser/dependency_builder.rb +86 -0
  156. data/lib/optimiser/optimiser.rb +3 -0
  157. data/lib/optimiser/shared_formula_dependency_builder.rb +43 -0
  158. data/lib/optimiser/workbook_pruner.rb +80 -0
  159. data/lib/rubyfromexcel.rb +105 -0
  160. data/lib/runtime/runtime_formula_builder.rb +32 -0
  161. data/spec/array_formula_builder_spec.rb +35 -0
  162. data/spec/array_formula_cell_spec.rb +17 -0
  163. data/spec/arraying_formula_cell_spec.rb +38 -0
  164. data/spec/dependency_builder_spec.rb +71 -0
  165. data/spec/excel_functions_spec.rb +381 -0
  166. data/spec/excel_matrix_spec.rb +92 -0
  167. data/spec/excel_range_spec.rb +161 -0
  168. data/spec/formula_builder_spec.rb +230 -0
  169. data/spec/formula_peg_spec.rb +165 -0
  170. data/spec/reference_spec.rb +72 -0
  171. data/spec/relationships_spec.rb +51 -0
  172. data/spec/runtime_formula_builder_spec.rb +55 -0
  173. data/spec/shared_formula_builder_spec.rb +29 -0
  174. data/spec/shared_formula_cell_spec.rb +23 -0
  175. data/spec/shared_formula_dependency_builder_spec.rb +48 -0
  176. data/spec/shared_strings_spec.rb +14 -0
  177. data/spec/sharing_formula_cell_spec.rb +79 -0
  178. data/spec/simple_formula_cell_spec.rb +78 -0
  179. data/spec/single_cell_array_formula_builder_spec.rb +19 -0
  180. data/spec/single_cell_array_formula_cell_spec.rb +25 -0
  181. data/spec/spec_helper.rb +2 -0
  182. data/spec/table_spec.rb +100 -0
  183. data/spec/value_cell_spec.rb +49 -0
  184. data/spec/workbook_pruner_spec.rb +27 -0
  185. data/spec/workbook_spec.rb +283 -0
  186. data/spec/worksheet_failiures_spec.rb +41 -0
  187. data/spec/worksheet_spec.rb +486 -0
  188. metadata +291 -0
@@ -0,0 +1,72 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe Reference do
4
+ it "converts excel A1 style references to ruby method calls" do
5
+ Reference.new("A1").to_ruby.should == "a1"
6
+ Reference.new("$AA$103").to_ruby.should == "aa103"
7
+ Reference.new("ZZ1").to_ruby.should == "zz1"
8
+ end
9
+
10
+ it "offsets references if required, dealing with any absolute constraints" do
11
+ Reference.new("A1").shift!([1,1]).to_ruby.should == "b2"
12
+ Reference.new("A$1").shift!([1,1]).to_ruby.should == "b1"
13
+ Reference.new("$A1").shift!([1,1]).to_ruby.should == "a2"
14
+ Reference.new("$A$1").shift!([1,1]).to_ruby.should == "a1"
15
+ end
16
+
17
+ it "manages wrap on column numbering when offsetting" do
18
+ Reference.new("Z1").shift!([1,1]).to_ruby.should == "aa2"
19
+ Reference.new("ZZ1").shift!([1,1]).to_ruby.should == "aaa2"
20
+ end
21
+
22
+ it "deals with a nil value as an offset, treating it as offset [0,0]" do
23
+ Reference.new("A1").shift!(nil).to_ruby.should == "a1"
24
+ end
25
+
26
+ it "converts columns to integers" do
27
+ Reference.column_to_integer("A").should == 1
28
+ Reference.column_to_integer("B").should == 2
29
+ Reference.column_to_integer("Z").should == 26
30
+ Reference.column_to_integer("AA").should == 27
31
+ Reference.column_to_integer("AB").should == 28
32
+ end
33
+
34
+ it "converts integers to columns" do
35
+ Reference.integer_to_column(1).should == "a"
36
+ Reference.integer_to_column(2).should == "b"
37
+ Reference.integer_to_column(26).should == "z"
38
+ Reference.integer_to_column(27).should == "aa"
39
+ Reference.integer_to_column(28).should == "ab"
40
+ end
41
+
42
+ it "raises an exception if asked for a column number < 1 (Excel column numbering starts at 1)" do
43
+ lambda { Reference.integer_to_column(0) }.should raise_error(Exception)
44
+ end
45
+
46
+ it "can return the column_number and row_number for a reference" do
47
+ Reference.new("AB1").column_number.should == 28
48
+ Reference.new("AB1").row_number.should == 1
49
+ end
50
+
51
+ it "converts column and row numbers into ruby versions of cell references" do
52
+ Reference.ruby_for(28,1).should == "ab1"
53
+ Reference.ruby_for(16384,16384).should == "xfd16384"
54
+ Reference.ruby_for(26,10).should == "z10"
55
+ Reference.ruby_for(701,10).should == "zy10"
56
+ Reference.ruby_for(702,10).should == "zz10"
57
+ Reference.ruby_for(703,10).should == "aaa10"
58
+ Reference.ruby_for(704,10).should == "aab10"
59
+ Reference.ruby_for(1378,10).should == "azz10"
60
+ Reference.ruby_for(2054,10).should == "bzz10"
61
+ end
62
+
63
+ it "returns its value as a ruby_method style reference when to_s is called" do
64
+ Reference.new("$AB$1").to_s.should == "ab1"
65
+ end
66
+
67
+ it "returns an array with [row_offset,column_offset] when subtracted from another reference" do
68
+ (Reference.new("A1") - Reference.new("A1")).should == [0,0]
69
+ (Reference.new("B2") - Reference.new("A1")).should == [1,1]
70
+ (Reference.new("AA10") - Reference.new("Z9")).should == [1,1]
71
+ end
72
+ end
@@ -0,0 +1,51 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe Relationships do
4
+
5
+ relationship_xml =<<END
6
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
7
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
8
+ <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet3.xml"/>
9
+ <Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/calcChain" Target="calcChain.xml"/>
10
+ <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet2.xml"/>
11
+ <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>
12
+ <Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>
13
+ <Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
14
+ <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>
15
+ </Relationships>
16
+ END
17
+
18
+ it "it should be created from xml be equivalent to a Hash where the keys are the relationship ids and the values are the target files" do
19
+ wr = Relationships.new(Nokogiri::XML(relationship_xml).root)
20
+ wr['rId3'].should == 'worksheets/sheet3.xml'
21
+ end
22
+
23
+ it "when given a root_directory will prepend that to the target files" do
24
+ wr = Relationships.new(Nokogiri::XML(relationship_xml).root, root_directory = '/usr/local')
25
+ wr['rId3'].should == '/usr/local/worksheets/sheet3.xml'
26
+ end
27
+
28
+ it "should have a Relationships.for_file(path_to_workkbook) that loads the xml automatically" do
29
+ File.should_receive(:open).with('/usr/local/excel_dir/xl/_rels/workbook.xml.rels').and_yield(StringIO.new(relationship_xml))
30
+ File.should_receive(:exist?).with('/usr/local/excel_dir/xl/_rels/workbook.xml.rels').and_return(true)
31
+
32
+ wr = Relationships.for_file('/usr/local/excel_dir/xl/workbook.xml')
33
+ wr['rId3'].should == '/usr/local/excel_dir/xl/worksheets/sheet3.xml'
34
+
35
+ File.should_receive(:open).with('/usr/local/excel_dir/xl/worksheets/_rels/sheet1.xml.rels').and_yield(StringIO.new(relationship_xml))
36
+ File.should_receive(:exist?).with('/usr/local/excel_dir/xl/worksheets/_rels/sheet1.xml.rels').and_return(true)
37
+ wr = Relationships.for_file('/usr/local/excel_dir/xl/worksheets/sheet1.xml')
38
+ wr['rId3'].should == '/usr/local/excel_dir/xl/worksheets/worksheets/sheet3.xml'
39
+
40
+ end
41
+
42
+ it "should return an empty Relationships if relationships xml file doesn't exist" do
43
+ wr = Relationships.for_file('missing_file')
44
+ wr.size.should == 0
45
+ end
46
+
47
+ it "should pick out the sharedStrings relationship and put in an accessor" do
48
+ wr = Relationships.new(Nokogiri::XML(relationship_xml).root)
49
+ wr.shared_strings.should == 'sharedStrings.xml'
50
+ end
51
+ end
@@ -0,0 +1,55 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe RuntimeFormulaBuilder, "For parsing indirect references" do
4
+
5
+ before(:each) do
6
+ @worksheet = mock(:worksheet)
7
+ @builder = RuntimeFormulaBuilder.new(@worksheet)
8
+ end
9
+
10
+ def ruby_for(formula)
11
+ ast = Formula.parse(formula)
12
+ ast.visit(@builder)
13
+ end
14
+ # These are the new conversions
15
+ it "should convert sheet names to ruby methods" do
16
+ ruby_for("asheetname!A3:B20").should == "s('asheetname').a('a3','b20')"
17
+ ruby_for("'a long sheet name with spaces'!A3:B20").should == "s('a long sheet name with spaces').a('a3','b20')"
18
+ end
19
+
20
+ it "should convert table names to references" do
21
+ table = mock(:table)
22
+ table.should_receive('reference_for').with('[#totals],[Description]',nil).and_return("cell reference")
23
+ @worksheet.should_receive('t').with('Vectors').and_return(table)
24
+ ruby_for("Vectors[[#totals],[Description]]").should == "cell reference"
25
+ end
26
+
27
+ # All these are the standard conversions
28
+ it "Should convert simple references to ruby method calls" do
29
+ ruby_for("AA1").should == "aa1"
30
+ ruby_for("$AA$100").should == "aa100"
31
+ ruby_for("A$1").should == "a1"
32
+ ruby_for("$A1").should == "a1"
33
+ ruby_for("I9+J9+K9+P9+Q9").should == "i9+j9+k9+p9+q9"
34
+ end
35
+
36
+ it "Should convert area references to a(start,end) functions" do
37
+ ruby_for('$A$1:BZ$2000').should == "a('a1','bz2000')"
38
+ end
39
+
40
+ it "Should convert column references to c(start,end) functions" do
41
+ ruby_for('A:ZZ').should == "c('a','zz')"
42
+ end
43
+
44
+ it "should convert row references to r(start,end) functions" do
45
+ ruby_for('1:1000').should == 'r(1,1000)'
46
+ end
47
+
48
+ it "should convert named references to ruby methods" do
49
+ ruby_for("SUM(OneAnd2)").should == "sum(one_and2)"
50
+ ruby_for("ReferenceOne").should == "reference_one"
51
+ ruby_for("Reference.2").should == "reference_2"
52
+ ruby_for("-($AG70+$X70)*EF.NaturalGas.N2O").should == "-(ag70+x70)*ef_natural_gas_n2o"
53
+ end
54
+
55
+ end
@@ -0,0 +1,29 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe SharedFormulaBuilder, "Formulas with shared_formula_offsets" do
4
+
5
+ before(:each) do
6
+ @builder = SharedFormulaBuilder.new
7
+ @builder.shared_formula_offset = [1,1]
8
+ end
9
+
10
+ def ruby_for(formula)
11
+ ast = Formula.parse(formula)
12
+ ast.visit(@builder)
13
+ end
14
+
15
+ it "should move individual references appropriately" do
16
+ ruby_for("A1").should == "b2"
17
+ ruby_for("A$1").should == "b1"
18
+ ruby_for("$A1").should == "a2"
19
+ ruby_for("$A$1").should == "a1"
20
+ end
21
+
22
+ it "should move several references in the same formula" do
23
+ ruby_for("A1+B2").should == "b2+c3"
24
+ ruby_for("A$1+B$1").should == "b1+c1"
25
+ ruby_for("$A1+$B1").should == "a2+b2"
26
+ ruby_for("$A$1+$B$1").should == "a1+b1"
27
+ end
28
+
29
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe SharedFormulaCell do
4
+
5
+ before do
6
+ @cell = SharedFormulaCell.new(
7
+ mock(:worksheet,:class_name => 'Sheet1', :to_s => 'sheet1'),
8
+ Nokogiri::XML('<c r="W8" s="49"><f t="shared" si="2"/><v>1</v></c>').root
9
+ )
10
+ @cell.shared_formula = Formula.parse("$A$1+B2")
11
+ @cell.shared_formula_offset = [1,1]
12
+ end
13
+
14
+ it "it is given a pre-parsed formula and offsets its references by the amount of its shared_formula_offset" do
15
+ @cell.to_ruby.should == "def w8; @w8 ||= a1+c3; end\n"
16
+ @cell.to_test.should == "it 'cell w8 should equal 1.0' do\n sheet1.w8.should be_close(1.0,0.1)\nend\n\n"
17
+ end
18
+
19
+ it "knows what it depends on" do
20
+ @cell.work_out_dependencies
21
+ @cell.dependencies.should == ['sheet1.a1','sheet1.c3']
22
+ end
23
+ end
@@ -0,0 +1,48 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe SharedFormulaDependencyBuilder do
4
+
5
+ before(:each) do
6
+ SheetNames.instance.clear
7
+ SheetNames.instance['Other Sheet'] = 'sheet2'
8
+ @workbook = mock(:workbook, :named_references => {'named_cell' => 'sheet2.z10', 'named_cell2' => "sheet2.a('z10','ab10')"})
9
+ @worksheet1 = mock(:worksheet, :to_s => 'sheet1', :workbook => @workbook, :named_references => {'named_cell' => 'sheet1.a1'})
10
+ @worksheet2 = mock(:worksheet, :to_s => 'sheet2', :workbook => @workbook, :named_references => {})
11
+ @workbook.stub!(:worksheets => {'sheet1' => @worksheet1, 'sheet2' => @worksheet2 })
12
+ @cell = mock(:cell,:worksheet => @worksheet1, :reference => Reference.new('c30',@worksheet1))
13
+ @builder = SharedFormulaDependencyBuilder.new(@cell)
14
+ @builder.shared_formula_offset = [1,1]
15
+ end
16
+
17
+ def ruby_for(formula)
18
+ ast = Formula.parse(formula)
19
+ ast.visit(@builder)
20
+ end
21
+
22
+ it "should offset single cell dependencies appropriately" do
23
+ ruby_for("A1").should == ['sheet1.b2']
24
+ ruby_for("$A1").should == ['sheet1.a2']
25
+ ruby_for("A$1").should == ['sheet1.b1']
26
+ ruby_for("$A$1").should == ['sheet1.a1']
27
+ end
28
+
29
+ it "should offset dependences on other worksheets" do
30
+ ruby_for("A1+'Other Sheet'!A1").should == ['sheet1.b2','sheet2.b2']
31
+ end
32
+
33
+ it "should offset dependences in ranges" do
34
+ ruby_for("A1:A3").should == ['sheet1.b2','sheet1.b3','sheet1.b4']
35
+ end
36
+
37
+ it "should not offset dependencies in named_cells" do
38
+ ruby_for("named_cell").should == ['sheet1.a1']
39
+ end
40
+
41
+ it "should not offset dependencies created by table references" do
42
+ Table.new(@worksheet2,'Vectors','a1:b2',['ColA','Description'],1)
43
+ ruby_for("Vectors[#all]").should == ["sheet2.a1","sheet2.a2",'sheet2.b1','sheet2.b2']
44
+ Table.new(@worksheet1,'Vectors','a1:d41',['ColA','Description','ColC'],1)
45
+ ruby_for("[Description]").should == ["sheet1.b30"]
46
+ end
47
+
48
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe SharedStrings do
4
+
5
+ it "should return a shared string when provided with an index" do
6
+ xml = Nokogiri::XML('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
7
+ <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="2" uniqueCount="2"><si><t>This a second shared string</t><phoneticPr fontId="3" type="noConversion"/></si><si><r><t>This is, h</t></r><r><rPr><b/><sz val="10"/><rFont val="Verdana"/></rPr><t>opefully, the first</t></r><r><rPr><sz val="10"/><rFont val="Verdana"/></rPr><t xml:space="preserve"> shared string</t></r><phoneticPr fontId="3" type="noConversion"/></si></sst>')
8
+ shared_strings = SharedStrings.instance
9
+ shared_strings.clear
10
+ shared_strings.load_strings_from_xml xml
11
+ SharedStrings.shared_string_for(0).should == "This a second shared string"
12
+ SharedStrings.shared_string_for(1).should == "This is, hopefully, the first shared string"
13
+ end
14
+ end
@@ -0,0 +1,79 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe SharingFormulaCell do
4
+ it "it is given a pre-parsed formula and offsets its references by the amount of its shared_formula_offset" do
5
+ worksheet = mock(:worksheet,:class_name => 'Sheet1',:to_s => 'sheet1')
6
+ sharing_cell = SharingFormulaCell.new(
7
+ worksheet,
8
+ Nokogiri::XML('<c r="W7" s="49"><f t="shared" ref="W7:W8" si="2">A1+B2</f><v>1</v></c>').root
9
+ )
10
+ shared_cell = SharedFormulaCell.new(
11
+ worksheet,
12
+ Nokogiri::XML('<c r="W8" s="49"><f t="shared" si="2"></f><v>2</v></c>').root
13
+ )
14
+ worksheet.should_receive(:cell).with('w8').and_return(shared_cell)
15
+
16
+ sharing_cell.alter_other_cells_if_required
17
+ sharing_cell.to_ruby.should == "def w7; @w7 ||= a1+b2; end\n"
18
+ shared_cell.to_ruby.should == "def w8; @w8 ||= a2+b3; end\n"
19
+ end
20
+
21
+ it "knows what it depends upon" do
22
+ worksheet = mock(:worksheet,:class_name => 'Sheet1',:to_s => 'sheet1')
23
+ sharing_cell = SharingFormulaCell.new(
24
+ worksheet,
25
+ Nokogiri::XML('<c r="W7" s="49"><f t="shared" ref="W7:W8" si="2">A1+B2</f><v>1</v></c>').root
26
+ )
27
+ shared_cell = SharedFormulaCell.new(
28
+ worksheet,
29
+ Nokogiri::XML('<c r="W8" s="49"><f t="shared" si="2"></f><v>2</v></c>').root
30
+ )
31
+ worksheet.should_receive(:cell).with('w8').and_return(shared_cell)
32
+
33
+ sharing_cell.alter_other_cells_if_required
34
+ sharing_cell.work_out_dependencies
35
+ shared_cell.work_out_dependencies
36
+ sharing_cell.dependencies.should == ['sheet1.a1','sheet1.b2']
37
+ shared_cell.dependencies.should == ['sheet1.a2','sheet1.b3']
38
+ end
39
+
40
+ it "it should cope if it is sharing only with itself" do
41
+ worksheet = mock(:worksheet,:class_name => 'Sheet1')
42
+ sharing_cell = SharingFormulaCell.new(
43
+ worksheet,
44
+ Nokogiri::XML('<c r="W7" s="49"><f t="shared" ref="W7" si="2">A1+B2</f><v>1</v></c>').root
45
+ )
46
+
47
+ sharing_cell.alter_other_cells_if_required
48
+ sharing_cell.to_ruby.should == "def w7; @w7 ||= a1+b2; end\n"
49
+ end
50
+
51
+ it "it should cope if it is sharing to a formula that doesn't exist" do
52
+ worksheet = mock(:worksheet,:class_name => 'Sheet1')
53
+ sharing_cell = SharingFormulaCell.new(
54
+ worksheet,
55
+ Nokogiri::XML('<c r="W7" s="49"><f t="shared" ref="W7:W8" si="2">A1+B2</f><v>1</v></c>').root
56
+ )
57
+ worksheet.should_receive(:cell).with('w8').and_return(nil)
58
+
59
+ sharing_cell.alter_other_cells_if_required
60
+ sharing_cell.to_ruby.should == "def w7; @w7 ||= a1+b2; end\n"
61
+ end
62
+
63
+ it "it should cope if it is sharing with a cell that has its own formula" do
64
+ worksheet = mock(:worksheet,:class_name => 'Sheet1')
65
+ sharing_cell = SharingFormulaCell.new(
66
+ worksheet,
67
+ Nokogiri::XML('<c r="W7" s="49"><f t="shared" ref="W7:W8" si="2">A1+B2</f><v>1</v></c>').root
68
+ )
69
+ shared_cell = SimpleFormulaCell.new(
70
+ worksheet,
71
+ Nokogiri::XML('<c r="W8" s="49"><f>AND(1,2)</f><v>1</v></c>').root
72
+ )
73
+ worksheet.should_receive(:cell).with('w8').and_return(shared_cell)
74
+
75
+ sharing_cell.alter_other_cells_if_required
76
+ sharing_cell.to_ruby.should == "def w7; @w7 ||= a1+b2; end\n"
77
+ shared_cell.to_ruby.should == "def w8; @w8 ||= excel_and(1.0,2.0); end\n"
78
+ end
79
+ end
@@ -0,0 +1,78 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe SimpleFormulaCell, "when result is a number" do
4
+
5
+ before do
6
+ @cell = SimpleFormulaCell.new(
7
+ mock(:worksheet,:class_name => 'Sheet1', :to_s => 'sheet1'),
8
+ Nokogiri::XML("<c r=\"C3\"><f>1+2</f><v>3</v></c>").root
9
+ )
10
+ end
11
+
12
+ it "should use the FormulaPeg to create ruby code for a formula and turn that into a method" do
13
+ @cell.to_ruby.should == "def c3; @c3 ||= 1.0+2.0; end\n"
14
+ end
15
+
16
+ it "should create a test for the ruby code" do
17
+ @cell.to_test.should == %Q{it 'cell c3 should equal 3.0' do\n sheet1.c3.should be_close(3.0,0.3)\nend\n\n}
18
+ end
19
+
20
+ it "has a method that says it cannot be replaced with its value" do
21
+ @cell.can_be_replaced_with_value?.should be_false
22
+ end
23
+
24
+ end
25
+
26
+ describe SimpleFormulaCell, "when result is a boolean" do
27
+
28
+ before do
29
+ @cell = SimpleFormulaCell.new(
30
+ mock(:worksheet,:class_name => 'Sheet1', :to_s => 'sheet1'),
31
+ Nokogiri::XML('<c r="C3" t="b"><f>AND(1,2)</f><v>TRUE</v></c>').root
32
+ )
33
+ end
34
+
35
+ it "should use the FormulaPeg to create ruby code for a formula and turn that into a method" do
36
+ @cell.to_ruby.should == "def c3; @c3 ||= excel_and(1.0,2.0); end\n"
37
+ end
38
+
39
+ it "should create a test for the ruby code" do
40
+ @cell.to_test.should == %Q{it 'cell c3 should equal true' do\n sheet1.c3.should == true\nend\n\n}
41
+ end
42
+
43
+ end
44
+
45
+ describe SimpleFormulaCell, "when result is a string" do
46
+
47
+ before do
48
+ @cell = SimpleFormulaCell.new(
49
+ mock(:worksheet,:class_name => 'Sheet1', :to_s => 'sheet1'),
50
+ Nokogiri::XML('<c r="C3" t="str"><f>"Hello "&amp;A1</f><v>Hello Bob</v></c>').root
51
+ )
52
+ end
53
+
54
+ it "should use the FormulaPeg to create ruby code for a formula and turn that into a method" do
55
+ @cell.to_ruby.should == %Q{def c3; @c3 ||= "Hello "+a1.to_s; end\n}
56
+ end
57
+
58
+ it "should create a test for the ruby code" do
59
+ @cell.to_test.should == %Q{it 'cell c3 should equal "Hello Bob"' do\n sheet1.c3.should == "Hello Bob"\nend\n\n}
60
+ end
61
+
62
+ end
63
+
64
+ describe SimpleFormulaCell, "can list the cells upon which it depends" do
65
+
66
+ before do
67
+ @cell = SimpleFormulaCell.new(
68
+ mock(:worksheet,:class_name => 'Sheet1', :to_s => 'sheet1'),
69
+ Nokogiri::XML("<c r=\"C3\" t=\"str\"><f>A1</f><v>Hello Bob</v></c>").root
70
+ )
71
+ end
72
+
73
+ it "in simple cases knows what it depends upon" do
74
+ @cell.work_out_dependencies
75
+ @cell.dependencies.should == ['sheet1.a1']
76
+ end
77
+
78
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe SingleCellArrayFormulaBuilder, "Single cell array formulas" do
4
+
5
+ before(:each) do
6
+ @builder = SingleCellArrayFormulaBuilder.new
7
+ end
8
+
9
+ def ruby_for(formula)
10
+ ast = Formula.parse(formula)
11
+ ast.visit(@builder)
12
+ end
13
+
14
+ it "should wrap operations in an array_operation(left,operation,right) methods" do
15
+ ruby_for("SUM(F$437:F$449/$M$150:$M$162*($B454=$F$149:$N$149)*($F$150:$N$162))").should == "sum(m(a('f437','f449'),a('m150','m162'),(m(b454,a('f149','n149')) { |r1,r2| r1==r2 }),(a('f150','n162'))) { |r1,r2,r3,r4| r1/r2*r3*r4 })"
16
+ end
17
+
18
+
19
+ end
@@ -0,0 +1,25 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe SingleCellArrayFormulaCell do
4
+
5
+ before do
6
+ @cell = SingleCellArrayFormulaCell.new(
7
+ mock(:worksheet,:class_name => 'Sheet1', :to_s => 'sheet1'),
8
+ Nokogiri::XML("<c r=\"C3\"><f t=\"array\" ref=\"C3\">SUM(F$437:F$449/$M$150:$M$162*($B454=$F$149:$N$149)*($F$150:$N$162))</f><v>3</v></c>").root
9
+ )
10
+ end
11
+
12
+ it "should use the FormulaPeg to create ruby code for a formula and turn that into a method" do
13
+ @cell.to_ruby.should == "def c3; @c3 ||= sum(m(a('f437','f449'),a('m150','m162'),(m(b454,a('f149','n149')) { |r1,r2| r1==r2 }),(a('f150','n162'))) { |r1,r2,r3,r4| r1/r2*r3*r4 }); end\n"
14
+ end
15
+
16
+ it "should create a test for the ruby code" do
17
+ @cell.to_test.should == %Q{it 'cell c3 should equal 3.0' do\n sheet1.c3.should be_close(3.0,0.3)\nend\n\n}
18
+ end
19
+
20
+ it "in can list the cells upon which it depends" do
21
+ @cell.work_out_dependencies
22
+ dependencies = @cell.dependencies
23
+ dependencies.include?('sheet1.g151').should be_true
24
+ end
25
+ end
@@ -0,0 +1,2 @@
1
+ require_relative '../lib/rubyfromexcel'
2
+ include RubyFromExcel
@@ -0,0 +1,100 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe Table do
4
+
5
+ def table
6
+ table_xml =<<-END
7
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
8
+ <table xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" id="1" name="FirstTable" displayName="FirstTable" ref="B3:D7" totalsRowCount="1">
9
+ <autoFilter ref="B3:D6"/>
10
+ <tableColumns count="3">
11
+ <tableColumn id="1" name="ColA" totalsRowLabel="Total"/>
12
+ <tableColumn id="2" name="ColB" totalsRowFunction="custom" dataDxfId="1">
13
+ <calculatedColumnFormula>FirstTable[[#This Row],[ColA]]+FirstTable[[#This Row],[ColC]]</calculatedColumnFormula>
14
+ <totalsRowFormula>AVERAGE(FirstTable[ColB])</totalsRowFormula>
15
+ </tableColumn>
16
+ <tableColumn id="3" name="ColC" totalsRowFunction="count" dataDxfId="0">
17
+ <calculatedColumnFormula>3*FirstTable[[#This Row],[ColA]]</calculatedColumnFormula>
18
+ </tableColumn>
19
+ </tableColumns>
20
+ <tableStyleInfo name="TableStyleLight16" showFirstColumn="1" showLastColumn="1" showRowStripes="1" showColumnStripes="1"/>
21
+ </table>
22
+ END
23
+ @worksheet ||= mock(:worksheet,:to_s => 'sheet1')
24
+ @table ||= Table.from_xml(@worksheet, Nokogiri::XML(table_xml).root)
25
+ end
26
+
27
+ it "should know its name" do
28
+ table.name.should == 'FirstTable'
29
+ end
30
+
31
+ it "should know the area (returned in #all) that it covers" do
32
+ table.all.start_cell.to_s.should == 'b3'
33
+ table.all.end_cell.to_s.should == 'd7'
34
+ end
35
+
36
+ it "should know the area (returned in #data) covered by its data" do
37
+ table.data.start_cell.to_s.should == 'b4'
38
+ table.data.end_cell.to_s.should == 'd6'
39
+ end
40
+
41
+ it "should know the area covered by its headers" do
42
+ table.headers.start_cell.to_s.should == 'b3'
43
+ table.headers.end_cell.to_s.should == 'd3'
44
+ end
45
+
46
+ it "should know the area covered by its totals" do
47
+ table.totals.start_cell.to_s.should == 'b7'
48
+ table.totals.end_cell.to_s.should == 'd7'
49
+ end
50
+
51
+ it "should know the area covered by each of its columns (excluding the headers and the totals)" do
52
+ table.column('ColA').start_cell.to_s.should == 'b4'
53
+ table.column('ColA').end_cell.to_s.should == 'b6'
54
+ table.column('ColC').start_cell.to_s.should == 'd4'
55
+ table.column('ColC').end_cell.to_s.should == 'd6'
56
+ end
57
+
58
+ it "should be able to translate structured references into normal references" do
59
+ table.reference_for('ColA').start_cell.to_s.should == 'b4'
60
+ table.reference_for('ColA').end_cell.to_s.should == 'b6'
61
+ table.reference_for('#All').start_cell.to_s.should == 'b3'
62
+ table.reference_for('#All').end_cell.to_s.should == 'd7'
63
+ table.reference_for('#Data').start_cell.to_s.should == 'b4'
64
+ table.reference_for('#Data').end_cell.to_s.should == 'd6'
65
+ table.reference_for('#Headers').start_cell.to_s.should == 'b3'
66
+ table.reference_for('#Headers').end_cell.to_s.should == 'd3'
67
+ table.reference_for('#Totals').start_cell.to_s.should == 'b7'
68
+ table.reference_for('#Totals').end_cell.to_s.should == 'd7'
69
+ end
70
+
71
+ it "should be able to translate structured references that are intersections into normal references" do
72
+ table.reference_for('[#Totals],[ColA]').to_s.should == 'sheet1.b7'
73
+ table.reference_for('[#Headers],[ColC]').to_s.should == 'sheet1.d3'
74
+ table.reference_for('[#All],[ColB]').start_cell.to_s.should == 'c3'
75
+ table.reference_for('[#All],[ColB]').end_cell.to_s.should == 'c7'
76
+ end
77
+
78
+ it "should be able to translate structured references that include the special variable #This Row" do
79
+ table.reference_for('[#This Row],[ColA]', Reference.new('e5')).to_s.should == 'sheet1.b5'
80
+ table.reference_for('#This Row',Reference.new('e5')).start_cell.to_s.should == 'b5'
81
+ table.reference_for('#This Row',Reference.new('e5')).end_cell.to_s.should == 'd5'
82
+ end
83
+
84
+ it "should be able to translate structured references from cells that are in the table, treating them as if they had indicated [#This row] as part of the reference" do
85
+ table.reference_for('ColA', Reference.new('e5',@worksheet)).to_s.should == "sheet1.a('b4','b6')"
86
+ table.reference_for('ColA', Reference.new('c5',@worksheet)).to_s.should == 'sheet1.b5'
87
+ end
88
+
89
+ it "should be able to access structured references by providing the table name to Table.reference_for(table_name,structured_reference,referring_cell)" do
90
+ table
91
+ Table.reference_for('FirstTable','#Data').start_cell.to_s.should == 'b4'
92
+ Table.reference_for('Not a known table','#Data').should == ":ref"
93
+ Table.reference_for('FirstTable','[#This Row],[ColA]', Reference.new('e5')).to_s.should == 'sheet1.b5'
94
+ end
95
+
96
+ it "#inspect should create a string that can be used to recreate the table" do
97
+ table.inspect.should == %Q{'Table.new(sheet1,"FirstTable","B3:D7",["ColA", "ColB", "ColC"],1)'}
98
+ end
99
+
100
+ end
@@ -0,0 +1,49 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe ValueCell do
4
+
5
+ it "creates a ruby method that returns the cell's value as a float if it is a number" do
6
+ cell = ValueCell.new(mock('worksheet',:ruby_name => 'sheet1'),Nokogiri::XML('<c r="C22"><v>24</v></c>').root)
7
+ cell.to_ruby.should == "def c22; 24.0; end\n"
8
+ end
9
+
10
+ it "creates a ruby method that returns the cell's value as a ruby boolean if it is a boolean" do
11
+ cell = ValueCell.new(mock('worksheet',:ruby_name => 'sheet1'),Nokogiri::XML('<c r="C22" t="b"><v>TRUE</v></c>').root)
12
+ cell.to_ruby.should == "def c22; true; end\n"
13
+ cell = ValueCell.new(mock('worksheet',:ruby_name => 'sheet1'),Nokogiri::XML('<c r="C22" t="b"><v>1</v></c>').root)
14
+ cell.to_ruby.should == "def c22; true; end\n"
15
+
16
+ end
17
+
18
+ it "creates a ruby method that returns the cell's value as a ruby string if it is a string" do
19
+ cell = ValueCell.new(mock('worksheet',:ruby_name => 'sheet1'),Nokogiri::XML('<c r="B6" t="str"><v>hello</v></c>').root)
20
+ cell.to_ruby.should == %Q{def b6; "hello"; end\n}
21
+ end
22
+
23
+ it "creates a ruby method that returns the cell's value as a ruby string if it is a shared string" do
24
+ cell = ValueCell.new(mock('worksheet',:ruby_name => 'sheet1'),Nokogiri::XML('<c r="B6" t="s"><v>7</v></c>').root)
25
+ SharedStrings.should_receive(:shared_string_for).with(7).and_return('hello')
26
+ cell.to_ruby.should == %Q{def b6; "hello"; end\n}
27
+ end
28
+
29
+ it "creates a ruby method that returns an appropriate symbol if it is an error" do
30
+ cell = ValueCell.new(mock('worksheet',:ruby_name => 'sheet1'),Nokogiri::XML('<c r="B6" t="e"><v>#N/A</v></c>').root)
31
+ cell.to_ruby.should == "def b6; :na; end\n"
32
+ end
33
+
34
+ it "has a method that confirms it can be replaced with its value" do
35
+ cell = ValueCell.new(mock('worksheet',:ruby_name => 'sheet1'),Nokogiri::XML('<c r="B6" t="str"><v>hello</v></c>').root)
36
+ cell.can_be_replaced_with_value?.should be_true
37
+ end
38
+
39
+ end
40
+
41
+ describe ValueCell, "can list the cells upon which it depends" do
42
+
43
+ it "in simple cases knows what it depends upon" do
44
+ cell = ValueCell.new(mock('worksheet',:ruby_name => 'sheet1'),Nokogiri::XML('<c r="B6" t="s"><v>7</v></c>').root)
45
+ cell.work_out_dependencies
46
+ cell.dependencies.should == []
47
+ end
48
+
49
+ end