c# - A complex string splitter- How do I make this working code better? -
i have below program
class program { static void main(string[] args) { list<assembly> failedassemblies = loadassembly(); string batchfile = "d:\\1" + ".bat"; filestream fs = file.create(batchfile); fs.close(); using (streamwriter outfile = new streamwriter(batchfile)) { string command = @"echo off"; outfile.writeline(command); process(outfile, failedassemblies); } } private static void process(streamwriter outfile, list<assembly> assemblieslist) { string command = "mstest.exe "; string testcontainer = " /testcontainer:"; list<string> testcontainerassemblies = new list<string>(4); outfile.writeline("set path=%mstestpath%"); foreach (assembly assmbly in assemblieslist) { command = string.empty; if (!testcontainerassemblies.contains(assmbly.assemblyname)) { outfile.writeline(' '); testcontainerassemblies.add(assmbly.assemblyname); command = "mstest.exe "; command += testcontainer + "\\" + assmbly.assemblyname + " "; command += "/resultsfile:\"" + "\\resultfile_" + assmbly.assemblyname.replace(".dll", "") + "_" + "1".tostring() + ".trx\""; command += " /runconfig:"; command += " /detail:owner"; command += " /detail:duration"; command += " /detail:description"; command += " /unique "; } command += " /test:" + assmbly.namespacename + "." + assmbly.classname + "." + assmbly.functionname; outfile.write(command); } } private static list<assembly> loadassembly() { var assemblycollection = new list<assembly>(); assemblycollection.add(new assembly { assemblyname = "accounttestbase.dll", namespacename = "ecardtest", classname = "ecardtest", functionname = "ecardtestdownloadpkgsuccess" }); assemblycollection.add(new assembly { assemblyname = "accounttestbase.dll", namespacename = "accounttest", classname = "iaccounttest", functionname = "somefunc" }); assemblycollection.add(new assembly { assemblyname = "testpayment.dll", namespacename = "testpayment", classname = "creditcardtestcases", functionname = "boletofunctionaltestcase" }); assemblycollection.add(new assembly { assemblyname = "testpayment.dll", namespacename = "testpayment", classname = "creditcardtestcases", functionname = "boletoendtoendfunctionaltestcase" }); assemblycollection.add(new assembly { assemblyname = "testpayment.dll", namespacename = "testpayment", classname = "creditcardtestcases", functionname = "boletopurcahsetestcase" }); assemblycollection.add(new assembly { assemblyname = "testpayment.dll", namespacename = "testpayment", classname = "creditcardtestcases", functionname = "creditcard_resumeorder_success" }); assemblycollection.add(new assembly { assemblyname = "testpayment.dll", namespacename = "testpayment", classname = "creditcardtestcases", functionname = "creditcard_eurcurr_usbilling_enus" }); assemblycollection.add(new assembly { assemblyname = "testpayment.dll", namespacename = "testpayment", classname = "creditcardtestcases", functionname = "dinersclubpayment" }); return assemblycollection; } } public class assembly { public string assemblyname { get; set; } public string classname { get; set; } public string functionname { get; set; } public string namespacename { get; set; } }
it generates below output
echo off set path=%mstestpath% mstest.exe /testcontainer:\accounttestbase.dll /resultsfile:"\resultfile_accounttestbase_1.trx" /runconfig: /detail:owner /detail:duration /detail:description /unique /test:ecardtest.ecardtest.ecardtestdownloadpkgsuccess /test:accounttest.iaccounttest.somefunc mstest.exe /testcontainer:\testpayment.dll /resultsfile:"\resultfile_testpayment_1.trx" /runconfig: /detail:owner /detail:duration /detail:description /unique /test:testpayment.creditcardtestcases.boletofunctionaltestcase /test:testpayment.creditcardtestcases.boletoendtoendfunctionaltestcase /test:testpayment.creditcardtestcases.boletopurcahsetestcase /test:testpayment.creditcardtestcases.creditcard_resumeorder_success /test:testpayment.creditcardtestcases.creditcard_eurcurr_usbilling_enus /test:testpayment.creditcardtestcases.dinersclubpayment
now new requirement has come need break output based on limits passed.
say if limit 300, output be
echo off set path=%mstestpath% mstest.exe /testcontainer:\accounttestbase.dll /resultsfile:"\resultfile_accounttestbase_1.trx" /runconfig: /detail:owner /detail:duration /detail:description /unique /test:ecardtest.ecardtest.ecardtestdownloadpkgsuccess mstest.exe /testcontainer:\testpayment.dll /resultsfile:"\resultfile_testpayment_1.trx" /runconfig: /detail:owner /detail:duration /detail:description /unique /test:testpayment.creditcardtestcases.boletofunctionaltestcase /test:testpayment.creditcardtestcases.boletoendtoendfunctionaltestcase mstest.exe /testcontainer:\testpayment.dll /resultsfile:"\resultfile_testpayment_1.trx" /runconfig: /detail:owner /detail:duration /detail:description /unique /test:testpayment.creditcardtestcases.boletopurcahsetestcase /test:testpayment.creditcardtestcases.creditcard_resumeorder_success /test:testpayment.creditcardtestcases.creditcard_eurcurr_usbilling_enus /test:testpayment.creditcardtestcases.dinersclubpayment
i.e. firstone has total character limit of 210(approx) , henceforth remain same. second 1 has crossed limit , needs splited 2 parts. first 1 got split on (290) because adding 1 more command cross limit.that's why need split 2 parts.
one more point tell that, cannot split precisely based on limit value provided. because mstest command needs run. henceforth,
"mstest.exe /testcontainer:\testpayment.dll /resultsfile:"\resultfile_testpayment_1.trx" /runconfig: /detail:owner /detail:duration /detail:description /unique"
come , "test/..."
how same in c#?
myshot(please improve it)
private static void process(streamwriter outfile, list<assembly> failedassemblies) { int maxlimit = 2000; string command = "mstest.exe "; string testcontainer = " /testcontainer:"; list<string> testcontainerassemblies = new list<string>(4); int sum = 0; outfile.writeline("set path=%mstestpath%"); var failedassemblycollections = (from x in failedassemblies group x x.assemblyname g select new { assemblynames = g.key, fullyqualifiedtestmethods = g.select(i => " /test:" + i.namespacename + "." + i.classname + "." + i.functionname), fullyqualifiedtestmethodslen = g.select(i => convert.tostring(" /test:" + i.namespacename + "." + i.classname + "." + i.functionname).length) }); foreach (var item in failedassemblycollections) { var assemblynames = item.assemblynames; var methodslengths = item.fullyqualifiedtestmethodslen.tolist(); var flag = true; int counter = 0; //write first time if (flag) { write(outfile, ref command, testcontainer, assemblynames); flag = false; } (int = 0; < methodslengths.count; i++) { sum += methodslengths[i]; if (sum <= maxlimit) { command += item.fullyqualifiedtestmethods.tolist()[i]; //this execute when long command splitted , written in new trx files if (flag) { counter++; write(outfile, ref command, testcontainer, assemblynames); flag = false; } } //if value crosses max limit //write current output //then reset variables original if (sum >= maxlimit) { outfile.write(command); sum = 0; flag = true; i--; } } outfile.write(command); } } private static void write(streamwriter outfile, ref string command, string testcontainer, string assemblynames) { outfile.writeline(' '); command = "mstest.exe "; command += testcontainer + "\\" + assemblynames + " "; command += " /runconfig:"; command += " /detail:owner"; command += " /detail:duration"; command += " /detail:description"; command += " /unique "; }
a very rough example hammered out here. have not tested edge cases such as: line length close or limit, or when single test case exceeds limit. i'll leave exercises you.
sometimes easiest write out unit tests, spit out standard loops , length checks pass tests, play around linq or regex or code cleanup maintainable , readable.
string input = @"mstest.exe /testcontainer:\testpayment.dll /resultsfile:""\resultfile_testpayment_1.trx"" /runconfig: /detail:owner /detail:duration /detail:description /unique /test:testpayment.creditcardtestcases.boletofunctionaltestcase /test:testpayment.creditcardtestcases.boletoendtoendfunctionaltestcase /test:testpayment.creditcardtestcases.boletopurcahsetestcase /test:testpayment.creditcardtestcases.creditcard_resumeorder_success /test:testpayment.creditcardtestcases.creditcard_eurcurr_usbilling_enus /test:testpayment.creditcardtestcases.dinersclubpayment"; const int line_limit = 300; const string test_marker = " /test:"; int testindex = input.indexof(test_marker); string prefix = input.substring(0, testindex); int availablecharacters = line_limit - prefix.length; queue<string> tests = new queue<string>(input.substring(testindex).split(new []{test_marker}, stringsplitoptions.removeemptyentries)); list<string> testsets = new list<string>(); string currenttest = ""; while (tests.count > 0) { //restores test marker splitting string test = test_marker + tests.dequeue(); if (currenttest.length + test.length > availablecharacters) { testsets.add(currenttest); currenttest = ""; } else { currenttest += test; } } if (currenttest != "") { testsets.add(currenttest); } var lines = testsets.select(t => prefix + t).tolist(); //your line outputs
Comments
Post a Comment