calco 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +34 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +26 -0
  5. data/LICENSE +21 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +360 -0
  8. data/Rakefile +1 -0
  9. data/calco.gemspec +23 -0
  10. data/examples/ages.ods +0 -0
  11. data/examples/compute_cells.rb +61 -0
  12. data/examples/data.csv +8 -0
  13. data/examples/example.rb +97 -0
  14. data/examples/multiplication_tables.ods +0 -0
  15. data/examples/multiplication_tables.rb +73 -0
  16. data/examples/register_function.rb +44 -0
  17. data/examples/using_date_functions.rb +42 -0
  18. data/examples/write_csv.rb +68 -0
  19. data/examples/write_ods.rb +69 -0
  20. data/lib/calco.rb +17 -0
  21. data/lib/calco/core_ext/fixnum.rb +22 -0
  22. data/lib/calco/core_ext/float.rb +22 -0
  23. data/lib/calco/core_ext/range.rb +15 -0
  24. data/lib/calco/core_ext/string.rb +20 -0
  25. data/lib/calco/date_functions.rb +13 -0
  26. data/lib/calco/definition_dsl.rb +127 -0
  27. data/lib/calco/elements/aggregator.rb +17 -0
  28. data/lib/calco/elements/builtin_function.rb +84 -0
  29. data/lib/calco/elements/constant.rb +31 -0
  30. data/lib/calco/elements/current.rb +19 -0
  31. data/lib/calco/elements/element.rb +31 -0
  32. data/lib/calco/elements/empty.rb +9 -0
  33. data/lib/calco/elements/formula.rb +42 -0
  34. data/lib/calco/elements/if.rb +26 -0
  35. data/lib/calco/elements/operation.rb +34 -0
  36. data/lib/calco/elements/operator.rb +17 -0
  37. data/lib/calco/elements/or.rb +26 -0
  38. data/lib/calco/elements/value_extractor.rb +42 -0
  39. data/lib/calco/elements/variable.rb +35 -0
  40. data/lib/calco/engines/calculator_builtin_functions.rb +32 -0
  41. data/lib/calco/engines/csv_engine.rb +80 -0
  42. data/lib/calco/engines/default_engine.rb +140 -0
  43. data/lib/calco/engines/office_engine.rb +263 -0
  44. data/lib/calco/engines/simple_calculator_engine.rb +151 -0
  45. data/lib/calco/math_functions.rb +9 -0
  46. data/lib/calco/sheet.rb +363 -0
  47. data/lib/calco/spreadsheet.rb +172 -0
  48. data/lib/calco/string_functions.rb +9 -0
  49. data/lib/calco/style.rb +15 -0
  50. data/lib/calco/time_functions.rb +12 -0
  51. data/lib/calco/version.rb +3 -0
  52. data/spec/absolute_references_spec.rb +86 -0
  53. data/spec/builtin_functions_spec.rb +161 -0
  54. data/spec/calculator_engine_spec.rb +251 -0
  55. data/spec/conditions_spec.rb +118 -0
  56. data/spec/content_change_spec.rb +190 -0
  57. data/spec/csv_engine_spec.rb +324 -0
  58. data/spec/default_engine_spec.rb +135 -0
  59. data/spec/definitions_spec.rb +65 -0
  60. data/spec/errors_spec.rb +189 -0
  61. data/spec/functions_spec.rb +251 -0
  62. data/spec/header_row_spec.rb +63 -0
  63. data/spec/range_spec.rb +189 -0
  64. data/spec/sheet_selections_spec.rb +49 -0
  65. data/spec/sheet_spec.rb +229 -0
  66. data/spec/smart_types_spec.rb +43 -0
  67. data/spec/spreadsheet_spec.rb +80 -0
  68. data/spec/styles_spec.rb +29 -0
  69. data/spec/variables_spec.rb +41 -0
  70. metadata +158 -0
