1 module boilerplate;
2 
3 public import boilerplate.accessors;
4 
5 public import boilerplate.autostring;
6 
7 public import boilerplate.conditions;
8 
9 public import boilerplate.constructor;
10 
11 enum GenerateAll = GenerateThis ~ GenerateToString ~ GenerateFieldAccessors ~ GenerateInvariants;
12 
13 /**
14  * Used to indicate that a field should be treated as if aliased to this as much as practical.
15  * At the moment this has no effect in boilerplate, but it is used in serialized to treat the
16  * field as aliased to this for purpose of encode/decode.
17  */
18 struct AliasThis
19 {
20 }
21 
22 @("can use all four generators at once")
23 unittest
24 {
25     import core.exception : AssertError;
26     import std.conv : to;
27     import unit_threaded.should : shouldEqual, shouldThrow;
28 
29     class Class
30     {
31         @ConstRead @Write @NonInit
32         int i_;
33 
34         mixin(GenerateAll);
35     }
36 
37     auto obj = new Class(5);
38 
39     obj.i.shouldEqual(5);
40     obj.to!string.shouldEqual("Class(i=5)");
41     obj.i(0).shouldThrow!AssertError;
42 }
43 
44 // regression test for workaround for https://issues.dlang.org/show_bug.cgi?id=19731
45 @("accessor on field in struct with invariant and constructor")
46 unittest
47 {
48     import core.exception : AssertError;
49     import unit_threaded.should : shouldThrow;
50 
51     struct Struct
52     {
53         @NonNull
54         @ConstRead
55         Object constObject_;
56 
57         @NonNull
58         @Read
59         Object object_;
60 
61         mixin(GenerateAll);
62     }
63 
64     Struct().constObject.shouldThrow!AssertError;
65     Struct().object.shouldThrow!AssertError;
66 }
67 
68 @("field with reserved name")
69 unittest
70 {
71     struct Struct
72     {
73         int version_;
74 
75         mixin(GenerateAll);
76     }
77 
78     with (Struct.Builder())
79     {
80         version_ = 5;
81 
82         assert(value.version_ == 5);
83         assert(value.BuilderFrom().value.version_ == 5);
84     }
85 }
86 
87 @("class with no members")
88 unittest
89 {
90     static class Class
91     {
92         mixin(GenerateAll);
93     }
94 
95     auto instance = Class.Builder().value;
96 }
97 
98 @("underscore property is aliased to this")
99 unittest
100 {
101     struct Foo
102     {
103         @ConstRead
104         int i_;
105 
106         alias i_ this;
107 
108         mixin(GenerateAll);
109     }
110 
111     auto builder = Foo.Builder();
112 
113     cast(void) builder;
114 }
115 
116 @("const sumtype with non-const subtype")
117 unittest
118 {
119     import std.sumtype : SumType;
120 
121     struct Foo
122     {
123         int[] array;
124     }
125 
126     struct Bar
127     {
128         const SumType!Foo foo;
129 
130         mixin(GenerateAll);
131     }
132 }
133 
134 @("struct with overloaded method")
135 unittest
136 {
137     struct Foo
138     {
139         void foo(int) { }
140 
141         void foo(float) { }
142 
143         mixin(GenerateAll);
144     }
145 }