1 module ut.wrap.traits; 2 3 import test; 4 import xlld.wrap.traits; 5 import xlld.wrap.worksheet; 6 7 8 /// return a WorksheetFunction for a double function(double) with no 9 /// optional arguments 10 WorksheetFunction makeWorksheetFunction(wstring name, wstring typeText) @safe pure nothrow { 11 return 12 WorksheetFunction( 13 Procedure(name), 14 TypeText(typeText), 15 FunctionText(name), 16 Optional( 17 ArgumentText(""w), 18 MacroType("1"w), 19 Category(""w), 20 ShortcutText(""w), 21 HelpTopic(""w), 22 FunctionHelp(""w), 23 ArgumentHelp([]), 24 ) 25 ); 26 } 27 28 /// 29 WorksheetFunction doubleToDoubleFunction(wstring name) @safe pure nothrow { 30 return makeWorksheetFunction(name, "BB"w); 31 } 32 33 /// 34 WorksheetFunction FP12ToDoubleFunction(wstring name) @safe pure nothrow { 35 return makeWorksheetFunction(name, "BK%"w); 36 } 37 38 /// 39 WorksheetFunction operToOperFunction(wstring name) @safe pure nothrow { 40 return makeWorksheetFunction(name, "UU"w); 41 } 42 43 WorksheetFunction asyncFunction(wstring name) @safe pure nothrow { 44 return makeWorksheetFunction(name, ">UX"w); 45 } 46 47 /// 48 @("getWorksheetFunction for double -> double functions with no extra attributes") 49 @safe pure unittest { 50 extern(Windows) double foo(double) nothrow @nogc { return 0; } 51 getWorksheetFunction!foo.shouldEqual(doubleToDoubleFunction("foo")); 52 53 extern(Windows) double bar(double) nothrow @nogc { return 0; } 54 getWorksheetFunction!bar.shouldEqual(doubleToDoubleFunction("bar")); 55 } 56 57 /// 58 @("getWorksheetFunction for double -> int functions should fail") 59 @safe pure unittest { 60 extern(Windows) double foo(int) { return 0; } 61 getWorksheetFunction!foo.shouldThrowWithMessage("Unsupported function type double(int) for foo"); 62 } 63 64 /// 65 @("getworksheetFunction with @Register in order") 66 @safe pure unittest { 67 68 @Register(ArgumentText("my arg txt"), MacroType("macro")) 69 extern(Windows) double foo(double) nothrow; 70 71 auto expected = doubleToDoubleFunction("foo"); 72 expected.argumentText = ArgumentText("my arg txt"); 73 expected.macroType = MacroType("macro"); 74 75 getWorksheetFunction!foo.shouldEqual(expected); 76 } 77 78 /// 79 @("getworksheetFunction with @Register out of order") 80 @safe pure unittest { 81 82 @Register(HelpTopic("I need somebody"), ArgumentText("my arg txt")) 83 extern(Windows) double foo(double) nothrow; 84 85 auto expected = doubleToDoubleFunction("foo"); 86 expected.argumentText = ArgumentText("my arg txt"); 87 expected.helpTopic = HelpTopic("I need somebody"); 88 89 getWorksheetFunction!foo.shouldEqual(expected); 90 } 91 92 93 @safe pure unittest { 94 extern(Windows) double doubleToDouble(double) nothrow; 95 static assert(isWorksheetFunction!doubleToDouble); 96 97 extern(Windows) LPXLOPER12 operToOper(LPXLOPER12) nothrow; 98 static assert(isWorksheetFunction!operToOper); 99 100 extern(Windows) void funcAsync(LPXLOPER12 n, LPXLOPER12 asyncHandle) nothrow; 101 static assert(isWorksheetFunction!funcAsync); 102 103 LPXLOPER12 operToOperWrongLinkage(LPXLOPER12) nothrow; 104 static assert(isWorksheetFunctionModuloLinkage!operToOperWrongLinkage); 105 static assert(!isWorksheetFunction!operToOperWrongLinkage); 106 107 enum MyEnum { foo, bar, baz, } 108 109 extern(Windows) MyEnum FuncEnumRet(LPXLOPER12 n) nothrow; 110 static assert(!isWorksheetFunction!FuncEnumRet); 111 112 extern(Windows) LPXLOPER12 FuncEnumArg(MyEnum _) nothrow; 113 static assert(!isWorksheetFunction!FuncEnumArg); 114 } 115 116 117 @("getWorksheetFunctions on test.xl_funcs") 118 @safe pure unittest { 119 getModuleWorksheetFunctions!"test.xl_funcs".shouldEqual( 120 [ 121 doubleToDoubleFunction("FuncMulByTwo"), 122 FP12ToDoubleFunction("FuncFP12"), 123 operToOperFunction("FuncFib"), 124 asyncFunction("FuncAsync"), 125 ] 126 ); 127 } 128 129 @("template mixin for getWorkSheetFunctions for test.xl_funcs") 130 unittest { 131 import xlld.wrap.worksheet; 132 133 // mixin the function here then call it to see if it does what it's supposed to 134 mixin(implGetWorksheetFunctionsString!"test.xl_funcs"); 135 getWorksheetFunctions.shouldEqual( 136 [ 137 doubleToDoubleFunction("FuncMulByTwo"), 138 FP12ToDoubleFunction("FuncFP12"), 139 operToOperFunction("FuncFib"), 140 asyncFunction("FuncAsync"), 141 ] 142 ); 143 } 144 145 @("implGetWorksheetFunctionsString runtime") 146 unittest { 147 import xlld.wrap.worksheet; 148 149 // mixin the function here then call it to see if it does what it's supposed to 150 mixin(implGetWorksheetFunctionsString("test.xl_funcs")); 151 getWorksheetFunctions.shouldEqual( 152 [ 153 doubleToDoubleFunction("FuncMulByTwo"), 154 FP12ToDoubleFunction("FuncFP12"), 155 operToOperFunction("FuncFib"), 156 asyncFunction("FuncAsync"), 157 ] 158 ); 159 } 160 161 162 @("worksheet functions to .def file") 163 unittest { 164 dllDefFile!"test.xl_funcs"("myxll32.dll", "Simple D add-in").shouldEqual( 165 DllDefFile( 166 [ 167 Statement("LIBRARY", "myxll32.dll"), 168 Statement("EXPORTS", 169 [ 170 "xlAutoOpen", 171 "xlAutoClose", 172 "xlAutoFree12", 173 "FuncMulByTwo", 174 "FuncFP12", 175 "FuncFib", 176 "FuncAsync", 177 ]), 178 ] 179 ) 180 ); 181 } 182 183 184 @("getTypeText") 185 @safe pure unittest { 186 import std.conv: to; // working around unit-threaded bug 187 188 double foo(double); 189 getTypeText!foo.to!string.shouldEqual("BB"); 190 191 double bar(FP12*); 192 getTypeText!bar.to!string.shouldEqual("BK%"); 193 194 FP12* baz(FP12*); 195 getTypeText!baz.to!string.shouldEqual("K%K%"); 196 197 FP12* qux(double); 198 getTypeText!qux.to!string.shouldEqual("K%B"); 199 200 LPXLOPER12 fun(LPXLOPER12); 201 getTypeText!fun.to!string.shouldEqual("UU"); 202 203 void void_(LPXLOPER12, LPXLOPER12); 204 getTypeText!void_.to!string.shouldEqual(">UU"); 205 206 @Async 207 void async(LPXLOPER12, LPXLOPER12); 208 getTypeText!async.to!string.shouldEqual(">UX"); 209 }