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.
- checksums.yaml +4 -4
- data/bin/excel_to_c +0 -4
- data/bin/excel_to_ruby +0 -4
- data/src/commands/excel_to_c.rb +7 -27
- data/src/commands/excel_to_ruby.rb +2 -2
- data/src/commands/excel_to_x.rb +215 -175
- data/src/compile/c/a.out +0 -0
- data/src/compile/c/excel_to_c_runtime.c +39 -806
- data/src/compile/c/excel_to_c_runtime_test.c +759 -0
- data/src/compile/ruby/map_formulae_to_ruby.rb +1 -0
- data/src/excel/excel_functions.rb +2 -0
- data/src/excel/excel_functions/lower.rb +21 -0
- data/src/extract.rb +1 -10
- data/src/extract/{extract_everything.rb → extract_data_from_worksheet.rb} +1 -1
- metadata +30 -39
- data/src/extract/check_for_unknown_functions.rb +0 -20
- data/src/extract/extract_array_formulae.rb +0 -23
- data/src/extract/extract_formulae.rb +0 -46
- data/src/extract/extract_shared_formulae.rb +0 -24
- data/src/extract/extract_shared_formulae_targets.rb +0 -15
- data/src/extract/extract_simple_formulae.rb +0 -23
- data/src/extract/extract_values.rb +0 -53
- data/src/extract/extract_worksheet_dimensions.rb +0 -21
- data/src/extract/extract_worksheet_table_relationships.rb +0 -22
- data/src/extract/simple_extract_from_xml.rb +0 -17
@@ -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
|
+
}
|