24
26
self.TempPath = tempfile.gettempdir()
25
27
FreeCAD.Console.PrintLog( ' Using temp path: ' + self.TempPath + '\n')
29
def testAggregates(self):
30
""" Test all aggregate functions """
31
sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet')
35
sheet.set('A1', '=sum(1)')
36
sheet.set('A2', '=sum(1;2)')
37
sheet.set('A3', '=sum(1;2;3)')
38
sheet.set('A4', '=sum(1;2;3;B3)')
39
sheet.set('A5', '=sum(1;2;3;B3:B5)')
40
sheet.set('A6', '=stddev(1;2;3)')
41
sheet.set('A7', '=average(1;2;3)')
42
sheet.set('A8', '=count(1;2;3)')
43
sheet.set('A9', '=min(1;2;3)')
44
sheet.set('A10', '=max(1;2;3)')
46
self.assertEqual(sheet.A1, 1)
47
self.assertEqual(sheet.A2, 3)
48
self.assertEqual(sheet.A3, 6)
49
self.assertEqual(sheet.A4, 10)
50
self.assertEqual(sheet.A5, 21)
51
self.assertEqual(sheet.A6, 1)
52
self.assertEqual(sheet.A7, 2)
53
self.assertEqual(sheet.A8, 3)
54
self.assertEqual(sheet.A9, 1)
55
self.assertEqual(sheet.A10, 3)
57
def assertMostlyEqual(self, a, b):
58
if type(a) is Quantity:
59
self.assertTrue( math.fabs(a.Value - b.Value) < 1e-14)
60
self.assertTrue( a.Unit == b.Unit)
62
self.assertTrue( math.fabs(a - b) < 1e-14)
64
def testFunctions(self):
65
""" Test all built-in simple functions """
66
doc = FreeCAD.newDocument()
67
sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet')
68
sheet.set('A1', '=cos(60)') # Cos
69
sheet.set('B1', '=cos(60deg)')
70
sheet.set('C1', '=cos(pi / 2 * 1rad)')
71
sheet.set('A2', '=sin(30)') # Sin
72
sheet.set('B2', '=sin(30deg)')
73
sheet.set('C2', '=sin(pi / 6 * 1rad)')
74
sheet.set('A3', '=tan(45)') # Tan
75
sheet.set('B3', '=tan(45deg)')
76
sheet.set('C3', '=tan(pi / 4 * 1rad)')
77
sheet.set('A4', '=abs(3)') # Abs
78
sheet.set('B4', '=abs(-3)')
79
sheet.set('C4', '=abs(-3mm)')
80
sheet.set('A5', '=exp(3)') # Exp
81
sheet.set('B5', '=exp(-3)')
82
sheet.set('C5', '=exp(-3mm)')
83
sheet.set('A6', '=log(3)') # Log
84
sheet.set('B6', '=log(-3)')
85
sheet.set('C6', '=log(-3mm)')
86
sheet.set('A7', '=log10(10)') # Log10
87
sheet.set('B7', '=log10(-3)')
88
sheet.set('C7', '=log10(-3mm)')
89
sheet.set('A8', '=round(3.4)')# Round
90
sheet.set('B8', '=round(3.6)')
91
sheet.set('C8', '=round(-3.4)')
92
sheet.set('D8', '=round(-3.6)')
93
sheet.set('E8', '=round(3.4mm)')
94
sheet.set('F8', '=round(3.6mm)')
95
sheet.set('G8', '=round(-3.4mm)')
96
sheet.set('H8', '=round(-3.6mm)')
97
sheet.set('A9', '=trunc(3.4)')# Trunc
98
sheet.set('B9', '=trunc(3.6)')
99
sheet.set('C9', '=trunc(-3.4)')
100
sheet.set('D9', '=trunc(-3.6)')
101
sheet.set('E9', '=trunc(3.4mm)')
102
sheet.set('F9', '=trunc(3.6mm)')
103
sheet.set('G9', '=trunc(-3.4mm)')
104
sheet.set('H9', '=trunc(-3.6mm)')
105
sheet.set('A10', '=ceil(3.4)') # Ceil
106
sheet.set('B10', '=ceil(3.6)')
107
sheet.set('C10', '=ceil(-3.4)')
108
sheet.set('D10', '=ceil(-3.6)')
109
sheet.set('E10', '=ceil(3.4mm)')
110
sheet.set('F10', '=ceil(3.6mm)')
111
sheet.set('G10', '=ceil(-3.4mm)')
112
sheet.set('H10', '=ceil(-3.6mm)')
113
sheet.set('A11', '=floor(3.4)')# Floor
114
sheet.set('B11', '=floor(3.6)')
115
sheet.set('C11', '=floor(-3.4)')
116
sheet.set('D11', '=floor(-3.6)')
117
sheet.set('E11', '=floor(3.4mm)')
118
sheet.set('F11', '=floor(3.6mm)')
119
sheet.set('G11', '=floor(-3.4mm)')
120
sheet.set('H11', '=floor(-3.6mm)')
121
sheet.set('A12', '=asin(0.5)') # Asin
122
sheet.set('B12', '=asin(0.5mm)')
123
sheet.set('A13', '=acos(0.5)') # Acos
124
sheet.set('B13', '=acos(0.5mm)')
125
sheet.set('A14', '=atan(sqrt(3))') # Atan
126
sheet.set('B14', '=atan(0.5mm)')
127
sheet.set('A15', '=sinh(0.5)') # Sinh
128
sheet.set('B15', '=sinh(0.5mm)')
129
sheet.set('A16', '=cosh(0.5)') # Cosh
130
sheet.set('B16', '=cosh(0.5mm)')
131
sheet.set('A17', '=tanh(0.5)') # Tanh
132
sheet.set('B17', '=tanh(0.5mm)')
133
sheet.set('A18', '=sqrt(4)') # Sqrt
134
sheet.set('B18', '=sqrt(4mm^2)')
135
sheet.set('A19', '=mod(7; 4)') # Mod
136
sheet.set('B19', '=mod(-7; 4)')
137
sheet.set('C19', '=mod(7mm; 4)')
138
sheet.set('D19', '=mod(7mm; 4mm)')
139
sheet.set('A20', '=atan2(3; 3)') # Atan2
140
sheet.set('B20', '=atan2(-3; 3)')
141
sheet.set('C20', '=atan2(3mm; 3)')
142
sheet.set('D20', '=atan2(3mm; 3mm)')
143
sheet.set('A21', '=pow(7; 4)') # Pow
144
sheet.set('B21', '=pow(-7; 4)')
145
sheet.set('C21', '=pow(7mm; 4)')
146
sheet.set('D21', '=pow(7mm; 4mm)')
148
self.assertMostlyEqual(sheet.A1, 0.5) # Cos
149
self.assertMostlyEqual(sheet.B1, 0.5)
150
self.assertMostlyEqual(sheet.C1, 0)
151
self.assertMostlyEqual(sheet.A2, 0.5) # Sin
152
self.assertMostlyEqual(sheet.B2, 0.5)
153
self.assertMostlyEqual(sheet.C2, 0.5)
154
self.assertMostlyEqual(sheet.A3, 1) # Tan
155
self.assertMostlyEqual(sheet.B3, 1)
156
self.assertMostlyEqual(sheet.C3, 1 )
157
self.assertMostlyEqual(sheet.A4, 3) # Abs
158
self.assertMostlyEqual(sheet.B4, 3)
159
self.assertMostlyEqual(sheet.C4, Quantity('3 mm'))
160
self.assertMostlyEqual(sheet.A5, math.exp(3)) # Exp
161
self.assertMostlyEqual(sheet.B5, math.exp(-3))
162
self.assertEqual(sheet.C5, u'ERR: Unit must be empty.')
163
self.assertMostlyEqual(sheet.A6, math.log(3)) # Log
164
self.assertTrue(math.isnan(sheet.B6))
165
self.assertEqual(sheet.C6, u'ERR: Unit must be empty.')
166
self.assertMostlyEqual(sheet.A7, math.log10(10)) # Log10
167
self.assertTrue(math.isnan(sheet.B7))
168
self.assertEqual(sheet.C7, u'ERR: Unit must be empty.')
169
self.assertMostlyEqual(sheet.A8, 3) # Round
170
self.assertMostlyEqual(sheet.B8, 4)
171
self.assertMostlyEqual(sheet.C8, -3)
172
self.assertMostlyEqual(sheet.D8, -4)
173
self.assertEqual(sheet.E8, Quantity('3 mm'))
174
self.assertEqual(sheet.F8, Quantity('4 mm'))
175
self.assertEqual(sheet.G8, Quantity('-3 mm'))
176
self.assertEqual(sheet.H8, Quantity('-4 mm'))
177
self.assertMostlyEqual(sheet.A9, 3)# Trunc
178
self.assertMostlyEqual(sheet.B9, 3)
179
self.assertMostlyEqual(sheet.C9, -3)
180
self.assertMostlyEqual(sheet.D9, -3)
181
self.assertEqual(sheet.E9, Quantity('3 mm'))
182
self.assertEqual(sheet.F9, Quantity('3 mm'))
183
self.assertEqual(sheet.G9, Quantity('-3 mm'))
184
self.assertEqual(sheet.H9, Quantity('-3 mm'))
185
self.assertMostlyEqual(sheet.A10, 4) # Ceil
186
self.assertMostlyEqual(sheet.B10, 4)
187
self.assertMostlyEqual(sheet.C10, -3)
188
self.assertMostlyEqual(sheet.D10, -3)
189
self.assertMostlyEqual(sheet.E10, Quantity('4 mm'))
190
self.assertMostlyEqual(sheet.F10, Quantity('4 mm'))
191
self.assertMostlyEqual(sheet.G10, Quantity('-3 mm'))
192
self.assertMostlyEqual(sheet.H10, Quantity('-3 mm'))
193
self.assertMostlyEqual(sheet.A11, 3)# Floor
194
self.assertMostlyEqual(sheet.B11, 3)
195
self.assertMostlyEqual(sheet.C11, -4)
196
self.assertMostlyEqual(sheet.D11, -4)
197
self.assertMostlyEqual(sheet.E11, Quantity('3 mm'))
198
self.assertMostlyEqual(sheet.F11, Quantity('3 mm'))
199
self.assertMostlyEqual(sheet.G11, Quantity('-4 mm'))
200
self.assertMostlyEqual(sheet.H11, Quantity('-4 mm'))
201
self.assertMostlyEqual(sheet.A12, Quantity('30 deg')) # Asin
202
self.assertEqual(sheet.B12, u'ERR: Unit must be empty.')
203
self.assertMostlyEqual(sheet.A13, Quantity('60 deg')) # Acos
204
self.assertEqual(sheet.B13, u'ERR: Unit must be empty.')
205
self.assertMostlyEqual(sheet.A14, Quantity('60 deg')) # Atan
206
self.assertEqual(sheet.B14, u'ERR: Unit must be empty.')
207
self.assertMostlyEqual(sheet.A15, math.sinh(0.5)) # Sinh
208
self.assertEqual(sheet.B15, u'ERR: Unit must be empty.')
209
self.assertMostlyEqual(sheet.A16, math.cosh(0.5)) # Cosh
210
self.assertEqual(sheet.B16, u'ERR: Unit must be empty.')
211
self.assertMostlyEqual(sheet.A17, math.tanh(0.5)) # Tanh
212
self.assertEqual(sheet.B17, u'ERR: Unit must be empty.')
213
self.assertMostlyEqual(sheet.A18, 2) # Sqrt
214
self.assertMostlyEqual(sheet.B18, Quantity('2 mm'))
215
self.assertMostlyEqual(sheet.A19, 3) # Mod
216
self.assertMostlyEqual(sheet.B19, -3)
217
self.assertMostlyEqual(sheet.C19, Quantity('3 mm'))
218
self.assertEqual(sheet.D19, u'ERR: Second argument must have empty unit.')
219
self.assertMostlyEqual(sheet.A20, Quantity('45 deg')) # Atan2
220
self.assertMostlyEqual(sheet.B20, Quantity('-45 deg'))
221
self.assertEqual(sheet.C20, u'ERR: Units must be equal')
222
self.assertMostlyEqual(sheet.D20, Quantity('45 deg'))
223
self.assertMostlyEqual(sheet.A21, 2401) # Pow
224
self.assertMostlyEqual(sheet.B21, 2401)
225
self.assertMostlyEqual(sheet.C21, Quantity('2401mm^4'))
226
self.assertEqual(sheet.D21, u'ERR: Exponent is not allowed to have a unit.')
27
228
def testRelationalOperators(self):
229
""" Test relational operators """
28
230
sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet')
29
231
# All should be 1 as result
30
232
sheet.set('A1', '=1 == 1 ? 1 : 0')
78
280
self.assertEqual(sheet.A23, 1)
79
281
self.assertEqual(sheet.A24, 1)
284
""" Units -- test unit calculations. """
285
sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet')
286
sheet.set('A1', '=2mm + 3mm')
287
sheet.set('A2', '=2mm - 3mm')
288
sheet.set('A3', '=2mm * 3mm')
289
sheet.set('A4', '=4mm / 2mm')
290
sheet.set('A5', '=(4mm)^2')
291
sheet.set('A6', '=5(mm^2)')
292
sheet.set('A7', '=5mm^2') # ^2 operates on whole number
293
sheet.set('A8', '=5')
294
sheet.set('A9', '=5*1/K') # Currently fails
295
sheet.set('A10', '=5 K^-1') # Currently fails
296
sheet.set('A11', '=9.8 m/s^2') # Currently fails
297
sheet.setDisplayUnit('A8', '1/K')
299
self.assertEqual(sheet.A1, Quantity('5mm'))
300
self.assertEqual(sheet.A2, Quantity('-1 mm'))
301
self.assertEqual(sheet.A3, Quantity('6 mm^2'))
302
self.assertEqual(sheet.A4, Quantity('2'))
303
self.assertEqual(sheet.A5, Quantity('16 mm^2'))
304
self.assertEqual(sheet.A6, Quantity('5 mm^2'))
305
self.assertEqual(sheet.A7, Quantity('5 mm^2'))
306
self.assertEqual(sheet.A8, Quantity('5'))
307
self.assertEqual(sheet.A9, Quantity('5 K^-1'))
308
self.assertEqual(sheet.A10, Quantity('5 K^-1'))
309
self.assertEqual(sheet.A11, Quantity('9.8 m/s^2'))
81
311
def testPrecedence(self):
82
312
""" Precedence -- test precedence for relational operators and conditional operator. """
83
313
sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet')
84
314
sheet.set('A1', '=1 < 2 ? 3 : 4')
85
315
sheet.set('A2', '=1 + 2 < 3 + 4 ? 5 + 6 : 7 + 8')
86
316
sheet.set('A3', '=1 + 2 * 1 < 3 + 4 ? 5 * 2 + 6 * 3 + 2 ^ 4 : 7 * 2 + 8 * 3 + 2 ^ 3')
317
sheet.set('A4', '=123')
318
sheet.set('A5', '=123 + 321')
319
sheet.set('A6', '=123 * 2 + 321')
320
sheet.set('A7', '=123 * 2 + 333 / 3')
321
sheet.set('A8', '=123 * (2 + 321)')
322
sheet.set('A9', '=3 ^ 4')
323
sheet.set('A10', '=3 ^ 4 * 2')
324
sheet.set('A11', '=3 ^ (4 * 2)')
325
sheet.set('A12', '=3 ^ 4 + 4')
326
sheet.set('A13', '=1 + 4 / 2 + 5')
327
sheet.set('A14', '=(3 + 6) / (1 + 2)')
328
sheet.set('A15', '=1 * 2 / 3 * 4')
329
sheet.set('A16', '=(1 * 2) / (3 * 4)')
331
sheet.set('A17', '=3 ^ 4 ^ 2') # exponentiation is left-associative; to follow excel, openoffice, matlab, octave
332
sheet.set('A18', '=3 ^ (4 ^ 2)') # exponentiation is left-associative
333
sheet.set('A19', '=(3 ^ 4) ^ 2') # exponentiation is left-associative
334
sheet.set('A20', '=3 + 4 + 2')
335
sheet.set('A21', '=3 + (4 + 2)')
336
sheet.set('A22', '=(3 + 4) + 2')
337
sheet.set('A23', '=3 - 4 - 2')
338
sheet.set('A24', '=3 - (4 - 2)')
339
sheet.set('A25', '=(3 - 4) - 2')
340
sheet.set('A26', '=3 * 4 * 2')
341
sheet.set('A27', '=3 * (4 * 2)')
342
sheet.set('A28', '=(3 * 4) * 2')
343
sheet.set('A29', '=3 / 4 / 2')
344
sheet.set('A30', '=3 / (4 / 2)')
345
sheet.set('A31', '=(3 / 4) / 2')
346
sheet.set('A32', '=pi * 3')
347
sheet.set('A33', '=A32 / 3')
348
sheet.set('A34', '=1 < 2 ? <<A>> : <<B>>')
349
sheet.set('A35', '=min(A32:A33)')
350
sheet.set('A36', '=(1 < 2 ? 0 : 1) * 3')
87
351
self.doc.recompute()
88
352
self.assertEqual(sheet.getContents("A1"), "=1 < 2 ? 3 : 4")
89
353
self.assertEqual(sheet.getContents("A2"), "=1 + 2 < 3 + 4 ? 5 + 6 : 7 + 8")
91
355
self.assertEqual(sheet.A1, 3)
92
356
self.assertEqual(sheet.A2, 11)
93
357
self.assertEqual(sheet.A3, 44)
358
self.assertEqual(sheet.A4, 123)
359
self.assertEqual(sheet.A5, 444)
360
self.assertEqual(sheet.A6, 567)
361
self.assertEqual(sheet.A7, 357)
362
self.assertEqual(sheet.A8, 39729)
363
self.assertEqual(sheet.A9, 81)
364
self.assertEqual(sheet.A10, 162)
365
self.assertEqual(sheet.A11, 6561)
366
self.assertEqual(sheet.A12, 85)
367
self.assertEqual(sheet.A13, 8)
368
self.assertEqual(sheet.A14, 3)
369
self.assertEqual(sheet.A15, 8.0/3)
370
self.assertEqual(sheet.A16, 1.0/6)
371
self.assertEqual(sheet.A17, 6561)
372
self.assertEqual(sheet.A18, 43046721)
373
self.assertEqual(sheet.A19, 6561)
374
self.assertEqual(sheet.A20, 9)
375
self.assertEqual(sheet.A21, 9)
376
self.assertEqual(sheet.A22, 9)
377
self.assertEqual(sheet.A23, -3)
378
self.assertEqual(sheet.A24, 1)
379
self.assertEqual(sheet.A25, -3)
380
self.assertEqual(sheet.A26, 24)
381
self.assertEqual(sheet.A27, 24)
382
self.assertEqual(sheet.A28, 24)
383
self.assertEqual(sheet.A29, 3.0/8)
384
self.assertEqual(sheet.A30, 3.0/2)
385
self.assertEqual(sheet.A31, 3.0/8)
386
self.assertEqual(sheet.getContents('A1'), '=1 < 2 ? 3 : 4')
387
self.assertEqual(sheet.getContents('A2'), '=1 + 2 < 3 + 4 ? 5 + 6 : 7 + 8')
388
self.assertEqual(sheet.getContents('A3'), '=1 + 2 * 1 < 3 + 4 ? 5 * 2 + 6 * 3 + 2 ^ 4 : 7 * 2 + 8 * 3 + 2 ^ 3')
389
self.assertEqual(sheet.getContents('A4'), '123')
390
self.assertEqual(sheet.getContents('A5'), '=123 + 321')
391
self.assertEqual(sheet.getContents('A6'), '=123 * 2 + 321')
392
self.assertEqual(sheet.getContents('A7'), '=123 * 2 + 333 / 3')
393
self.assertEqual(sheet.getContents('A8'), '=123 * (2 + 321)')
394
self.assertEqual(sheet.getContents('A9'), '=3 ^ 4')
395
self.assertEqual(sheet.getContents('A10'), '=3 ^ 4 * 2')
396
self.assertEqual(sheet.getContents('A11'), '=3 ^ (4 * 2)')
397
self.assertEqual(sheet.getContents('A12'), '=3 ^ 4 + 4')
398
self.assertEqual(sheet.getContents('A13'), '=1 + 4 / 2 + 5')
399
self.assertEqual(sheet.getContents('A14'), '=(3 + 6) / (1 + 2)')
400
self.assertEqual(sheet.getContents('A15'), '=1 * 2 / 3 * 4')
401
self.assertEqual(sheet.getContents('A16'), '=1 * 2 / 3 * 4')
402
self.assertEqual(sheet.getContents('A17'), '=3 ^ 4 ^ 2')
403
self.assertEqual(sheet.getContents('A18'), '=3 ^ (4 ^ 2)')
404
self.assertEqual(sheet.getContents('A19'), '=3 ^ 4 ^ 2')
405
self.assertEqual(sheet.getContents('A20'), '=3 + 4 + 2')
406
self.assertEqual(sheet.getContents('A21'), '=3 + 4 + 2')
407
self.assertEqual(sheet.getContents('A22'), '=3 + 4 + 2')
408
self.assertEqual(sheet.getContents('A23'), '=3 - 4 - 2')
409
self.assertEqual(sheet.getContents('A24'), '=3 - (4 - 2)')
410
self.assertEqual(sheet.getContents('A25'), '=3 - 4 - 2')
411
self.assertEqual(sheet.getContents('A26'), '=3 * 4 * 2')
412
self.assertEqual(sheet.getContents('A27'), '=3 * 4 * 2')
413
self.assertEqual(sheet.getContents('A28'), '=3 * 4 * 2')
414
self.assertEqual(sheet.getContents('A29'), '=3 / 4 / 2')
415
self.assertEqual(sheet.getContents('A30'), '=3 / (4 / 2)')
416
self.assertEqual(sheet.getContents('A31'), '=3 / 4 / 2')
417
self.assertEqual(sheet.getContents('A32'), '=pi * 3')
418
self.assertEqual(sheet.getContents('A33'), '=A32 / 3')
419
self.assertEqual(sheet.getContents('A34'), '=1 < 2 ? <<A>> : <<B>>')
420
self.assertEqual(sheet.getContents('A35'), '=min(A32:A33)')
421
self.assertEqual(sheet.getContents('A36'), '=(1 < 2 ? 0 : 1) * 3')
423
def testNumbers(self):
424
""" Test different numbers """
425
sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet')
427
sheet.set('A2', '1.5')
428
sheet.set('A3', '.5')
429
sheet.set('A4', '1e2')
430
sheet.set('A5', '1E2')
431
sheet.set('A6', '1e-2')
432
sheet.set('A7', '1E-2')
433
sheet.set('A8', '1.5e2')
434
sheet.set('A9', '1.5E2')
435
sheet.set('A10', '1.5e-2')
436
sheet.set('A11', '1.5E-2')
437
sheet.set('A12', '.5e2')
438
sheet.set('A13', '.5E2')
439
sheet.set('A14', '.5e-2')
440
sheet.set('A15', '.5E-2')
441
sheet.set('A16', '1/1')
442
sheet.set('A17', '1/2')
443
sheet.set('A18', '2/4')
445
self.assertEqual(sheet.A1, 1)
446
self.assertEqual(sheet.A2, 1.5)
447
self.assertEqual(sheet.A3, 0.5)
448
self.assertEqual(sheet.A4, 1e2)
449
self.assertEqual(sheet.A5, 1e2)
450
self.assertEqual(sheet.A6, 1e-2)
451
self.assertEqual(sheet.A7, 1e-2)
452
self.assertEqual(sheet.A8, 1.5e2)
453
self.assertEqual(sheet.A9, 1.5e2)
454
self.assertEqual(sheet.A10, 1.5e-2)
455
self.assertEqual(sheet.A11, 1.5e-2)
456
self.assertEqual(sheet.A12, 0.5e2)
457
self.assertEqual(sheet.A13, 0.5e2)
458
self.assertEqual(sheet.A14, 0.5e-2)
459
self.assertEqual(sheet.A15, 0.5e-2)
460
self.assertEqual(sheet.A16, 1)
461
self.assertEqual(sheet.A17, 0.5)
462
self.assertEqual(sheet.A18, 0.5)
95
464
def testRemoveRows(self):
96
465
""" Removing rows -- check renaming of internal cells """
97
466
sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet')