1 module ut.wrap.wrap;
2 
3 import test;
4 import xlld.wrap.wrap;
5 import xlld.conv.to: toXlOper;
6 
7 
8 // this has to be a top-level function and can't be declared in the unittest
9 double twice(double d) { return d * 2; }
10 
11 ///
12 @Flaky
13 @("wrapAsync")
14 @system unittest {
15     import xlld.test.util: asyncReturn, newAsyncHandle;
16     import xlld.conv.from: fromXlOper;
17     import core.time: MonoTime;
18     import core.thread;
19 
20     const start = MonoTime.currTime;
21     auto asyncHandle = newAsyncHandle;
22     auto oper = (3.2).toXlOper(theGC);
23     wrapAsync!twice(theGC, cast(immutable)asyncHandle, oper);
24     const expected = 6.4;
25     while(asyncReturn(asyncHandle).fromXlOper!double(theGC) != expected &&
26           MonoTime.currTime - start < 1.seconds)
27     {
28         Thread.sleep(10.msecs);
29     }
30     asyncReturn(asyncHandle).shouldEqualDlang(expected);
31 }
32 
33 @("xltypeNum can convert to array")
34 @safe unittest {
35     import std.typecons: tuple;
36 
37     void fun(double[] arg) {}
38     auto arg = 33.3.toSRef(theGC);
39     auto argPtr = () @trusted { return &arg; }();
40     toDArgs!fun(theGC, argPtr).shouldEqual(tuple([33.3]));
41 }
42 
43 @("xltypeNil can convert to array")
44 @safe unittest {
45     import xlld.sdk.xlcall: XlType;
46     import std.typecons: tuple;
47 
48     void fun(double[] arg) {}
49     XLOPER12 arg;
50     arg.xltype = XlType.xltypeNil;
51     double[] empty;
52     auto argPtr = () @trusted { return &arg; }();
53     toDArgs!fun(theGC, argPtr).shouldEqual(tuple(empty));
54 }
55 
56 
57 @("excelRet!double[] from row caller")
58 unittest {
59     import xlld.sdk.xlcall: XlType, xlfCaller;
60     import xlld.conv.misc: stripMemoryBitmask;
61     import xlld.memorymanager: autoFree;
62 
63     XLOPER12 caller;
64     caller.xltype = XlType.xltypeSRef;
65     caller.val.sref.ref_.rwFirst = 1;
66     caller.val.sref.ref_.rwLast = 1;
67     caller.val.sref.ref_.colFirst = 2;
68     caller.val.sref.ref_.colLast = 4;
69 
70     with(MockXlFunction(xlfCaller, caller)) {
71         auto doubles = [1.0, 2.0, 3.0, 4.0];
72         auto oper = excelRet(doubles);
73         scope(exit) autoFree(&oper);
74 
75         oper.shouldEqualDlang(doubles);
76         oper.xltype.stripMemoryBitmask.shouldEqual(XlType.xltypeMulti);
77         oper.val.array.rows.shouldEqual(1);
78         oper.val.array.columns.shouldEqual(4);
79     }
80 }
81 
82 @("excelRet!double[] from column caller")
83 unittest {
84     import xlld.sdk.xlcall: XlType, xlfCaller;
85     import xlld.conv.misc: stripMemoryBitmask;
86     import xlld.memorymanager: autoFree;
87 
88     XLOPER12 caller;
89     caller.xltype = XlType.xltypeSRef;
90     caller.val.sref.ref_.rwFirst = 1;
91     caller.val.sref.ref_.rwLast = 4;
92     caller.val.sref.ref_.colFirst = 5;
93     caller.val.sref.ref_.colLast = 5;
94 
95     with(MockXlFunction(xlfCaller, caller)) {
96         auto doubles = [1.0, 2.0, 3.0, 4.0];
97         auto oper = excelRet(doubles);
98         scope(exit) autoFree(&oper);
99 
100         oper.shouldEqualDlang(doubles);
101         oper.xltype.stripMemoryBitmask.shouldEqual(XlType.xltypeMulti);
102         oper.val.array.rows.shouldEqual(4);
103         oper.val.array.columns.shouldEqual(1);
104     }
105 }
106 
107 
108 @("excelRet!tuple from column caller")
109 unittest {
110     import xlld.sdk.xlcall: XlType, xlfCaller;
111     import xlld.conv.misc: stripMemoryBitmask;
112     import xlld.memorymanager: autoFree;
113     import std.typecons: tuple;
114 
115     XLOPER12 caller;
116     caller.xltype = XlType.xltypeSRef;
117     caller.val.sref.ref_.rwFirst = 1;
118     caller.val.sref.ref_.rwLast = 4;
119     caller.val.sref.ref_.colFirst = 5;
120     caller.val.sref.ref_.colLast = 5;
121 
122     with(MockXlFunction(xlfCaller, caller)) {
123         auto doubles = tuple(1.0, 2.0, 3.0, 4.0);
124         auto oper = excelRet(doubles);
125         scope(exit) autoFree(&oper);
126 
127         oper.shouldEqualDlang(doubles);
128         oper.xltype.stripMemoryBitmask.shouldEqual(XlType.xltypeMulti);
129         oper.val.array.rows.shouldEqual(4);
130         oper.val.array.columns.shouldEqual(1);
131     }
132 }
133 
134 @("excelRet!vector from column caller")
135 unittest {
136     import xlld.sdk.xlcall: XlType, xlfCaller;
137     import xlld.conv.misc: stripMemoryBitmask;
138     import xlld.memorymanager: autoFree;
139     import automem.vector: vector;
140 
141     XLOPER12 caller;
142     caller.xltype = XlType.xltypeSRef;
143     caller.val.sref.ref_.rwFirst = 1;
144     caller.val.sref.ref_.rwLast = 4;
145     caller.val.sref.ref_.colFirst = 5;
146     caller.val.sref.ref_.colLast = 5;
147 
148     with(MockXlFunction(xlfCaller, caller)) {
149         auto doubles = vector(1.0, 2.0, 3.0, 4.0);
150         auto oper = excelRet(doubles);
151         scope(exit) autoFree(&oper);
152 
153         oper.shouldEqualDlang(doubles[]);
154         oper.xltype.stripMemoryBitmask.shouldEqual(XlType.xltypeMulti);
155         oper.val.array.rows.shouldEqual(4);
156         oper.val.array.columns.shouldEqual(1);
157     }
158 }
159 
160 
161 @("excelRet!double[] from other caller")
162 unittest {
163     import xlld.sdk.xlcall: XlType, xlfCaller;
164     import xlld.conv.misc: stripMemoryBitmask;
165     import xlld.memorymanager: autoFree;
166 
167     XLOPER12 caller;
168     caller.xltype = XlType.xltypeErr;
169 
170     with(MockXlFunction(xlfCaller, caller)) {
171         auto doubles = [1.0, 2.0, 3.0, 4.0];
172         auto oper = excelRet(doubles);
173         scope(exit) autoFree(&oper);
174 
175         oper.shouldEqualDlang(doubles);
176         oper.xltype.stripMemoryBitmask.shouldEqual(XlType.xltypeMulti);
177         oper.val.array.rows.shouldEqual(1);
178         oper.val.array.columns.shouldEqual(4);
179     }
180 }
181 
182 @("toDArgs optional arguments")
183 @safe unittest {
184     import std.typecons: tuple;
185 
186     static int add(int i, int j = 42);
187 
188     XLOPER12 missing;
189     missing.xltype = XlType.xltypeMissing;
190 
191     auto i = 2.toXlOper(theGC);
192     auto j = 3.toXlOper(theGC);
193 
194     auto iPtr = () @trusted { return &i; }();
195     auto jPtr = () @trusted { return &j; }();
196     auto missingPtr = () @trusted { return &missing; }();
197 
198     toDArgs!add(theGC, iPtr, jPtr).shouldEqual(tuple(2, 3));
199     toDArgs!add(theGC, iPtr, missingPtr).shouldEqual(tuple(2, 42));
200 }