1 /*************************************************************** 2 * Features for unit testing 3 * 4 * Fine-tune the output destination of coverage, etc. 5 */ 6 module examples.ut; 7 8 debug shared static this() 9 { 10 import core.stdc.stdio; 11 setvbuf(stdout, null, _IONBF, 0); 12 } 13 /// 14 version (D_Coverage) 15 { 16 private extern (C) void dmd_coverDestPath( string pathname ); 17 private extern (C) void dmd_coverSourcePath( string pathname ); 18 private extern (C) void dmd_coverSetMerge( bool flag ); 19 20 private struct CovOpt 21 { 22 string dir; 23 bool merge; 24 } 25 26 private CovOpt getCovOptFromString(string str) 27 { 28 import std.string, std.getopt, std.algorithm, std.array; 29 CovOpt ret; 30 auto args = [""] ~ str.splitLines.map!(a => a.strip).filter!(a => a.length > 0).array; 31 args.getopt( 32 config.caseSensitive, 33 config.bundling, 34 config.passThrough, 35 "d|dir|coverage_dir", &ret.dir, 36 "m|merge|coverage_merge", &ret.merge); 37 return ret; 38 } 39 40 @system unittest 41 { 42 auto opt = getCovOptFromString(` 43 -d=xxx 44 `); 45 assert(opt.dir == "xxx"); 46 assert(!opt.merge); 47 opt = getCovOptFromString(` 48 --dir=cov 49 --xxx 50 -m 51 `); 52 assert(opt.dir == "cov"); 53 assert(opt.merge); 54 opt = getCovOptFromString(null); 55 assert(opt.dir.length == 0); 56 assert(!opt.merge); 57 58 opt = getCovOptFromString(`-md=xxx`); 59 assert(opt.dir == "xxx"); 60 assert(opt.merge); 61 62 } 63 64 private CovOpt getCovOpt(string[] searchDirs = ["."], string[] searchFileNames = [".coverageopt"]) 65 { 66 import std.file, std.path; 67 CovOpt ret; 68 foreach (d; searchDirs) 69 { 70 foreach (f; searchFileNames) 71 { 72 auto filepath = d.buildPath(f); 73 if (filepath.exists && filepath.isFile) 74 { 75 ret = getCovOptFromString(readText(filepath)); 76 break; 77 } 78 } 79 if (ret.dir.length == 0 && d.exists && d.isDir) 80 { 81 ret.dir = d; 82 break; 83 } 84 } 85 return ret; 86 } 87 88 @system unittest 89 { 90 import std.file, std.path; 91 auto opt = getCovOpt(["."], ["nul"]); 92 assert(opt.dir == "."); 93 assert(!opt.merge); 94 95 auto dir = "._._._workdir_._._"; 96 auto file = ".dat"; 97 dir.mkdir(); 98 scope (exit) 99 dir.rmdirRecurse(); 100 dir.buildPath(file).write("-d=dir"); 101 opt = getCovOpt([dir], [file]); 102 assert(opt.dir == "dir"); 103 assert(!opt.merge); 104 } 105 106 private CovOpt getCovOpt(string[string] env) 107 { 108 import std.algorithm, std.string; 109 CovOpt ret; 110 if (auto p = "COVERAGE_DIR" in env) 111 ret.dir = strip(*p); 112 if (auto p = "COVERAGE_MERGE" in env) 113 ret.merge = ["merge", "true", "yes"].any!(a => a == *p ); 114 return ret; 115 } 116 117 @system unittest 118 { 119 auto opt = getCovOpt(["COVERAGE_DIR": "xxx", "COVERAGE_MERGE": "yes"]); 120 assert(opt.dir == "xxx" && opt.merge); 121 122 opt = getCovOpt(["COVERAGE_DIR": "aaa", "COVERAGE_MERGE": "true"]); 123 assert(opt.dir == "aaa" && opt.merge); 124 125 opt = getCovOpt(["COVERAGE_MERGE": "merge"]); 126 assert(opt.dir.length == 0 && opt.merge); 127 128 opt = getCovOpt(["COVERAGE_DIR": "xxx", "COVERAGE_MERGE": "aaa"]); 129 assert(opt.dir == "xxx" && !opt.merge); 130 131 opt = getCovOpt(["COVERAGE_DIR": "xxx"]); 132 assert(opt.dir == "xxx" && !opt.merge); 133 } 134 135 private CovOpt getCovOpt(string[string] env, string[] searchDirs, string[] searchFileNames) 136 { 137 auto opt = getCovOpt(env); 138 if (opt.dir.length > 0) 139 return opt; 140 return getCovOpt(searchDirs, searchFileNames); 141 } 142 143 @system unittest 144 { 145 auto opt = getCovOpt(["xx": "yy"], ["."], [".xxx"]); 146 assert(opt.dir == "."); 147 opt = getCovOpt(["COVERAGE_DIR": "yy"], ["."], [".xxx"]); 148 assert(opt.dir == "yy"); 149 } 150 151 152 private CovOpt getCovOpt() 153 { 154 import std.process, std.path, std.file; 155 return getCovOpt(environment.toAA, [".", 156 thisExePath.dirName.buildPath("cov"), 157 thisExePath.dirName.buildPath(".cov"), 158 "cov", ".cov", "."], [".coverageopt"]); 159 } 160 161 shared static this() 162 { 163 import std.file, std.path; 164 auto covopt = getCovOpt(); 165 if (covopt.dir.length > 0) 166 { 167 enum rootDir = __FILE_FULL_PATH__.dirName.dirName.buildNormalizedPath(); 168 if (!covopt.dir.exists) mkdirRecurse(covopt.dir); 169 dmd_coverSetMerge(covopt.merge); 170 dmd_coverSourcePath(rootDir); 171 dmd_coverDestPath(covopt.dir); 172 } 173 } 174 }