@@ -0,0 +1,65 @@
1
+ require 'calco'
2
+
3
+ RSpec.configure do |c|
4
+ c.alias_example_to :check
5
+ end
6
+
7
+ describe "definitions" do
8
+
9
+ check "definitions setup" do
10
+
11
+ doc = spreadsheet do
12
+
13
+ definitions do
14
+
15
+ set a: 8
16
+ set b: 'hello'
17
+
18
+ function f1: a
19
+ function f2: b
20
+
21
+ end
22
+
23
+ sheet "A" do
24
+ column value_of(:a)
25
+ column value_of(:b)
26
+ column :f1
27
+ column :f2
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ check "definitions are visible to all sheets" do
35
+
36
+ doc = spreadsheet do
37
+
38
+ definitions do
39
+
40
+ set a: 8
41
+
42
+ function f1: a
43
+
44
+ end
45
+
46
+ sheet "A" do
47
+ column value_of(:a)
48
+ column :f1
49
+ end
50
+
51
+ sheet "B" do
52
+ column value_of(:a)
53
+ column :f1
54
+ end
55
+
56
+ sheet "C" do
57
+ column value_of(:a)
58
+ column :f1
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,189 @@
1
+ require 'calco'
2
+
3
+ RSpec.configure do |c|
4
+ c.alias_example_to :detect
5
+ end
6
+
7
+ describe 'Spreadsheet errors' do
8
+
9
+ detect "variable does not exist" do
10
+
11
+ expect {
12
+
13
+ spreadsheet do
14
+
15
+ sheet do
16
+
17
+ column value_of(:some_var)
18
+
19
+ end
20
+
21
+ end
22
+
23
+ }.to raise_error("Unknown variable some_var")
24
+
25
+ end
26
+
27
+ detect "function using an unknown variable" do
28
+
29
+ expect {
30
+
31
+ doc = spreadsheet do
32
+
33
+ definitions do
34
+
35
+ function some_var + 1
36
+
37
+ end
38
+
39
+ end
40
+
41
+ }.to raise_error("Unknown function or variable 'some_var'")
42
+
43
+ end
44
+
45
+ detect "assiging value to unknown variable" do
46
+
47
+ doc = spreadsheet do
48
+
49
+ sheet do
50
+
51
+ end
52
+
53
+ end
54
+
55
+ expect {
56
+
57
+ doc.save($stdout) do |spreadsheet|
58
+
59
+ sheet = spreadsheet.current
60
+
61
+ sheet[:some_var] = 12
62
+
63
+ end
64
+
65
+ }.to raise_error("Unknown variable 'some_var'")
66
+
67
+ end
68
+
69
+ detect "reference to an unknown function" do
70
+
71
+ expect {
72
+
73
+ spreadsheet do
74
+
75
+ sheet do
76
+
77
+ column :some_function
78
+
79
+ end
80
+
81
+ end
82
+
83
+ }.to raise_error("Unknown function or variable 'some_function'")
84
+
85
+ end
86
+
87
+ detect "using an unknown function" do
88
+
89
+ expect {
90
+
91
+ spreadsheet do
92
+
93
+ definitions do
94
+
95
+ function name: some_function
96
+
97
+ end
98
+
99
+ end
100
+
101
+ }.to raise_error("Unknown function or variable 'some_function'")
102
+
103
+ end
104
+
105
+ detect "declaring a variable twice" do
106
+
107
+ expect {
108
+
109
+ spreadsheet do
110
+
111
+ definitions do
112
+
113
+ set var: 12
114
+ set var: "hello"
115
+
116
+ end
117
+
118
+ end
119
+
120
+ }.to raise_error("Variable 'var' already set")
121
+
122
+ end
123
+
124
+ detect "declaring a function twice" do
125
+
126
+ expect {
127
+
128
+ spreadsheet do
129
+
130
+ definitions do
131
+
132
+ function f: 12
133
+ function f: "hello"
134
+
135
+ end
136
+
137
+ end
138
+
139
+ }.to raise_error("Function 'f' already defined")
140
+
141
+ end
142
+
143
+ detect "unnamed option for column" do
144
+
145
+ expect {
146
+
147
+ spreadsheet do
148
+
149
+ definitions do
150
+
151
+ set price: 11
152
+
153
+ end
154
+
155
+ sheet do
156
+ column :price, 'pp'
157
+ end
158
+
159
+ end
160
+
161
+ }.to raise_error(ArgumentError, "Options should be a Hash")
162
+
163
+ end
164
+
165
+ detect "unknown column id" do
166
+
167
+ expect {
168
+
169
+ doc = spreadsheet do
170
+
171
+ definitions do
172
+
173
+ set a: 'a'
174
+
175
+ end
176
+
177
+ sheet do
178
+ column :a
179
+ end
180
+
181
+ end
182
+
183
+ doc.current.replace_content :no_id, nil
184
+
185
+ }.to raise_error(RuntimeError, "Column id 'no_id' not found")
186
+
187
+ end
188
+
189
+ end
@@ -0,0 +1,251 @@
1
+ require 'calco'
2
+
3
+ RSpec.configure do |c|
4
+ c.alias_example_to :support
5
+ end
6
+
7
+ describe "Functions support" do
8
+
9
+ support "operators" do
10
+
11
+ doc = spreadsheet do
12
+
13
+ definitions do
14
+
15
+ set price: 14.4
16
+ set product: 'USB 8Gb'
17
+ set tax: 13
18
+ set quantity: 30
19
+
20
+ function total: price * quantity * (tax / 100 + 1)
21
+
22
+ end
23
+
24
+ sheet do
25
+
26
+ column value_of(:product)
27
+ column value_of(:price)
28
+ column value_of(:quantity)
29
+ column value_of(:tax)
30
+ column skip
31
+ column :total
32
+
33
+ end
34
+
35
+ end
36
+
37
+ row = doc.row(1)
38
+
39
+ expect(row[0]).to eq('"USB 8Gb"')
40
+ expect(row[1]).to eq('14.4')
41
+ expect(row[2]).to eq('30')
42
+ expect(row[3]).to eq('13')
43
+
44
+ expect(row[5]).to eq('(B1*C1)*((D1/100)+1)')
45
+
46
+ end
47
+
48
+ support "functions using functions" do
49
+
50
+ doc = spreadsheet do
51
+
52
+ definitions do
53
+
54
+ set price: 14.4
55
+ set product: 'USB 8Gb'
56
+ set tax: 13
57
+ set quantity: 30
58
+
59
+ function total: price * quantity
60
+ function total_with_taxes: total * (tax / 100 + 1)
61
+
62
+ end
63
+
64
+ sheet do
65
+
66
+ column value_of(:product)
67
+ column value_of(:price)
68
+ column value_of(:quantity)
69
+ column value_of(:tax)
70
+ column skip
71
+ column :total
72
+ column :total_with_taxes
73
+
74
+ end
75
+
76
+ end
77
+
78
+ row = doc.row(1)
79
+
80
+ expect(row[0]).to eq('"USB 8Gb"')
81
+ expect(row[1]).to eq('14.4')
82
+ expect(row[2]).to eq('30')
83
+ expect(row[3]).to eq('13')
84
+
85
+ expect(row[5]).to eq('B1*C1')
86
+ expect(row[6]).to eq('F1*((D1/100)+1)')
87
+
88
+ end
89
+
90
+ support "conditions with functions" do
91
+
92
+ doc = spreadsheet do
93
+
94
+ definitions do
95
+
96
+ set x: 9
97
+
98
+ function f0: x + 3
99
+ function f1: f0 * f0
100
+ function f2: f1 + f0
101
+ function f3: f2 + 7
102
+
103
+ function cond: _if(f1 > 2, f2, f3)
104
+
105
+ end
106
+
107
+ sheet do
108
+
109
+ column value_of(:x)
110
+ column :f0
111
+ column :f1
112
+ column :f2
113
+ column :f3
114
+
115
+ column :cond
116
+
117
+ end
118
+
119
+ end
120
+
121
+ row = doc.row(1)
122
+
123
+ expect(row[0]).to eq('9')
124
+ expect(row[1]).to eq('A1+3')
125
+ expect(row[2]).to eq('B1*B1')
126
+ expect(row[3]).to eq('C1+B1')
127
+ expect(row[4]).to eq('D1+7')
128
+ expect(row[5]).to eq('IF(C1>2;D1;E1)')
129
+
130
+ end
131
+
132
+ support "containing literals" do
133
+
134
+ some_day = Date.new(1998, 7, 12)
135
+
136
+ doc = spreadsheet do
137
+
138
+ definitions do
139
+
140
+ function a: 'string'
141
+ function b: 12
142
+ function c: 34.9
143
+ function d: some_day
144
+
145
+ end
146
+
147
+ sheet do
148
+
149
+ column :a
150
+ column :b
151
+ column :c
152
+ column :d
153
+
154
+ end
155
+
156
+ end
157
+
158
+ row = doc.current.row(1)
159
+
160
+ expect(row[0]).to eq('"string"')
161
+ expect(row[1]).to eq("12")
162
+ expect(row[2]).to eq("34.9")
163
+ expect(row[3]).to eq(some_day.to_s)
164
+
165
+ end
166
+
167
+ support "starting with an integer" do
168
+
169
+ doc = spreadsheet do
170
+
171
+ definitions do
172
+
173
+ set x: 12
174
+
175
+ function add: 66 + x
176
+
177
+ end
178
+
179
+ sheet do
180
+
181
+ column value_of(:x)
182
+ column :add
183
+
184
+ end
185
+
186
+ end
187
+
188
+ row = doc.row(1)
189
+
190
+ expect(row[0]).to eq('12')
191
+ expect(row[1]).to eq('66+A1')
192
+
193
+ end
194
+
195
+ support "starting with a float" do
196
+
197
+ doc = spreadsheet do
198
+
199
+ definitions do
200
+
201
+ set x: 12.9
202
+
203
+ function add: 34.7 + x
204
+
205
+ end
206
+
207
+ sheet do
208
+
209
+ column value_of(:x)
210
+ column :add
211
+
212
+ end
213
+
214
+ end
215
+
216
+ row = doc.row(1)
217
+
218
+ expect(row[0]).to eq('12.9')
219
+ expect(row[1]).to eq('34.7+A1')
220
+
221
+ end
222
+
223
+ support "starting with a string" do
224
+
225
+ doc = spreadsheet do
226
+
227
+ definitions do
228
+
229
+ set name: "Joe"
230
+
231
+ function greeting: "Hello " + name
232
+
233
+ end
234
+
235
+ sheet do
236
+
237
+ column value_of(:name)
238
+ column :greeting
239
+
240
+ end
241
+
242
+ end
243
+
244
+ row = doc.row(1)
245
+
246
+ expect(row[0]).to eq('"Joe"')
247
+ expect(row[1]).to eq('"Hello "+A1')
248
+
249
+ end
250
+
251
+ end