1 module dmocks.arguments;
2 
3 import dmocks.dynamic;
4 import std.algorithm;
5 import std.conv;
6 import std.range;
7 
8 interface ArgumentsMatch
9 {
10     bool matches(Dynamic[] args);
11     string toString();
12 }
13 
14  //TODO: allow richer specification of arguments
15 class StrictArgumentsMatch : ArgumentsMatch
16 {
17     private Dynamic[] _arguments;
18     this(Dynamic[] args)
19     {
20         _arguments = args;
21     }
22 
23     override bool matches(Dynamic[] args)
24     {
25         return _arguments == args;
26     }
27 
28     override string toString()
29     {
30         return _arguments.formatArguments();
31     }
32 }
33 
34 class ArgumentsTypeMatch : ArgumentsMatch
35 {
36     private Dynamic[] _arguments;
37     private bool delegate(Dynamic, Dynamic) _del;
38     this(Dynamic[] args, bool delegate(Dynamic, Dynamic) del)
39     {
40         _arguments = args;
41         _del = del;
42     }
43     override bool matches(Dynamic[] args)
44     {
45         import std.range;
46         if (args.length != _arguments.length)
47             return false;
48 
49         foreach(e; zip(_arguments, args))
50         {
51             if (e[0].type != e[1].type)
52                 return false;
53             if (!_del(e[0], e[1]))
54                 return false;
55         }
56         return true;
57     }
58 
59     override string toString()
60     {
61         return "("~_arguments.map!(a=>a.type.toString).join(", ")~")";
62     }
63 }
64 
65 
66 interface IArguments
67 {
68     string toString();
69     bool opEquals (Object other);
70 }
71 
72 auto arguments(ARGS...)(ARGS args)
73 {
74     Dynamic[] res = new Dynamic[](ARGS.length);
75     foreach(i, arg; args)
76     {
77         res[i] = dynamic(arg);
78     }
79     return res;
80 }
81 
82 auto formatArguments(Dynamic[] _arguments)
83 {
84     return "(" ~ _arguments.map!(a=>a.type.toString ~ " " ~ a.toString()).join(", ") ~")";
85 }
86 
87 @("argument equality")
88 unittest
89 {
90     auto a = arguments!(int, real)(5, 9.7);
91     auto b = arguments!(int, real)(5, 9.7);
92     auto c = arguments!(int, real)(9, 1.1);
93     auto d = arguments!(int, float)(5, 9.7f);
94 
95     assert (a == b);
96     assert (a != c);
97     assert (a != d);
98 }
99 
100 @("argument toString")
101 unittest
102 {
103     auto a = arguments!(int, real)(5, 9.7);
104     a.formatArguments();
105 }