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 }