1 /++ 2 A module containing the ProgressReporter 3 4 This is an example of how this reporter looks 5 <script type="text/javascript" src="https://asciinema.org/a/a3aspcv8cw5l04l59xw9vbtqa.js" id="asciicast-a3aspcv8cw5l04l59xw9vbtqa" async></script> 6 7 Copyright: © 2017 Szabo Bogdan 8 License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. 9 Authors: Szabo Bogdan 10 +/ 11 module trial.reporters.progress; 12 13 import std.stdio; 14 import std.array; 15 import std.conv; 16 import std.datetime; 17 import std..string; 18 import std.algorithm; 19 20 import trial.interfaces; 21 import trial.reporters.writer; 22 23 /// 24 struct ProgressGlyphs { 25 version(Windows) { 26 string empty = "."; 27 string fill = "#"; 28 } else { 29 string empty = "░"; 30 string fill = "▓"; 31 } 32 } 33 34 /// 35 string progressGlyphsToCode(ProgressGlyphs glyphs) { 36 return "ProgressGlyphs(`" ~ glyphs.empty ~ "`,`" ~ glyphs.fill ~ "`)"; 37 } 38 39 /// The “progress” reporter implements a simple progress-bar 40 class ProgressReporter : ITestCaseLifecycleListener, ILifecycleListener 41 { 42 private 43 { 44 ReportWriter writer; 45 ProgressGlyphs glyphs; 46 47 ulong testCount; 48 ulong currentTest; 49 bool success = true; 50 } 51 this(ProgressGlyphs glyphs) 52 { 53 writer = defaultWriter; 54 this.glyphs = glyphs; 55 } 56 57 this(ReportWriter writer) 58 { 59 this.writer = writer; 60 } 61 62 void begin(ulong testCount) 63 { 64 this.testCount = testCount; 65 writer.writeln(""); 66 draw; 67 } 68 69 void update() 70 { 71 72 } 73 74 void end(SuiteResult[]) 75 { 76 77 } 78 79 void begin(string suite, ref TestResult test) 80 { 81 } 82 83 void end(string suite, ref TestResult test) 84 { 85 currentTest++; 86 success = success && test.status == TestResult.Status.success; 87 draw; 88 } 89 90 private void draw() 91 { 92 int size = min((writer.width / 4) * 3, testCount); 93 size_t position = ((cast(double) currentTest / cast(double) testCount) * size).to!size_t; 94 95 writer.goTo(1); 96 97 writer.write(currentTest.to!string ~ "/" ~ testCount.to!string ~ " ", 98 success ? ReportWriter.Context.active : ReportWriter.Context.danger); 99 100 writer.write(glyphs.fill.replicate(position), ReportWriter.Context.active); 101 writer.writeln(glyphs.empty.replicate(size - position), ReportWriter.Context.inactive); 102 } 103 } 104 105 version (unittest) 106 { 107 version(Have_fluent_asserts) { 108 import fluent.asserts; 109 } 110 } 111 112 @("it should print 10 success tests") 113 unittest 114 { 115 auto writer = new BufferedWriter; 116 auto reporter = new ProgressReporter(writer); 117 118 auto suite = SuiteResult("some suite"); 119 auto test = new TestResult("some test"); 120 test.status = TestResult.Status.success; 121 reporter.begin(10); 122 123 writer.buffer.should.equal("0/10 ░░░░░░░░░░\n"); 124 125 foreach (i; 0 .. 10) 126 { 127 reporter.begin("some suite", test); 128 reporter.end("some suite", test); 129 } 130 131 writer.buffer.should.equal("10/10 ▓▓▓▓▓▓▓▓▓▓\n"); 132 }