1 // Written in D programming language
2 /**
3 *   Utilities for integration test of binary format conversion.
4 *
5 *   Copyright: © 2014 DSoftOut
6 *   License: Subject to the terms of the MIT license, as written in the included LICENSE file.
7 *   Authors: NCrashed <ncrashed@gmail.com>
8 */
9 module pgator.db.pq.types.test;
10 
11 version(IntegrationTest2):
12 
13 import std.random;
14 import std.range;
15 import std.algorithm;
16 import std.encoding;
17 import std.traits;
18 import std.math;
19 import vibe.data.bson;
20 import derelict.pq.pq;
21 import pgator.db.pool;
22 import dlogg.log;
23 import dlogg.buffered;
24 
25 T id(T)(T val) {return val;}
26 
27 bool floatEquality(T)(T a, T b) 
28     if(isFloatingPoint!T)
29 {
30     if(a.isNaN) return b.isNaN;
31     if(b.isNaN) return a.isNaN;
32     return approxEqual(a,b);
33 }
34 
35 Bson queryValue(shared ILogger logger, shared IConnectionPool pool, string val)
36 {
37     auto query = "SELECT "~val~" as test_field";
38     logger.logInfo(query);
39     auto res = cast()pool.execTransaction([query]).front;
40     
41     logger.logInfo(text(res));
42     return res.get!(Bson[string])["test_field"][0];
43 }
44 
45 void testValue(T, alias converter = to!string, alias resConverter = id)
46     (shared ILogger logger, shared IConnectionPool pool, T local, string sqlType)
47 {
48 	auto delayed = new shared BufferedLogger(logger);
49 	scope(exit) delayed.finalize();
50 	scope(failure) delayed.minOutputLevel = LoggingLevel.Notice;
51 	
52     auto node = queryValue(delayed, pool, converter(local)~"::"~sqlType);
53     
54     static if(is(T == ubyte[]))
55         auto remote = node.opt!BsonBinData.rawData;
56     else 
57         auto remote = node.deserializeBson!T;
58         
59     static if(isFloatingPoint!T)
60     {
61         assert(resConverter(remote).floatEquality(resConverter(local)), resConverter(remote).to!string ~ "!=" ~ resConverter(local).to!string);
62     }
63     else static if(isArray!T && isFloatingPoint!(ElementType!T))
64     {
65         assert(equal!floatEquality(resConverter(remote), resConverter(local)), resConverter(remote).to!string ~ "!=" ~ resConverter(local).to!string); 
66     } else
67     {
68         assert(resConverter(remote) == resConverter(local), resConverter(remote).to!string ~ "!=" ~ resConverter(local).to!string);
69     } 
70 }