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

Popular posts from this blog

Delphi XE2 Indy10 udp client-server interchange using SendBuffer-ReceiveBuffer -

Qt ActiveX WMI QAxBase::dynamicCallHelper: ItemIndex(int): No such property in -

Enable autocomplete or intellisense in Atom editor for PHP -