rubyfromexcel 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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