1 module cogito.tests.meter; 2 3 import cogito; 4 import cogito.list; 5 import cogito.meter; 6 import std.array; 7 import dmd.identifier; 8 import dmd.globals; 9 import std.algorithm; 10 import std.sumtype; 11 12 @("filename.d:line: identifier: score") 13 unittest 14 { 15 enum string filename = "filename.d"; 16 auto meter = Meter(new Identifier(""), Loc(filename, 2, 1), Meter.Type.callable); 17 auto meters = List!Meter(); 18 19 meter.ownScore = 3; 20 meters.insert(meter); 21 22 auto source = Source(meters, filename); 23 auto output = appender!string(); 24 auto reporter = FlatReporter!((string x) => output.put(x))(source); 25 26 reporter.report(Threshold(1, 50)); 27 28 assert(output.data == "filename.d:2: function (λ): 3\n"); 29 } 30 31 @("flat reporter prepends function identifiers with function") 32 unittest 33 { 34 enum string filename = "filename.d"; 35 auto meter = Meter(new Identifier("f"), Loc(filename, 2, 1), Meter.Type.callable); 36 auto meters = List!Meter(); 37 38 meter.ownScore = 3; 39 meters.insert(meter); 40 41 auto source = Source(meters, filename); 42 auto output = appender!string(); 43 auto reporter = FlatReporter!((string x) => output.put(x))(source); 44 45 reporter.report(Threshold(1, 50)); 46 47 assert(output.data == "filename.d:2: function f: 3\n"); 48 } 49 50 @("reports interface score") 51 unittest 52 { 53 enum string filename = "filename.d"; 54 auto meter = Meter(new Identifier("I"), Loc(filename, 2, 1), Meter.Type.interface_); 55 auto meters = List!Meter(); 56 57 meter.ownScore = 3; 58 meters.insert(meter); 59 60 auto source = Source(meters, filename); 61 auto output = appender!string(); 62 auto reporter = FlatReporter!((string x) => output.put(x))(source); 63 64 reporter.report(Threshold(1, 2)); 65 66 assert(output.data == "filename.d:2: interface I: 3\n"); 67 } 68 69 @("reports interface aggregate type") 70 unittest 71 { 72 auto meter = runOnCode(q{ 73 interface I 74 { 75 } 76 }); 77 auto output = appender!string(); 78 auto reporter = meter.tryMatch!((Source source) => 79 FlatReporter!((string x) => output.put(x))(source)); 80 81 reporter.report(Threshold()); 82 83 assert(output.data.canFind("interface I")); 84 } 85 86 @("reports struct aggregate type") 87 unittest 88 { 89 auto meter = runOnCode(q{ 90 struct S 91 { 92 } 93 }); 94 auto output = appender!string(); 95 auto reporter = meter.tryMatch!((Source source) => 96 FlatReporter!((string x) => output.put(x))(source)); 97 98 reporter.report(Threshold()); 99 100 assert(output.data.canFind("struct S")); 101 } 102 103 @("reports class aggregate type") 104 unittest 105 { 106 auto meter = runOnCode(q{ 107 class C 108 { 109 } 110 }); 111 auto output = appender!string(); 112 auto reporter = meter.tryMatch!((Source source) => 113 FlatReporter!((string x) => output.put(x))(source)); 114 115 reporter.report(Threshold()); 116 117 assert(output.data.canFind("class C")); 118 } 119 120 @("reports union aggregate type") 121 unittest 122 { 123 auto meter = runOnCode(q{ 124 union U 125 { 126 char a; 127 byte b; 128 } 129 }); 130 auto output = appender!string(); 131 auto reporter = meter.tryMatch!((Source source) => 132 FlatReporter!((string x) => output.put(x))(source)); 133 134 reporter.report(Threshold()); 135 136 assert(output.data.canFind("union U")); 137 } 138 139 @("reports template aggregate type") 140 unittest 141 { 142 auto meter = runOnCode(q{ 143 template T() 144 { 145 } 146 }); 147 auto output = appender!string(); 148 auto reporter = meter.tryMatch!((Source source) => 149 FlatReporter!((string x) => output.put(x))(source)); 150 151 reporter.report(Threshold()); 152 153 assert(output.data.canFind("template T")); 154 } 155 156 @("FlatReporter reports only functions on function threshold violation") 157 unittest 158 { 159 auto meter = runOnCode(q{ 160 struct S 161 { 162 void f() 163 { 164 if (true) 165 { 166 } 167 else 168 { 169 } 170 } 171 172 void g() 173 { 174 if (true) 175 { 176 } 177 else 178 { 179 } 180 } 181 } 182 }); 183 auto output = appender!string(); 184 auto reporter = meter.tryMatch!((Source source) => 185 FlatReporter!((string x) => output.put(x))(source)); 186 187 reporter.report(Threshold(1, 0)); 188 189 assert(!output.data.canFind("struct S")); 190 } 191 192 @("FlatReporter reports only functions on function threshold violation if aggregate threshold is set") 193 unittest 194 { 195 auto meter = runOnCode(q{ 196 struct S 197 { 198 void f() 199 { 200 if (true) 201 { 202 } 203 else 204 { 205 } 206 } 207 208 void g() 209 { 210 if (true) 211 { 212 } 213 else 214 { 215 } 216 } 217 } 218 }); 219 auto output = appender!string(); 220 auto reporter = meter.tryMatch!((Source source) => 221 FlatReporter!((string x) => output.put(x))(source)); 222 223 reporter.report(Threshold(1, 10)); 224 225 assert(!output.data.canFind("struct S")); 226 }