excel_to_code 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,759 @@
1
+ #include "excel_to_c_runtime.c"
2
+
3
+ int test_functions() {
4
+ // Test ABS
5
+ assert(excel_abs(ONE).number == 1);
6
+ assert(excel_abs(new_excel_number(-1)).number == 1);
7
+ assert(excel_abs(VALUE).type == ExcelError);
8
+
9
+ // Test ADD
10
+ assert(add(ONE,new_excel_number(-2.5)).number == -1.5);
11
+ assert(add(ONE,VALUE).type == ExcelError);
12
+
13
+ // Test AND
14
+ ExcelValue true_array1[] = { TRUE, new_excel_number(10)};
15
+ ExcelValue true_array2[] = { ONE };
16
+ ExcelValue false_array1[] = { FALSE, new_excel_number(10)};
17
+ ExcelValue false_array2[] = { TRUE, new_excel_number(0)};
18
+ // ExcelValue error_array1[] = { new_excel_number(10)}; // Not implemented
19
+ ExcelValue error_array2[] = { TRUE, NA};
20
+ assert(excel_and(2,true_array1).number == 1);
21
+ assert(excel_and(1,true_array2).number == 1);
22
+ assert(excel_and(2,false_array1).number == 0);
23
+ assert(excel_and(2,false_array2).number == 0);
24
+ // assert(excel_and(1,error_array1).type == ExcelError); // Not implemented
25
+ assert(excel_and(2,error_array2).type == ExcelError);
26
+
27
+ // Test AVERAGE
28
+ ExcelValue array1[] = { new_excel_number(10), new_excel_number(5), TRUE, FALSE};
29
+ ExcelValue array1_v = new_excel_range(array1,2,2);
30
+ ExcelValue array2[] = { array1_v, new_excel_number(9), new_excel_string("Hello")};
31
+ ExcelValue array3[] = { array1_v, new_excel_number(9), new_excel_string("Hello"), VALUE};
32
+ assert(average(4, array1).number == 7.5);
33
+ assert(average(3, array2).number == 8);
34
+ assert(average(4, array3).type == ExcelError);
35
+
36
+ // Test CHOOSE
37
+ assert(choose(ONE,4,array1).number == 10);
38
+ assert(choose(new_excel_number(4),4,array1).type == ExcelBoolean);
39
+ assert(choose(new_excel_number(0),4,array1).type == ExcelError);
40
+ assert(choose(new_excel_number(5),4,array1).type == ExcelError);
41
+ assert(choose(ONE,4,array3).type == ExcelError);
42
+
43
+ // Test COUNT
44
+ assert(count(4,array1).number == 2);
45
+ assert(count(3,array2).number == 3);
46
+ assert(count(4,array3).number == 3);
47
+
48
+ // Test Large
49
+ ExcelValue large_test_array_1[] = { new_excel_number(10), new_excel_number(100), new_excel_number(500), BLANK };
50
+ ExcelValue large_test_array_1_v = new_excel_range(large_test_array_1, 1, 4);
51
+ assert(large(large_test_array_1_v, new_excel_number(1)).number == 500);
52
+ assert(large(large_test_array_1_v, new_excel_number(2)).number == 100);
53
+ assert(large(large_test_array_1_v, new_excel_number(3)).number == 10);
54
+ assert(large(large_test_array_1_v, new_excel_number(4)).type == ExcelError);
55
+ assert(large(new_excel_number(500), new_excel_number(1)).number == 500);
56
+ ExcelValue large_test_array_2[] = { new_excel_number(10), new_excel_number(100), new_excel_number(500), VALUE };
57
+ ExcelValue large_test_array_2_v = new_excel_range(large_test_array_2, 1, 4);
58
+ assert(large(large_test_array_2_v,new_excel_number(2)).type == ExcelError);
59
+ assert(large(new_excel_number(500),VALUE).type == ExcelError);
60
+
61
+
62
+ // Test COUNTA
63
+ ExcelValue count_a_test_array_1[] = { new_excel_number(10), new_excel_number(5), TRUE, FALSE, new_excel_string("Hello"), VALUE, BLANK};
64
+ ExcelValue count_a_test_array_1_v = new_excel_range(count_a_test_array_1,7,1);
65
+ ExcelValue count_a_test_array_2[] = {new_excel_string("Bye"),count_a_test_array_1_v};
66
+ assert(counta(7, count_a_test_array_1).number == 6);
67
+ assert(counta(2, count_a_test_array_2).number == 7);
68
+
69
+ // Test divide
70
+ assert(divide(new_excel_number(12.4),new_excel_number(3.2)).number == 3.875);
71
+ assert(divide(new_excel_number(12.4),new_excel_number(0)).type == ExcelError);
72
+
73
+ // Test excel_equal
74
+ assert(excel_equal(new_excel_number(1.2),new_excel_number(3.4)).type == ExcelBoolean);
75
+ assert(excel_equal(new_excel_number(1.2),new_excel_number(3.4)).number == false);
76
+ assert(excel_equal(new_excel_number(1.2),new_excel_number(1.2)).number == true);
77
+ assert(excel_equal(new_excel_string("hello"), new_excel_string("HELLO")).number == true);
78
+ assert(excel_equal(new_excel_string("hello world"), new_excel_string("HELLO")).number == false);
79
+ assert(excel_equal(new_excel_string("1"), ONE).number == false);
80
+ assert(excel_equal(DIV0, ONE).type == ExcelError);
81
+
82
+ // Test not_equal
83
+ assert(not_equal(new_excel_number(1.2),new_excel_number(3.4)).type == ExcelBoolean);
84
+ assert(not_equal(new_excel_number(1.2),new_excel_number(3.4)).number == true);
85
+ assert(not_equal(new_excel_number(1.2),new_excel_number(1.2)).number == false);
86
+ assert(not_equal(new_excel_string("hello"), new_excel_string("HELLO")).number == false);
87
+ assert(not_equal(new_excel_string("hello world"), new_excel_string("HELLO")).number == true);
88
+ assert(not_equal(new_excel_string("1"), ONE).number == true);
89
+ assert(not_equal(DIV0, ONE).type == ExcelError);
90
+
91
+ // Test excel_if
92
+ // Two argument version
93
+ assert(excel_if_2(TRUE,new_excel_number(10)).type == ExcelNumber);
94
+ assert(excel_if_2(TRUE,new_excel_number(10)).number == 10);
95
+ assert(excel_if_2(FALSE,new_excel_number(10)).type == ExcelBoolean);
96
+ assert(excel_if_2(FALSE,new_excel_number(10)).number == false);
97
+ assert(excel_if_2(NA,new_excel_number(10)).type == ExcelError);
98
+ // Three argument version
99
+ assert(excel_if(TRUE,new_excel_number(10),new_excel_number(20)).type == ExcelNumber);
100
+ assert(excel_if(TRUE,new_excel_number(10),new_excel_number(20)).number == 10);
101
+ assert(excel_if(FALSE,new_excel_number(10),new_excel_number(20)).type == ExcelNumber);
102
+ assert(excel_if(FALSE,new_excel_number(10),new_excel_number(20)).number == 20);
103
+ assert(excel_if(NA,new_excel_number(10),new_excel_number(20)).type == ExcelError);
104
+ assert(excel_if(TRUE,new_excel_number(10),NA).type == ExcelNumber);
105
+ assert(excel_if(TRUE,new_excel_number(10),NA).number == 10);
106
+
107
+ // Test excel_match
108
+ ExcelValue excel_match_array_1[] = { new_excel_number(10), new_excel_number(100) };
109
+ ExcelValue excel_match_array_1_v = new_excel_range(excel_match_array_1,1,2);
110
+ ExcelValue excel_match_array_2[] = { new_excel_string("Pear"), new_excel_string("Bear"), new_excel_string("Apple") };
111
+ ExcelValue excel_match_array_2_v = new_excel_range(excel_match_array_2,3,1);
112
+ ExcelValue excel_match_array_4[] = { ONE, BLANK, new_excel_number(0) };
113
+ ExcelValue excel_match_array_4_v = new_excel_range(excel_match_array_4,1,3);
114
+ ExcelValue excel_match_array_5[] = { ONE, new_excel_number(0), BLANK };
115
+ ExcelValue excel_match_array_5_v = new_excel_range(excel_match_array_5,1,3);
116
+
117
+ // Two argument version
118
+ assert(excel_match_2(new_excel_number(10),excel_match_array_1_v).number == 1);
119
+ assert(excel_match_2(new_excel_number(100),excel_match_array_1_v).number == 2);
120
+ assert(excel_match_2(new_excel_number(1000),excel_match_array_1_v).type == ExcelError);
121
+ assert(excel_match_2(new_excel_number(0), excel_match_array_4_v).number == 2);
122
+ assert(excel_match_2(BLANK, excel_match_array_5_v).number == 2);
123
+
124
+ // Three argument version
125
+ assert(excel_match(new_excel_number(10.0), excel_match_array_1_v, new_excel_number(0) ).number == 1);
126
+ assert(excel_match(new_excel_number(100.0), excel_match_array_1_v, new_excel_number(0) ).number == 2);
127
+ assert(excel_match(new_excel_number(1000.0), excel_match_array_1_v, new_excel_number(0) ).type == ExcelError);
128
+ assert(excel_match(new_excel_string("bEAr"), excel_match_array_2_v, new_excel_number(0) ).number == 2);
129
+ assert(excel_match(new_excel_number(1000.0), excel_match_array_1_v, ONE ).number == 2);
130
+ assert(excel_match(new_excel_number(1.0), excel_match_array_1_v, ONE ).type == ExcelError);
131
+ assert(excel_match(new_excel_string("Care"), excel_match_array_2_v, new_excel_number(-1) ).number == 1 );
132
+ assert(excel_match(new_excel_string("Zebra"), excel_match_array_2_v, new_excel_number(-1) ).type == ExcelError);
133
+ assert(excel_match(new_excel_string("a"), excel_match_array_2_v, new_excel_number(-1) ).number == 2);
134
+
135
+ // When not given a range
136
+ assert(excel_match(new_excel_number(10.0), new_excel_number(10), new_excel_number(0.0)).number == 1);
137
+ assert(excel_match(new_excel_number(20.0), new_excel_number(10), new_excel_number(0.0)).type == ExcelError);
138
+ assert(excel_match(new_excel_number(10.0), excel_match_array_1_v, BLANK).number == 1);
139
+
140
+ // Test more than on
141
+ // .. numbers
142
+ assert(more_than(ONE,new_excel_number(2)).number == false);
143
+ assert(more_than(ONE,ONE).number == false);
144
+ assert(more_than(ONE,new_excel_number(0)).number == true);
145
+ // .. booleans
146
+ assert(more_than(FALSE,FALSE).number == false);
147
+ assert(more_than(FALSE,TRUE).number == false);
148
+ assert(more_than(TRUE,FALSE).number == true);
149
+ assert(more_than(TRUE,TRUE).number == false);
150
+ // ..strings
151
+ assert(more_than(new_excel_string("HELLO"),new_excel_string("Ardvark")).number == true);
152
+ assert(more_than(new_excel_string("HELLO"),new_excel_string("world")).number == false);
153
+ assert(more_than(new_excel_string("HELLO"),new_excel_string("hello")).number == false);
154
+ // ..blanks
155
+ assert(more_than(BLANK,ONE).number == false);
156
+ assert(more_than(BLANK,new_excel_number(-1)).number == true);
157
+ assert(more_than(ONE,BLANK).number == true);
158
+ assert(more_than(new_excel_number(-1),BLANK).number == false);
159
+
160
+ // Test less than on
161
+ // .. numbers
162
+ assert(less_than(ONE,new_excel_number(2)).number == true);
163
+ assert(less_than(ONE,ONE).number == false);
164
+ assert(less_than(ONE,new_excel_number(0)).number == false);
165
+ // .. booleans
166
+ assert(less_than(FALSE,FALSE).number == false);
167
+ assert(less_than(FALSE,TRUE).number == true);
168
+ assert(less_than(TRUE,FALSE).number == false);
169
+ assert(less_than(TRUE,TRUE).number == false);
170
+ // ..strings
171
+ assert(less_than(new_excel_string("HELLO"),new_excel_string("Ardvark")).number == false);
172
+ assert(less_than(new_excel_string("HELLO"),new_excel_string("world")).number == true);
173
+ assert(less_than(new_excel_string("HELLO"),new_excel_string("hello")).number == false);
174
+ // ..blanks
175
+ assert(less_than(BLANK,ONE).number == true);
176
+ assert(less_than(BLANK,new_excel_number(-1)).number == false);
177
+ assert(less_than(ONE,BLANK).number == false);
178
+ assert(less_than(new_excel_number(-1),BLANK).number == true);
179
+
180
+ // Test FIND function
181
+ // ... should find the first occurrence of one string in another, returning :value if the string doesn't match
182
+ assert(find_2(new_excel_string("one"),new_excel_string("onetwothree")).number == 1);
183
+ assert(find_2(new_excel_string("one"),new_excel_string("twoonethree")).number == 4);
184
+ assert(find_2(new_excel_string("one"),new_excel_string("twoonthree")).type == ExcelError);
185
+ // ... should find the first occurrence of one string in another after a given index, returning :value if the string doesn't match
186
+ assert(find(new_excel_string("one"),new_excel_string("onetwothree"),ONE).number == 1);
187
+ assert(find(new_excel_string("one"),new_excel_string("twoonethree"),new_excel_number(5)).type == ExcelError);
188
+ assert(find(new_excel_string("one"),new_excel_string("oneone"),new_excel_number(2)).number == 4);
189
+ // ... should be possible for the start_num to be a string, if that string converts to a number
190
+ assert(find(new_excel_string("one"),new_excel_string("oneone"),new_excel_string("2")).number == 4);
191
+ // ... should return a :value error when given anything but a number as the third argument
192
+ assert(find(new_excel_string("one"),new_excel_string("oneone"),new_excel_string("a")).type == ExcelError);
193
+ // ... should return a :value error when given a third argument that is less than 1 or greater than the length of the string
194
+ assert(find(new_excel_string("one"),new_excel_string("oneone"),new_excel_number(0)).type == ExcelError);
195
+ assert(find(new_excel_string("one"),new_excel_string("oneone"),new_excel_number(-1)).type == ExcelError);
196
+ assert(find(new_excel_string("one"),new_excel_string("oneone"),new_excel_number(7)).type == ExcelError);
197
+ // ... BLANK in the first argument matches any character
198
+ assert(find_2(BLANK,new_excel_string("abcdefg")).number == 1);
199
+ assert(find(BLANK,new_excel_string("abcdefg"),new_excel_number(4)).number == 4);
200
+ // ... should treat BLANK in the second argument as an empty string
201
+ assert(find_2(BLANK,BLANK).number == 1);
202
+ assert(find_2(new_excel_string("a"),BLANK).type == ExcelError);
203
+ // ... should return an error if any argument is an error
204
+ assert(find(new_excel_string("one"),new_excel_string("onetwothree"),NA).type == ExcelError);
205
+ assert(find(new_excel_string("one"),NA,ONE).type == ExcelError);
206
+ assert(find(NA,new_excel_string("onetwothree"),ONE).type == ExcelError);
207
+
208
+ // Test the IFERROR function
209
+ assert(iferror(new_excel_string("ok"),ONE).type == ExcelString);
210
+ assert(iferror(VALUE,ONE).type == ExcelNumber);
211
+
212
+ // Test the INDEX function
213
+ ExcelValue index_array_1[] = { new_excel_number(10), new_excel_number(20), BLANK };
214
+ ExcelValue index_array_1_v_column = new_excel_range(index_array_1,3,1);
215
+ ExcelValue index_array_1_v_row = new_excel_range(index_array_1,1,3);
216
+ ExcelValue index_array_2[] = { BLANK, ONE, new_excel_number(10), new_excel_number(11), new_excel_number(100), new_excel_number(101) };
217
+ ExcelValue index_array_2_v = new_excel_range(index_array_2,3,2);
218
+ // ... if given one argument should return the value at that offset in the range
219
+ assert(excel_index_2(index_array_1_v_column,new_excel_number(2.0)).number == 20);
220
+ assert(excel_index_2(index_array_1_v_row,new_excel_number(2.0)).number == 20);
221
+ // ... but not if the range is not a single row or single column
222
+ assert(excel_index_2(index_array_2_v,new_excel_number(2.0)).type == ExcelError);
223
+ // ... it should return the value in the array at position row_number, column_number
224
+ assert(excel_index(new_excel_number(10),ONE,ONE).number == 10);
225
+ assert(excel_index(index_array_2_v,new_excel_number(1.0),new_excel_number(2.0)).number == 1);
226
+ assert(excel_index(index_array_2_v,new_excel_number(2.0),new_excel_number(1.0)).number == 10);
227
+ assert(excel_index(index_array_2_v,new_excel_number(3.0),new_excel_number(1.0)).number == 100);
228
+ assert(excel_index(index_array_2_v,new_excel_number(3.0),new_excel_number(3.0)).type == ExcelError);
229
+ // ... it should return ZERO not blank, if a blank cell is picked
230
+ assert(excel_index(index_array_2_v,new_excel_number(1.0),new_excel_number(1.0)).type == ExcelNumber);
231
+ assert(excel_index(index_array_2_v,new_excel_number(1.0),new_excel_number(1.0)).number == 0);
232
+ assert(excel_index_2(index_array_1_v_row,new_excel_number(3.0)).type == ExcelNumber);
233
+ assert(excel_index_2(index_array_1_v_row,new_excel_number(3.0)).number == 0);
234
+ // ... it should return the whole row if given a zero column number
235
+ ExcelValue index_result_1_v = excel_index(index_array_2_v,new_excel_number(1.0),new_excel_number(0.0));
236
+ assert(index_result_1_v.type == ExcelRange);
237
+ assert(index_result_1_v.rows == 1);
238
+ assert(index_result_1_v.columns == 2);
239
+ ExcelValue *index_result_1_a = index_result_1_v.array;
240
+ assert(index_result_1_a[0].number == 0);
241
+ assert(index_result_1_a[1].number == 1);
242
+ // ... it should return the whole column if given a zero row number
243
+ ExcelValue index_result_2_v = excel_index(index_array_2_v,new_excel_number(0),new_excel_number(1.0));
244
+ assert(index_result_2_v.type == ExcelRange);
245
+ assert(index_result_2_v.rows == 3);
246
+ assert(index_result_2_v.columns == 1);
247
+ ExcelValue *index_result_2_a = index_result_2_v.array;
248
+ assert(index_result_2_a[0].number == 0);
249
+ assert(index_result_2_a[1].number == 10);
250
+ assert(index_result_2_a[2].number == 100);
251
+ // ... it should return a :ref error when given arguments outside array range
252
+ assert(excel_index_2(index_array_1_v_row,new_excel_number(-1)).type == ExcelError);
253
+ assert(excel_index_2(index_array_1_v_row,new_excel_number(4)).type == ExcelError);
254
+ // ... it should treat BLANK as zero if given as a required row or column number
255
+ assert(excel_index(index_array_2_v,new_excel_number(1.0),BLANK).type == ExcelRange);
256
+ assert(excel_index(index_array_2_v,BLANK,new_excel_number(2.0)).type == ExcelRange);
257
+ // ... it should return an error if an argument is an error
258
+ assert(excel_index(NA,NA,NA).type == ExcelError);
259
+
260
+ // LEFT(string,[characters])
261
+ // ... should return the left n characters from a string
262
+ assert(strcmp(left_1(new_excel_string("ONE")).string,"O") == 0);
263
+ assert(strcmp(left(new_excel_string("ONE"),ONE).string,"O") == 0);
264
+ assert(strcmp(left(new_excel_string("ONE"),new_excel_number(3)).string,"ONE") == 0);
265
+ // ... should turn numbers into strings before processing
266
+ assert(strcmp(left(new_excel_number(1.31e12),new_excel_number(3)).string, "131") == 0);
267
+ // ... should turn booleans into the words TRUE and FALSE before processing
268
+ assert(strcmp(left(TRUE,new_excel_number(3)).string,"TRU") == 0);
269
+ assert(strcmp(left(FALSE,new_excel_number(3)).string,"FAL") == 0);
270
+ // ... should return BLANK if given BLANK for either argument
271
+ assert(left(BLANK,new_excel_number(3)).type == ExcelEmpty);
272
+ assert(left(new_excel_string("ONE"),BLANK).type == ExcelEmpty);
273
+ // ... should return an error if an argument is an error
274
+ assert(left_1(NA).type == ExcelError);
275
+ assert(left(new_excel_string("ONE"),NA).type == ExcelError);
276
+
277
+ // Test less than or equal to
278
+ // .. numbers
279
+ assert(less_than_or_equal(ONE,new_excel_number(2)).number == true);
280
+ assert(less_than_or_equal(ONE,ONE).number == true);
281
+ assert(less_than_or_equal(ONE,new_excel_number(0)).number == false);
282
+ // .. booleans
283
+ assert(less_than_or_equal(FALSE,FALSE).number == true);
284
+ assert(less_than_or_equal(FALSE,TRUE).number == true);
285
+ assert(less_than_or_equal(TRUE,FALSE).number == false);
286
+ assert(less_than_or_equal(TRUE,TRUE).number == true);
287
+ // ..strings
288
+ assert(less_than_or_equal(new_excel_string("HELLO"),new_excel_string("Ardvark")).number == false);
289
+ assert(less_than_or_equal(new_excel_string("HELLO"),new_excel_string("world")).number == true);
290
+ assert(less_than_or_equal(new_excel_string("HELLO"),new_excel_string("hello")).number == true);
291
+ // ..blanks
292
+ assert(less_than_or_equal(BLANK,ONE).number == true);
293
+ assert(less_than_or_equal(BLANK,new_excel_number(-1)).number == false);
294
+ assert(less_than_or_equal(ONE,BLANK).number == false);
295
+ assert(less_than_or_equal(new_excel_number(-1),BLANK).number == true);
296
+
297
+ // Test MAX
298
+ assert(max(4, array1).number == 10);
299
+ assert(max(3, array2).number == 10);
300
+ assert(max(4, array3).type == ExcelError);
301
+
302
+ // Test MIN
303
+ assert(min(4, array1).number == 5);
304
+ assert(min(3, array2).number == 5);
305
+ assert(min(4, array3).type == ExcelError);
306
+
307
+ // Test MOD
308
+ // ... should return the remainder of a number
309
+ assert(mod(new_excel_number(10), new_excel_number(3)).number == 1.0);
310
+ assert(mod(new_excel_number(10), new_excel_number(5)).number == 0.0);
311
+ // ... should be possible for the the arguments to be strings, if they convert to a number
312
+ assert(mod(new_excel_string("3.5"),new_excel_string("2")).number == 1.5);
313
+ // ... should treat BLANK as zero
314
+ assert(mod(BLANK,new_excel_number(10)).number == 0);
315
+ assert(mod(new_excel_number(10),BLANK).type == ExcelError);
316
+ assert(mod(BLANK,BLANK).type == ExcelError);
317
+ // ... should treat true as 1 and FALSE as 0
318
+ assert((mod(new_excel_number(1.1),TRUE).number - 0.1) < 0.001);
319
+ assert(mod(new_excel_number(1.1),FALSE).type == ExcelError);
320
+ assert(mod(FALSE,new_excel_number(10)).number == 0);
321
+ // ... should return an error when given inappropriate arguments
322
+ assert(mod(new_excel_string("Asdasddf"),new_excel_string("adsfads")).type == ExcelError);
323
+ // ... should return an error if an argument is an error
324
+ assert(mod(new_excel_number(1),VALUE).type == ExcelError);
325
+ assert(mod(VALUE,new_excel_number(1)).type == ExcelError);
326
+ assert(mod(VALUE,VALUE).type == ExcelError);
327
+
328
+ // Test more than or equal to on
329
+ // .. numbers
330
+ assert(more_than_or_equal(ONE,new_excel_number(2)).number == false);
331
+ assert(more_than_or_equal(ONE,ONE).number == true);
332
+ assert(more_than_or_equal(ONE,new_excel_number(0)).number == true);
333
+ // .. booleans
334
+ assert(more_than_or_equal(FALSE,FALSE).number == true);
335
+ assert(more_than_or_equal(FALSE,TRUE).number == false);
336
+ assert(more_than_or_equal(TRUE,FALSE).number == true);
337
+ assert(more_than_or_equal(TRUE,TRUE).number == true);
338
+ // ..strings
339
+ assert(more_than_or_equal(new_excel_string("HELLO"),new_excel_string("Ardvark")).number == true);
340
+ assert(more_than_or_equal(new_excel_string("HELLO"),new_excel_string("world")).number == false);
341
+ assert(more_than_or_equal(new_excel_string("HELLO"),new_excel_string("hello")).number == true);
342
+ // ..blanks
343
+ assert(more_than_or_equal(BLANK,BLANK).number == true);
344
+ assert(more_than_or_equal(BLANK,ONE).number == false);
345
+ assert(more_than_or_equal(BLANK,new_excel_number(-1)).number == true);
346
+ assert(more_than_or_equal(ONE,BLANK).number == true);
347
+ assert(more_than_or_equal(new_excel_number(-1),BLANK).number == false);
348
+
349
+ // Test negative
350
+ // ... should return the negative of its arguments
351
+ assert(negative(new_excel_number(1)).number == -1);
352
+ assert(negative(new_excel_number(-1)).number == 1);
353
+ // ... should treat strings that only contain numbers as numbers
354
+ assert(negative(new_excel_string("10")).number == -10);
355
+ assert(negative(new_excel_string("-1.3")).number == 1.3);
356
+ // ... should return an error when given inappropriate arguments
357
+ assert(negative(new_excel_string("Asdasddf")).type == ExcelError);
358
+ // ... should treat BLANK as zero
359
+ assert(negative(BLANK).number == 0);
360
+
361
+ // Test PMT(rate,number_of_periods,present_value) - optional arguments not yet implemented
362
+ // ... should calculate the monthly payment required for a given principal, interest rate and loan period
363
+ assert((pmt(new_excel_number(0.1),new_excel_number(10),new_excel_number(100)).number - -16.27) < 0.01);
364
+ assert((pmt(new_excel_number(0.0123),new_excel_number(99.1),new_excel_number(123.32)).number - -2.159) < 0.01);
365
+ assert((pmt(new_excel_number(0),new_excel_number(2),new_excel_number(10)).number - -5) < 0.01);
366
+
367
+ // Test power
368
+ // ... should return power of its arguments
369
+ assert(power(new_excel_number(2),new_excel_number(3)).number == 8);
370
+ assert(power(new_excel_number(4.0),new_excel_number(0.5)).number == 2.0);
371
+ assert(power(new_excel_number(-4.0),new_excel_number(0.5)).type == ExcelError);
372
+
373
+ // Test round
374
+ assert(excel_round(new_excel_number(1.1), new_excel_number(0)).number == 1.0);
375
+ assert(excel_round(new_excel_number(1.5), new_excel_number(0)).number == 2.0);
376
+ assert(excel_round(new_excel_number(1.56),new_excel_number(1)).number == 1.6);
377
+ assert(excel_round(new_excel_number(-1.56),new_excel_number(1)).number == -1.6);
378
+
379
+ // Test rounddown
380
+ assert(rounddown(new_excel_number(1.1), new_excel_number(0)).number == 1.0);
381
+ assert(rounddown(new_excel_number(1.5), new_excel_number(0)).number == 1.0);
382
+ assert(rounddown(new_excel_number(1.56),new_excel_number(1)).number == 1.5);
383
+ assert(rounddown(new_excel_number(-1.56),new_excel_number(1)).number == -1.5);
384
+
385
+ // Test int
386
+ assert(excel_int(new_excel_number(8.9)).number == 8.0);
387
+ assert(excel_int(new_excel_number(-8.9)).number == -9.0);
388
+
389
+ // Test roundup
390
+ assert(roundup(new_excel_number(1.1), new_excel_number(0)).number == 2.0);
391
+ assert(roundup(new_excel_number(1.5), new_excel_number(0)).number == 2.0);
392
+ assert(roundup(new_excel_number(1.56),new_excel_number(1)).number == 1.6);
393
+ assert(roundup(new_excel_number(-1.56),new_excel_number(1)).number == -1.6);
394
+
395
+ // Test string joining
396
+ ExcelValue string_join_array_1[] = {new_excel_string("Hello "), new_excel_string("world")};
397
+ ExcelValue string_join_array_2[] = {new_excel_string("Hello "), new_excel_string("world"), new_excel_string("!")};
398
+ ExcelValue string_join_array_3[] = {new_excel_string("Top "), new_excel_number(10.0)};
399
+ ExcelValue string_join_array_4[] = {new_excel_string("Top "), new_excel_number(10.5)};
400
+ ExcelValue string_join_array_5[] = {new_excel_string("Top "), TRUE, FALSE};
401
+ // ... should return a string by combining its arguments
402
+ // inspect_excel_value(string_join(2, string_join_array_1));
403
+ assert(string_join(2, string_join_array_1).string[6] == 'w');
404
+ assert(string_join(2, string_join_array_1).string[11] == '\0');
405
+ // ... should cope with an arbitrary number of arguments
406
+ assert(string_join(3, string_join_array_2).string[11] == '!');
407
+ assert(string_join(3, string_join_array_3).string[12] == '\0');
408
+ // ... should convert values to strings as it goes
409
+ assert(string_join(2, string_join_array_3).string[4] == '1');
410
+ assert(string_join(2, string_join_array_3).string[5] == '0');
411
+ assert(string_join(2, string_join_array_3).string[6] == '\0');
412
+ // ... should convert integer values into strings without decimal points, and float values with decimal points
413
+ assert(string_join(2, string_join_array_4).string[4] == '1');
414
+ assert(string_join(2, string_join_array_4).string[5] == '0');
415
+ assert(string_join(2, string_join_array_4).string[6] == '.');
416
+ assert(string_join(2, string_join_array_4).string[7] == '5');
417
+ assert(string_join(2, string_join_array_4).string[8] == '\0');
418
+ // ... should convert TRUE and FALSE into strings
419
+ assert(string_join(3,string_join_array_5).string[4] == 'T');
420
+ // Should deal with very long string joins
421
+ ExcelValue string_join_array_6[] = {new_excel_string("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"), new_excel_string("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789")};
422
+ assert(string_join(2, string_join_array_6).string[0] == '0');
423
+ free_all_allocated_memory();
424
+
425
+ // Test SUBTOTAL function
426
+ ExcelValue subtotal_array_1[] = {new_excel_number(10),new_excel_number(100),BLANK};
427
+ ExcelValue subtotal_array_1_v = new_excel_range(subtotal_array_1,3,1);
428
+ ExcelValue subtotal_array_2[] = {new_excel_number(1),new_excel_string("two"),subtotal_array_1_v};
429
+
430
+ // new_excel_number(1.0);
431
+ // inspect_excel_value(new_excel_number(1.0));
432
+ // inspect_excel_value(new_excel_range(subtotal_array_2,3,1));
433
+ // inspect_excel_value(subtotal(new_excel_number(1.0),3,subtotal_array_2));
434
+
435
+ assert(subtotal(new_excel_number(1.0),3,subtotal_array_2).number == 111.0/3.0);
436
+ assert(subtotal(new_excel_number(2.0),3,subtotal_array_2).number == 3);
437
+ assert(subtotal(new_excel_number(3.0),7, count_a_test_array_1).number == 6);
438
+ assert(subtotal(new_excel_number(3.0),3,subtotal_array_2).number == 4);
439
+ assert(subtotal(new_excel_number(9.0),3,subtotal_array_2).number == 111);
440
+ assert(subtotal(new_excel_number(101.0),3,subtotal_array_2).number == 111.0/3.0);
441
+ assert(subtotal(new_excel_number(102.0),3,subtotal_array_2).number == 3);
442
+ assert(subtotal(new_excel_number(103.0),3,subtotal_array_2).number == 4);
443
+ assert(subtotal(new_excel_number(109.0),3,subtotal_array_2).number == 111);
444
+
445
+ // Test SUMIFS function
446
+ ExcelValue sumifs_array_1[] = {new_excel_number(10),new_excel_number(100),BLANK};
447
+ ExcelValue sumifs_array_1_v = new_excel_range(sumifs_array_1,3,1);
448
+ ExcelValue sumifs_array_2[] = {new_excel_string("pear"),new_excel_string("bear"),new_excel_string("apple")};
449
+ ExcelValue sumifs_array_2_v = new_excel_range(sumifs_array_2,3,1);
450
+ ExcelValue sumifs_array_3[] = {new_excel_number(1),new_excel_number(2),new_excel_number(3),new_excel_number(4),new_excel_number(5),new_excel_number(5)};
451
+ ExcelValue sumifs_array_3_v = new_excel_range(sumifs_array_3,6,1);
452
+ ExcelValue sumifs_array_4[] = {new_excel_string("CO2"),new_excel_string("CH4"),new_excel_string("N2O"),new_excel_string("CH4"),new_excel_string("N2O"),new_excel_string("CO2")};
453
+ ExcelValue sumifs_array_4_v = new_excel_range(sumifs_array_4,6,1);
454
+ ExcelValue sumifs_array_5[] = {new_excel_string("1A"),new_excel_string("1A"),new_excel_string("1A"),new_excel_number(4),new_excel_number(4),new_excel_number(5)};
455
+ ExcelValue sumifs_array_5_v = new_excel_range(sumifs_array_5,6,1);
456
+
457
+ // ... should only sum values that meet all of the criteria
458
+ ExcelValue sumifs_array_6[] = { sumifs_array_1_v, new_excel_number(10), sumifs_array_2_v, new_excel_string("Bear") };
459
+ assert(sumifs(sumifs_array_1_v,4,sumifs_array_6).number == 0.0);
460
+
461
+ ExcelValue sumifs_array_7[] = { sumifs_array_1_v, new_excel_number(10), sumifs_array_2_v, new_excel_string("Pear") };
462
+ assert(sumifs(sumifs_array_1_v,4,sumifs_array_7).number == 10.0);
463
+
464
+ // ... should work when single cells are given where ranges expected
465
+ ExcelValue sumifs_array_8[] = { new_excel_string("CAR"), new_excel_string("CAR"), new_excel_string("FCV"), new_excel_string("FCV")};
466
+ assert(sumifs(new_excel_number(0.143897265452564), 4, sumifs_array_8).number == 0.143897265452564);
467
+
468
+ // ... should match numbers with strings that contain numbers
469
+ ExcelValue sumifs_array_9[] = { new_excel_number(10), new_excel_string("10.0")};
470
+ assert(sumifs(new_excel_number(100),2,sumifs_array_9).number == 100);
471
+
472
+ ExcelValue sumifs_array_10[] = { sumifs_array_4_v, new_excel_string("CO2"), sumifs_array_5_v, new_excel_number(2)};
473
+ assert(sumifs(sumifs_array_3_v,4, sumifs_array_10).number == 0);
474
+
475
+ // ... should match with strings that contain criteria
476
+ ExcelValue sumifs_array_10a[] = { sumifs_array_3_v, new_excel_string("=5")};
477
+ assert(sumifs(sumifs_array_3_v,2, sumifs_array_10a).number == 10);
478
+
479
+ ExcelValue sumifs_array_10b[] = { sumifs_array_3_v, new_excel_string("<>3")};
480
+ assert(sumifs(sumifs_array_3_v,2, sumifs_array_10b).number == 17);
481
+
482
+ ExcelValue sumifs_array_10c[] = { sumifs_array_3_v, new_excel_string("<3")};
483
+ assert(sumifs(sumifs_array_3_v,2, sumifs_array_10c).number == 3);
484
+
485
+ ExcelValue sumifs_array_10d[] = { sumifs_array_3_v, new_excel_string("<=3")};
486
+ assert(sumifs(sumifs_array_3_v,2, sumifs_array_10d).number == 6);
487
+
488
+ ExcelValue sumifs_array_10e[] = { sumifs_array_3_v, new_excel_string(">3")};
489
+ assert(sumifs(sumifs_array_3_v,2, sumifs_array_10e).number == 14);
490
+
491
+ ExcelValue sumifs_array_10f[] = { sumifs_array_3_v, new_excel_string(">=3")};
492
+ assert(sumifs(sumifs_array_3_v,2, sumifs_array_10f).number == 17);
493
+
494
+ // ... should treat BLANK as an empty string when in the check_range, but not in the criteria
495
+ ExcelValue sumifs_array_11[] = { BLANK, new_excel_number(20)};
496
+ assert(sumifs(new_excel_number(100),2,sumifs_array_11).number == 0);
497
+
498
+ ExcelValue sumifs_array_12[] = {BLANK, new_excel_string("")};
499
+ assert(sumifs(new_excel_number(100),2,sumifs_array_12).number == 100);
500
+
501
+ ExcelValue sumifs_array_13[] = {BLANK, BLANK};
502
+ assert(sumifs(new_excel_number(100),2,sumifs_array_13).number == 0);
503
+
504
+ // ... should return an error if range argument is an error
505
+ assert(sumifs(REF,2,sumifs_array_13).type == ExcelError);
506
+
507
+
508
+ // Test SUMIF
509
+ // ... where there is only a check range
510
+ assert(sumif_2(sumifs_array_1_v,new_excel_string(">0")).number == 110.0);
511
+ assert(sumif_2(sumifs_array_1_v,new_excel_string(">10")).number == 100.0);
512
+ assert(sumif_2(sumifs_array_1_v,new_excel_string("<100")).number == 10.0);
513
+
514
+ // ... where there is a seprate sum range
515
+ ExcelValue sumif_array_1[] = {new_excel_number(15),new_excel_number(20), new_excel_number(30)};
516
+ ExcelValue sumif_array_1_v = new_excel_range(sumif_array_1,3,1);
517
+ assert(sumif(sumifs_array_1_v,new_excel_string("10"),sumif_array_1_v).number == 15);
518
+
519
+
520
+ // Test SUMPRODUCT
521
+ ExcelValue sumproduct_1[] = { new_excel_number(10), new_excel_number(100), BLANK};
522
+ ExcelValue sumproduct_2[] = { BLANK, new_excel_number(100), new_excel_number(10), BLANK};
523
+ ExcelValue sumproduct_3[] = { BLANK };
524
+ ExcelValue sumproduct_4[] = { new_excel_number(10), new_excel_number(100), new_excel_number(1000)};
525
+ ExcelValue sumproduct_5[] = { new_excel_number(1), new_excel_number(2), new_excel_number(3)};
526
+ ExcelValue sumproduct_6[] = { new_excel_number(1), new_excel_number(2), new_excel_number(4), new_excel_number(5)};
527
+ ExcelValue sumproduct_7[] = { new_excel_number(10), new_excel_number(20), new_excel_number(40), new_excel_number(50)};
528
+ ExcelValue sumproduct_8[] = { new_excel_number(11), new_excel_number(21), new_excel_number(41), new_excel_number(51)};
529
+ ExcelValue sumproduct_9[] = { BLANK, BLANK };
530
+
531
+ ExcelValue sumproduct_1_v = new_excel_range( sumproduct_1, 3, 1);
532
+ ExcelValue sumproduct_2_v = new_excel_range( sumproduct_2, 3, 1);
533
+ ExcelValue sumproduct_3_v = new_excel_range( sumproduct_3, 1, 1);
534
+ // ExcelValue sumproduct_4_v = new_excel_range( sumproduct_4, 1, 3); // Unused
535
+ ExcelValue sumproduct_5_v = new_excel_range( sumproduct_5, 3, 1);
536
+ ExcelValue sumproduct_6_v = new_excel_range( sumproduct_6, 2, 2);
537
+ ExcelValue sumproduct_7_v = new_excel_range( sumproduct_7, 2, 2);
538
+ ExcelValue sumproduct_8_v = new_excel_range( sumproduct_8, 2, 2);
539
+ ExcelValue sumproduct_9_v = new_excel_range( sumproduct_9, 2, 1);
540
+
541
+ // ... should multiply together and then sum the elements in row or column areas given as arguments
542
+ ExcelValue sumproducta_1[] = {sumproduct_1_v, sumproduct_2_v};
543
+ assert(sumproduct(2,sumproducta_1).number == 100*100);
544
+
545
+ // ... should return :value when miss-matched array sizes
546
+ ExcelValue sumproducta_2[] = {sumproduct_1_v, sumproduct_3_v};
547
+ assert(sumproduct(2,sumproducta_2).type == ExcelError);
548
+
549
+ // ... if all its arguments are single values, should multiply them together
550
+ // ExcelValue *sumproducta_3 = sumproduct_4;
551
+ assert(sumproduct(3,sumproduct_4).number == 10*100*1000);
552
+
553
+ // ... if it only has one range as an argument, should add its elements together
554
+ ExcelValue sumproducta_4[] = {sumproduct_5_v};
555
+ assert(sumproduct(1,sumproducta_4).number == 1 + 2 + 3);
556
+
557
+ // ... if given multi row and column areas as arguments, should multipy the corresponding cell in each area and then add them all
558
+ ExcelValue sumproducta_5[] = {sumproduct_6_v, sumproduct_7_v, sumproduct_8_v};
559
+ assert(sumproduct(3,sumproducta_5).number == 1*10*11 + 2*20*21 + 4*40*41 + 5*50*51);
560
+
561
+ // ... should raise an error if BLANK values outside of an array
562
+ ExcelValue sumproducta_6[] = {BLANK,new_excel_number(1)};
563
+ assert(sumproduct(2,sumproducta_6).type == ExcelError);
564
+
565
+ // ... should ignore non-numeric values within an array
566
+ ExcelValue sumproducta_7[] = {sumproduct_9_v, sumproduct_9_v};
567
+ assert(sumproduct(2,sumproducta_7).number == 0);
568
+
569
+ // ... should return an error if an argument is an error
570
+ ExcelValue sumproducta_8[] = {VALUE};
571
+ assert(sumproduct(1,sumproducta_8).type == ExcelError);
572
+
573
+ // Test VLOOKUP
574
+ ExcelValue vlookup_a1[] = {new_excel_number(1),new_excel_number(10),new_excel_number(2),new_excel_number(20),new_excel_number(3),new_excel_number(30)};
575
+ ExcelValue vlookup_a2[] = {new_excel_string("hello"),new_excel_number(10),new_excel_number(2),new_excel_number(20),new_excel_number(3),new_excel_number(30)};
576
+ ExcelValue vlookup_a3[] = {BLANK,new_excel_number(10),new_excel_number(2),new_excel_number(20),new_excel_number(3),new_excel_number(30)};
577
+ ExcelValue vlookup_a1_v = new_excel_range(vlookup_a1,3,2);
578
+ ExcelValue vlookup_a2_v = new_excel_range(vlookup_a2,3,2);
579
+ ExcelValue vlookup_a3_v = new_excel_range(vlookup_a3,3,2);
580
+ // ... should match the first argument against the first column of the table in the second argument, returning the value in the column specified by the third argument
581
+ assert(vlookup_3(new_excel_number(2.0),vlookup_a1_v,new_excel_number(2)).number == 20);
582
+ assert(vlookup_3(new_excel_number(1.5),vlookup_a1_v,new_excel_number(2)).number == 10);
583
+ assert(vlookup_3(new_excel_number(0.5),vlookup_a1_v,new_excel_number(2)).type == ExcelError);
584
+ assert(vlookup_3(new_excel_number(10),vlookup_a1_v,new_excel_number(2)).number == 30);
585
+ assert(vlookup_3(new_excel_number(2.6),vlookup_a1_v,new_excel_number(2)).number == 20);
586
+ // ... has a four argument variant that matches the lookup type
587
+ assert(vlookup(new_excel_number(2.6),vlookup_a1_v,new_excel_number(2),TRUE).number == 20);
588
+ assert(vlookup(new_excel_number(2.6),vlookup_a1_v,new_excel_number(2),FALSE).type == ExcelError);
589
+ assert(vlookup(new_excel_string("HELLO"),vlookup_a2_v,new_excel_number(2),FALSE).number == 10);
590
+ assert(vlookup(new_excel_string("HELMP"),vlookup_a2_v,new_excel_number(2),TRUE).number == 10);
591
+ // .. the four argument variant should accept 0 and 1 instead of TRUE and FALSE
592
+ assert(vlookup(new_excel_string("HELLO"),vlookup_a2_v,new_excel_number(2),ZERO).number == 10);
593
+ assert(vlookup(new_excel_string("HELMP"),vlookup_a2_v,new_excel_number(2),ONE).number == 10);
594
+ // ... BLANK should not match with anything" do
595
+ assert(vlookup_3(BLANK,vlookup_a3_v,new_excel_number(2)).type == ExcelError);
596
+ // ... should return an error if an argument is an error" do
597
+ assert(vlookup(VALUE,vlookup_a1_v,new_excel_number(2),FALSE).type == ExcelError);
598
+ assert(vlookup(new_excel_number(2.0),VALUE,new_excel_number(2),FALSE).type == ExcelError);
599
+ assert(vlookup(new_excel_number(2.0),vlookup_a1_v,VALUE,FALSE).type == ExcelError);
600
+ assert(vlookup(new_excel_number(2.0),vlookup_a1_v,new_excel_number(2),VALUE).type == ExcelError);
601
+ assert(vlookup(VALUE,VALUE,VALUE,VALUE).type == ExcelError);
602
+
603
+ // Test HLOOKUP
604
+ ExcelValue hlookup_a1[] = {new_excel_number(1),new_excel_number(2),new_excel_number(3),new_excel_number(10),new_excel_number(20),new_excel_number(30)};
605
+ ExcelValue hlookup_a2[] = {new_excel_string("hello"),new_excel_number(2),new_excel_number(3),new_excel_number(10),new_excel_number(20),new_excel_number(30)};
606
+ ExcelValue hlookup_a3[] = {BLANK,new_excel_number(2),new_excel_number(3),new_excel_number(10),new_excel_number(20),new_excel_number(30)};
607
+ ExcelValue hlookup_a1_v = new_excel_range(hlookup_a1,2,3);
608
+ ExcelValue hlookup_a2_v = new_excel_range(hlookup_a2,2,3);
609
+ ExcelValue hlookup_a3_v = new_excel_range(hlookup_a3,2,3);
610
+ // ... should match the first argument against the first column of the table in the second argument, returning the value in the column specified by the third argument
611
+ assert(hlookup_3(new_excel_number(2.0),hlookup_a1_v,new_excel_number(2)).number == 20);
612
+ assert(hlookup_3(new_excel_number(1.5),hlookup_a1_v,new_excel_number(2)).number == 10);
613
+ assert(hlookup_3(new_excel_number(0.5),hlookup_a1_v,new_excel_number(2)).type == ExcelError);
614
+ assert(hlookup_3(new_excel_number(10),hlookup_a1_v,new_excel_number(2)).number == 30);
615
+ assert(hlookup_3(new_excel_number(2.6),hlookup_a1_v,new_excel_number(2)).number == 20);
616
+ // ... has a four argument variant that matches the lookup type
617
+ assert(hlookup(new_excel_number(2.6),hlookup_a1_v,new_excel_number(2),TRUE).number == 20);
618
+ assert(hlookup(new_excel_number(2.6),hlookup_a1_v,new_excel_number(2),FALSE).type == ExcelError);
619
+ assert(hlookup(new_excel_string("HELLO"),hlookup_a2_v,new_excel_number(2),FALSE).number == 10);
620
+ assert(hlookup(new_excel_string("HELMP"),hlookup_a2_v,new_excel_number(2),TRUE).number == 10);
621
+ // ... that four argument variant should accept 0 or 1 for the lookup type
622
+ assert(hlookup(new_excel_number(2.6),hlookup_a1_v,new_excel_number(2),ONE).number == 20);
623
+ assert(hlookup(new_excel_number(2.6),hlookup_a1_v,new_excel_number(2),ZERO).type == ExcelError);
624
+ assert(hlookup(new_excel_string("HELLO"),hlookup_a2_v,new_excel_number(2),ZERO).number == 10);
625
+ assert(hlookup(new_excel_string("HELMP"),hlookup_a2_v,new_excel_number(2),ONE).number == 10);
626
+ // ... BLANK should not match with anything" do
627
+ assert(hlookup_3(BLANK,hlookup_a3_v,new_excel_number(2)).type == ExcelError);
628
+ // ... should return an error if an argument is an error" do
629
+ assert(hlookup(VALUE,hlookup_a1_v,new_excel_number(2),FALSE).type == ExcelError);
630
+ assert(hlookup(new_excel_number(2.0),VALUE,new_excel_number(2),FALSE).type == ExcelError);
631
+ assert(hlookup(new_excel_number(2.0),hlookup_a1_v,VALUE,FALSE).type == ExcelError);
632
+ assert(hlookup(new_excel_number(2.0),hlookup_a1_v,new_excel_number(2),VALUE).type == ExcelError);
633
+ assert(hlookup(VALUE,VALUE,VALUE,VALUE).type == ExcelError);
634
+
635
+ // Test SUM
636
+ ExcelValue sum_array_0[] = {new_excel_number(1084.4557258064517),new_excel_number(32.0516914516129),new_excel_number(137.36439193548387)};
637
+ ExcelValue sum_array_0_v = new_excel_range(sum_array_0,3,1);
638
+ ExcelValue sum_array_1[] = {sum_array_0_v};
639
+ assert(sum(1,sum_array_1).number == 1253.8718091935484);
640
+
641
+ // Test PV
642
+ assert((int) pv_3(new_excel_number(0.03), new_excel_number(12), new_excel_number(100)).number == -995);
643
+ assert((int) pv_4(new_excel_number(0.03), new_excel_number(12), new_excel_number(-100), new_excel_number(100)).number == 925);
644
+ assert((int) pv_5(new_excel_number(0.03), new_excel_number(12), new_excel_number(-100), new_excel_number(-100), new_excel_number(1)).number == 1095);
645
+
646
+ // Test TEXT
647
+ assert(strcmp(text(new_excel_number(1.0), new_excel_string("0%")).string, "100%") == 0);
648
+ assert(strcmp(text(new_excel_string("1"), new_excel_string("0%")).string, "100%") == 0);
649
+ assert(strcmp(text(BLANK, new_excel_string("0%")).string, "0%") == 0);
650
+ assert(strcmp(text(new_excel_number(1.0), BLANK).string, "") == 0);
651
+ assert(strcmp(text(new_excel_string("ASGASD"), new_excel_string("0%")).string, "ASGASD") == 0);
652
+
653
+ // Test LOG
654
+ // One argument variant assumes LOG base 10
655
+ assert(excel_log(new_excel_number(10)).number == 1);
656
+ assert(excel_log(new_excel_number(100)).number == 2);
657
+ assert(excel_log(new_excel_number(0)).type == ExcelError);
658
+ // Two argument variant allows LOG base to be specified
659
+ assert(excel_log_2(new_excel_number(8),new_excel_number(2)).number == 3.0);
660
+ assert(excel_log_2(new_excel_number(8),new_excel_number(0)).type == ExcelError);
661
+
662
+ // Test MMULT (Matrix multiplication)
663
+ ExcelValue mmult_1[] = { ONE, TWO, THREE, FOUR};
664
+ ExcelValue mmult_2[] = { FOUR, THREE, TWO, ONE};
665
+ ExcelValue mmult_3[] = { ONE, TWO};
666
+ ExcelValue mmult_4[] = { THREE, FOUR};
667
+ ExcelValue mmult_5[] = { ONE, BLANK, THREE, FOUR};
668
+
669
+ ExcelValue mmult_1_v = new_excel_range( mmult_1, 2, 2);
670
+ ExcelValue mmult_2_v = new_excel_range( mmult_2, 2, 2);
671
+ ExcelValue mmult_3_v = new_excel_range( mmult_3, 1, 2);
672
+ ExcelValue mmult_4_v = new_excel_range( mmult_4, 2, 1);
673
+ ExcelValue mmult_5_v = new_excel_range( mmult_5, 2, 2);
674
+
675
+ // Treat the ranges as matrices and multiply them
676
+ ExcelValue mmult_result_1_v = mmult(mmult_1_v, mmult_2_v);
677
+ assert(mmult_result_1_v.type == ExcelRange);
678
+ assert(mmult_result_1_v.rows == 2);
679
+ assert(mmult_result_1_v.columns == 2);
680
+ ExcelValue *mmult_result_1_a = mmult_result_1_v.array;
681
+ assert(mmult_result_1_a[0].number == 8);
682
+ assert(mmult_result_1_a[1].number == 5);
683
+ assert(mmult_result_1_a[2].number == 20);
684
+ assert(mmult_result_1_a[3].number == 13);
685
+
686
+ ExcelValue mmult_result_2_v = mmult(mmult_3_v, mmult_4_v);
687
+ assert(mmult_result_2_v.type == ExcelRange);
688
+ assert(mmult_result_2_v.rows == 1);
689
+ assert(mmult_result_2_v.columns == 1);
690
+ ExcelValue *mmult_result_2_a = mmult_result_2_v.array;
691
+ assert(mmult_result_2_a[0].number == 11);
692
+
693
+ // Return an error if any cells are not numbers
694
+ ExcelValue mmult_result_3_v = mmult(mmult_5_v, mmult_2_v);
695
+ assert(mmult_result_3_v.type == ExcelRange);
696
+ assert(mmult_result_3_v.rows == 2);
697
+ assert(mmult_result_3_v.columns == 2);
698
+ ExcelValue *mmult_result_3_a = mmult_result_3_v.array;
699
+ assert(mmult_result_3_a[0].type == ExcelError);
700
+ assert(mmult_result_3_a[1].type == ExcelError);
701
+ assert(mmult_result_3_a[2].type == ExcelError);
702
+ assert(mmult_result_3_a[3].type == ExcelError);
703
+
704
+ // Returns errors if arguments are not ranges
705
+ // FIXME: Should work in edge case where passed two numbers which excel treats as ranges with one row and column
706
+ ExcelValue mmult_result_4_v = mmult(ONE, mmult_2_v);
707
+ assert(mmult_result_4_v.type == ExcelError);
708
+
709
+ // Returns errors if the ranges aren't the right size to multiply
710
+ ExcelValue mmult_result_5_v = mmult(mmult_1_v, mmult_3_v);
711
+ assert(mmult_result_5_v.type == ExcelRange);
712
+ assert(mmult_result_5_v.rows == 2);
713
+ assert(mmult_result_5_v.columns == 2);
714
+ ExcelValue *mmult_result_5_a = mmult_result_5_v.array;
715
+ assert(mmult_result_5_a[0].type == ExcelError);
716
+ assert(mmult_result_5_a[1].type == ExcelError);
717
+ assert(mmult_result_5_a[2].type == ExcelError);
718
+ assert(mmult_result_5_a[3].type == ExcelError);
719
+
720
+ // Test the RANK() function
721
+ ExcelValue rank_1_a[] = { FIVE, BLANK, THREE, ONE, ONE, FOUR, FIVE, TRUE, SIX, new_excel_string("Hi")};
722
+ ExcelValue rank_2_a[] = { FIVE, BLANK, THREE, NA, ONE, FOUR, FIVE, TRUE, SIX, new_excel_string("Hi")};
723
+ ExcelValue rank_1_v = new_excel_range( rank_1_a, 2, 5);
724
+ ExcelValue rank_2_v = new_excel_range( rank_2_a, 2, 5);
725
+
726
+ // Basics
727
+ assert(rank(THREE, rank_1_v, ZERO).number == 5);
728
+ assert(rank_2(THREE, rank_1_v).number == 5);
729
+ assert(rank(THREE, rank_1_v, ONE).number == 3);
730
+ assert(rank(ONE, rank_1_v, ZERO).number == 6);
731
+ assert(rank(new_excel_string("3"), rank_1_v, ONE).number == 3);
732
+
733
+ // Errors
734
+ assert(rank(TEN, rank_1_v, ZERO).type == ExcelError);
735
+ assert(rank(THREE, rank_2_v, ZERO).type == ExcelError);
736
+
737
+
738
+ // Test the ISNUMBER function
739
+ assert(excel_isnumber(ONE).type == ExcelBoolean);
740
+ assert(excel_isnumber(ONE).number == 1);
741
+ assert(excel_isnumber(BLANK).type == ExcelBoolean);
742
+ assert(excel_isnumber(BLANK).number == 0);
743
+ assert(excel_isnumber(new_excel_string("Hello")).type == ExcelBoolean);
744
+ assert(excel_isnumber(new_excel_string("Hello")).number == 0);
745
+ assert(excel_isnumber(TRUE).type == ExcelBoolean);
746
+ assert(excel_isnumber(TRUE).number == 0);
747
+
748
+ // Release memory
749
+ free_all_allocated_memory();
750
+
751
+ // Yay!
752
+ printf("All tests passed\n");
753
+
754
+ return 0;
755
+ }
756
+
757
+ int main() {
758
+ return test_functions();
759
+ }