1 /++
2     Unit test plugin.
3 
4     See_Also:
5         [kameloso.plugins.common.core],
6         [kameloso.plugins.common.misc]
7 
8     Copyright: [JR](https://github.com/zorael)
9     License: [Boost Software License 1.0](https://www.boost.org/users/license.html)
10 
11     Authors:
12         [JR](https://github.com/zorael)
13  +/
14 module kameloso.plugins.unittest_;
15 
16 version(unittest):
17 
18 private:
19 
20 import kameloso.plugins;
21 import kameloso.plugins.common.core;
22 import kameloso.plugins.common.awareness;
23 import kameloso.plugins.common.mixins;
24 import dialect.defs;
25 import std.typecons : Flag, No, Yes;
26 
27 mixin UserAwareness!(ChannelPolicy.any, Yes.debug_);
28 mixin ChannelAwareness!(ChannelPolicy.any, Yes.debug_);
29 mixin TwitchAwareness!(ChannelPolicy.any, Yes.debug_);
30 mixin PluginRegistration!(UnittestPlugin, 100.priority);
31 
32 
33 // UnittestSettings
34 /++
35     Unit test plugin settings.
36  +/
37 @Settings struct UnittestSettings
38 {
39     /// Enabler.
40     @Enabler bool enabled = false;
41 }
42 
43 
44 // onCommand
45 /++
46     Event handler command test.
47  +/
48 @(IRCEventHandler()
49     .onEvent(IRCEvent.Type.CHAN)
50     .onEvent(IRCEvent.Type.QUERY)
51     .permissionsRequired(Permissions.anyone)
52     .channelPolicy(ChannelPolicy.any)
53     .addCommand(
54         IRCEventHandler.Command()
55             .word("unittest")
56             .policy(PrefixPolicy.direct)
57             .description("Test command description")
58             .addSyntax("$command test command syntax")
59     )
60 )
61 void onCommand(UnittestPlugin plugin, const ref IRCEvent event)
62 {
63     with (plugin)
64     {
65         void onSuccess(IRCUser user)
66         {
67             chan(event.channel, "success:" ~ user.account);
68         }
69 
70         void onFailure()
71         {
72             chan(event.channel, "failure");
73         }
74 
75         mixin WHOISFiberDelegate!(onSuccess, onFailure, Yes.alwaysLookup);
76         enqueueAndWHOIS(event.sender.nickname);
77     }
78 }
79 
80 
81 // onRegex
82 /++
83     Event handler regex test.
84  +/
85 @(IRCEventHandler()
86     .onEvent(IRCEvent.Type.CHAN)
87     .onEvent(IRCEvent.Type.QUERY)
88     .permissionsRequired(Permissions.anyone)
89     .channelPolicy(ChannelPolicy.any)
90     .addRegex(
91         IRCEventHandler.Regex()
92             .expression("unit[tT]est.*")
93             .description("Test regex description")
94     )
95 )
96 void onRegex(UnittestPlugin _, const ref IRCEvent _2)
97 {
98     // ...
99 }
100 
101 
102 public:
103 
104 
105 // UnittestPlugin
106 /++
107     Unit test plugin.
108  +/
109 final class UnittestPlugin : IRCPlugin
110 {
111     /++
112         Unit test plugin settings.
113      +/
114     UnittestSettings unittestSettings;
115 
116     @Resource resFileWithoutSubdir = "unittest.delme";
117     @Resource("unittest") resFileWithSubdir = "unittest.delme";
118     @Configuration confFileWithoutSubdir = "unittest.delme";
119     @Configuration("unittest") confFileWithSubdir = "unittest.delme";
120 
121     mixin MessagingProxy;
122     mixin IRCPluginImpl!(Yes.debug_);
123 }
124 
125 ///
126 unittest
127 {
128     import std.conv : to;
129     import std.path : buildNormalizedPath;
130 
131     IRCPluginState state;
132     state.settings.configDirectory = "conf";
133     state.settings.resourceDirectory = "res";
134     auto plugin = new UnittestPlugin(state);
135 
136     assert((plugin.name == "unittest_"), plugin.name);
137 
138     assert(!plugin.isEnabled);
139     plugin.unittestSettings.enabled = true;
140     assert(plugin.isEnabled);
141 
142     assert((plugin.Introspection.allEventHandlerUDAsInModule.length > 2),
143         plugin.Introspection.allEventHandlerUDAsInModule.length.to!string);
144     assert((plugin.Introspection.allEventHandlerFunctionsInModule.length > 2),
145         plugin.Introspection.allEventHandlerFunctionsInModule.length.to!string);
146 
147     immutable resPathWithout = buildNormalizedPath(
148         plugin.state.settings.resourceDirectory,
149         "unittest.delme");
150     immutable resPathWith = buildNormalizedPath(
151         plugin.state.settings.resourceDirectory,
152         "unittest",
153         "unittest.delme");
154 
155     assert((plugin.resFileWithoutSubdir == resPathWithout), plugin.resFileWithoutSubdir);
156     assert((plugin.resFileWithSubdir == resPathWith), plugin.resFileWithSubdir);
157 
158     immutable confPathWithout = buildNormalizedPath(
159         plugin.state.settings.configDirectory,
160         "unittest.delme");
161     immutable confPathWith = buildNormalizedPath(
162         plugin.state.settings.configDirectory,
163         "unittest",
164         "unittest.delme");
165 
166     assert((plugin.confFileWithoutSubdir == confPathWithout), plugin.confFileWithoutSubdir);
167     assert((plugin.confFileWithSubdir == confPathWith), plugin.confFileWithSubdir);
168 }