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 }