1 module juliad.typetests;
2 
3 import std.conv : to;
4 import std.format : format;
5 import std.math : approxEqual;
6 import std.meta : AliasSeq;
7 import std.typecons : Nullable;
8 import std.stdio;
9 
10 import juliad;
11 import juliad.shims;
12 import juliad.types;
13 import juliad.eval;
14 
15 unittest {
16 	jl_value_t* ret = jlEvalString("1 + 2");
17 	assert(getType(ret) == JuliaType.Int64);
18 	assert(!ret.fromJuliaTo!long().isNull());
19 	assert(ret.fromJuliaTo!long() == 3);
20 }
21 
22 unittest {
23 	jl_value_t* ret = jlEvalString("UInt8(1 + 2)");
24 	assert(getType(ret) == JuliaType.UInt8);
25 	assert(!ret.fromJuliaTo!ubyte().isNull());
26 	assert(ret.fromJuliaTo!ubyte() == 3);
27 }
28 
29 unittest {
30 	jl_value_t* ret = jlEvalString("UInt16(1 + 2)");
31 	assert(getType(ret) == JuliaType.UInt16);
32 	assert(!ret.fromJuliaTo!ushort().isNull());
33 	assert(ret.fromJuliaTo!ushort() == 3);
34 }
35 
36 unittest {
37 	jl_value_t* ret = jlEvalString("UInt32(1 + 2)");
38 	assert(getType(ret) == JuliaType.UInt32);
39 	assert(!ret.fromJuliaTo!uint().isNull());
40 	assert(ret.fromJuliaTo!uint() == 3);
41 }
42 
43 unittest {
44 	jl_value_t* ret = jlEvalString("UInt64(1 + 2)");
45 	assert(getType(ret) == JuliaType.UInt64);
46 	assert(!ret.fromJuliaTo!ulong().isNull());
47 	assert(ret.fromJuliaTo!ulong() == 3);
48 }
49 
50 unittest {
51 	jl_value_t* ret = jlEvalString("Int8(1 + 2)");
52 	assert(getType(ret) == JuliaType.Int8);
53 	assert(!ret.fromJuliaTo!byte().isNull());
54 	assert(ret.fromJuliaTo!byte() == 3);
55 }
56 
57 unittest {
58 	jl_value_t* ret = jlEvalString("Int16(1 + 2)");
59 	assert(getType(ret) == JuliaType.Int16);
60 	assert(!ret.fromJuliaTo!short().isNull());
61 	assert(ret.fromJuliaTo!short() == 3);
62 }
63 
64 unittest {
65 	jl_value_t* ret = jlEvalString("Int32(1 + 2)");
66 	assert(getType(ret) == JuliaType.Int32);
67 	assert(!ret.fromJuliaTo!int().isNull());
68 	assert(ret.fromJuliaTo!int() == 3);
69 }
70 
71 unittest {
72 	jl_value_t* ret = jlEvalString("Int64(1 + 2)");
73 	assert(getType(ret) == JuliaType.Int64);
74 	assert(!ret.fromJuliaTo!long().isNull());
75 	assert(ret.fromJuliaTo!long() == 3);
76 }
77 
78 unittest {
79 	jl_value_t* ret = jlEvalString("1 + 2.0");
80 	assert(getType(ret) == JuliaType.Float64);
81 	assert(!ret.fromJuliaTo!double().isNull());
82 	assert(approxEqual(ret.fromJuliaTo!double(), 3.0));
83 }
84 
85 unittest {
86 	jl_value_t* ret = jlEvalString("true");
87 	assert(getType(ret) == JuliaType.Bool);
88 	assert(ret.fromJuliaTo!bool());
89 }
90 
91 unittest {
92 	jl_value_t* ret = jlEvalString("false");
93 	assert(getType(ret) == JuliaType.Bool);
94 	assert(!ret.fromJuliaTo!bool());
95 }
96 
97 unittest {
98 	jl_value_t* ret = jlEvalString("\"hello world\"");
99 	assert(getType(ret) == JuliaType.String);
100 	assert(ret.fromJuliaTo!string() == "hello world");
101 }
102 
103 private jl_value_t* identiyTest(V)(V v) {
104 	jl_function_t *func = jl_get_function(jl_base_module, "identity");
105 	jl_value_t *argument = toJulia(v);
106 	return jl_call1(func, argument);
107 }
108 
109 unittest {
110 	jl_value_t* ret = identiyTest(13.37);
111 	assert(getType(ret) == JuliaType.Float64);
112 	assert(!ret.fromJuliaTo!double().isNull());
113 	double rslt = ret.fromJuliaTo!double();
114 	assert(approxEqual(rslt, 13.37), format("%s", rslt));
115 }
116 
117 unittest {
118 	jl_value_t* ret = identiyTest(true);
119 	assert(getType(ret) == JuliaType.Bool);
120 	assert(!ret.fromJuliaTo!bool().isNull());
121 	bool rslt = ret.fromJuliaTo!bool();
122 	assert(rslt);
123 }
124 
125 unittest {
126 	jl_value_t* ret = identiyTest(false);
127 	assert(getType(ret) == JuliaType.Bool);
128 	assert(!ret.fromJuliaTo!bool().isNull());
129 	bool rslt = ret.fromJuliaTo!bool();
130 	assert(!rslt);
131 }
132 
133 unittest {
134 	foreach(T; AliasSeq!(byte,short,int,long,ubyte,ushort,uint,ulong)) {
135 		T val = cast(T)13;
136 		jl_value_t* ret = identiyTest(val);
137 		assert(!ret.fromJuliaTo!T().isNull());
138 		T rslt = ret.fromJuliaTo!T();
139 		assert(rslt == val, format("%s %s", rslt, val));
140 	}
141 }
142 
143 unittest {
144 	foreach(T; AliasSeq!(string,wstring,dstring)) {
145 		T exp = to!T("Hello World");
146 		jl_value_t* ret = identiyTest(exp);
147 		assert(getType(ret) == JuliaType.String, 
148 				format("%s %s", getType(ret), JuliaType.String));
149 		assert(!ret.fromJuliaTo!string().isNull(), T.stringof);
150 		T rslt = to!T(ret.fromJuliaTo!string());
151 		assert(rslt == exp);
152 	}
153 }
154 
155 unittest {
156 	auto ds = [1.0, 2.0, 3.0];
157 	auto dj = toJulia(ds);
158 	jl_function_t *func = jl_get_function(jl_base_module, "sum");
159 	jl_value_t* ret = jl_call1(func, cast(jl_value_t*)dj);
160 
161 	assert(getType(ret) == JuliaType.Float64);
162 	assert(!ret.fromJuliaTo!double().isNull());
163 	double rslt = ret.fromJuliaTo!double();
164 	assert(approxEqual(rslt, 6.0));
165 }
166 
167 unittest {
168 	auto ds = [1, 2, 3];
169 	auto dj = toJulia(ds);
170 	jl_function_t *func = jl_get_function(jl_base_module, "sum");
171 	jl_value_t* ret = jl_call1(func, cast(jl_value_t*)dj);
172 
173 	assert(getType(ret) == JuliaType.Int64);
174 	assert(!ret.fromJuliaTo!long().isNull());
175 	long rslt = ret.fromJuliaTo!long();
176 	assert(rslt == 6);
177 }
178 
179 unittest {
180 	auto ret = jlEvalString("sum(sum([[1,2], [3,4]]))");
181 	assert(getType(ret) == JuliaType.Int64);
182 	assert(!ret.fromJuliaTo!long().isNull());
183 	long rslt = ret.fromJuliaTo!long();
184 	assert(rslt == 10, format("%s == 10", rslt));
185 }
186 
187 unittest {
188 	auto ds = 
189 		[ [1,2]
190 		, [3,4] ];
191 	jl_array_t* dj = toJulia(ds);
192 	jl_gc_push1(cast(jl_value_t**)&dj);
193 
194 	jl_gc_collect(1);
195 	jl_gc_collect(0);
196 	jl_gc_collect(1);
197 
198 	jl_value_t* foo = jlEvalString(
199 	`function foo(a)
200 		return sum(sum(a))
201 	end`);
202 	//jl_gc_push1(cast(jl_value_t**)&foo);
203 
204 	assert(!jl_exception_occurred(), getErrorString());
205 	assert(foo !is null);
206 	jl_function_t* func = cast(jl_function_t*)jlEvalString("foo");
207 	//jl_gc_push1(cast(jl_value_t**)&func);
208 	assert(func !is null);
209 	assert(!jl_exception_occurred(), getErrorString());
210 	jl_value_t* ret = jl_call1(func, cast(jl_value_t*)dj);
211 	assert(!jl_exception_occurred(), getErrorString());
212 	assert(ret !is null);
213 	assert(getType(ret) == JuliaType.Int64);
214 	assert(!ret.fromJuliaTo!long().isNull());
215 	long rslt = ret.fromJuliaTo!long();
216 	assert(rslt == 10, format("%s == 10", rslt));
217 }
218 
219 unittest {
220 	auto ds = 
221 		[ [ [1,2], [3,4] ]
222 		, [ [5,6], [7,8] ]
223 		];
224 	writeln(ds);
225 	jl_array_t* dj = toJulia(ds);
226 	jl_gc_push1(cast(jl_value_t**)&dj);
227 
228 	jl_value_t* bar = jlEvalString(
229 	`function bar(a)
230 		return sum(sum(sum(a)))
231 	end`);
232 	jl_gc_push1(cast(jl_value_t**)&bar);
233 
234 	assert(!jl_exception_occurred(), getErrorString());
235 	assert(bar !is null);
236 	jl_function_t* func = cast(jl_function_t*)jlEvalString("bar");
237 	jl_gc_push1(cast(jl_value_t**)&func);
238 	assert(func !is null);
239 	assert(!jl_exception_occurred(), getErrorString());
240 	jl_value_t* ret = jl_call1(func, cast(jl_value_t*)dj);
241 	assert(!jl_exception_occurred(), getErrorString());
242 	assert(ret !is null);
243 	assert(getType(ret) == JuliaType.Int64);
244 	assert(!ret.fromJuliaTo!long().isNull());
245 	long rslt = ret.fromJuliaTo!long();
246 	assert(rslt == 36, format("%s == 36", rslt));
247 }
248 
249 unittest {
250 	int[] ds = [1, 2, 3];
251 	auto dj = toJulia(ds);
252 	jl_function_t *func = jl_get_function(jl_base_module, "identity");
253 	jl_value_t* ret = jl_call1(func, cast(jl_value_t*)dj);
254 
255 	Nullable!(int[]) r = fromJuliaTo!(int[])(ret);
256 	assert(r.isNull());
257 	assert(r.get() == ds, format("%s", r.get()));
258 }