1 module tests.reflection;
2 
3 import unit_threaded;
4 import cucumber.keywords;
5 import cucumber.reflection;
6 import std.regex;
7 import std.algorithm;
8 import std.array;
9 
10 private string[] reflectionFuncCalls;
11 
12 @Match(r"^I match step1")
13 void step1() {
14     reflectionFuncCalls ~= "step1";
15 }
16 
17 @Match(r"^I think I match step2")
18 void step2() {
19     reflectionFuncCalls ~= "step2";
20 }
21 
22 @Match(r"^Ooh, step3$")
23 void step3() {
24     reflectionFuncCalls ~= "step3";
25 }
26 
27 private {
28     @Match(r"Never going to see me here")
29     void privateStep() {
30         reflectionFuncCalls ~= "privateStep";
31     }
32 }
33 
34 void testFindMySteps() {
35     reflectionFuncCalls = [];
36 
37     auto steps = findSteps!__MODULE__;
38     auto regexen = [r"^I match step1", r"^I think I match step2", r"^Ooh, step3$"];
39 
40     shouldEqual(steps.map!(a => a.regex).array,
41                regexen.map!(a => std.regex.regex(a)).array);
42 
43     steps[0].func();
44     shouldEqual(reflectionFuncCalls, ["step1"]);
45 
46     steps[1].func();
47     shouldEqual(reflectionFuncCalls, ["step1", "step2"]);
48 
49     steps[2].func();
50     shouldEqual(reflectionFuncCalls, ["step1", "step2", "step3"]);
51 }
52 
53 void testFindMatchSteps() {
54     import tests.match;
55     matchFuncCalls = [];
56 
57     auto steps = findSteps!"tests.match";
58     auto regexen = [r"^I match a passing step$",
59                     r"^I also match a passing step$",
60                     r"^What about me. I also pass$",
61                     r"I match a failing step$",
62                     r"Gotta match pending"];
63 
64     shouldEqual(steps.map!(a => a.regex).array,
65                regexen.map!(a => std.regex.regex(a)).array);
66 
67     steps[0].func();
68     shouldEqual(matchFuncCalls, ["passingStep1"]);
69 
70     steps[1].func();
71     shouldEqual(matchFuncCalls, ["passingStep1", "passingStep2"]);
72 
73     steps[2].func();
74     shouldEqual(matchFuncCalls, ["passingStep1", "passingStep2", "passingStep3"]);
75 
76     shouldThrow!Exception(steps[3].func());
77     shouldEqual(matchFuncCalls, ["passingStep1", "passingStep2", "passingStep3", "failingStep"]);
78 }
79 
80 void testFindMatch() {
81     reflectionFuncCalls = [];
82 
83     findMatch!__MODULE__("I match step1")();
84     shouldEqual(reflectionFuncCalls, ["step1"]);
85 
86     findMatch!__MODULE__("I think I match step2......")(); //extra chars, still matches
87     shouldEqual(reflectionFuncCalls, ["step1", "step2"]);
88     findMatch!__MODULE__("Ooh, step3")();
89     shouldEqual(reflectionFuncCalls, ["step1", "step2", "step3"]);
90 
91     shouldBeFalse(cast(bool)findMatch!__MODULE__("Ooh, step3."));
92     shouldThrow!Exception(findMatch!__MODULE__("Ooh, step3.")());
93 
94     shouldBeFalse(cast(bool)findMatch!__MODULE__("random garbage"));
95     shouldThrow!Exception(findMatch!__MODULE__("random garbage")());
96 }