tcsdfdata.pp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. unit tcsdfdata;
  2. // Tests multiline functionality of sdfdataset
  3. {$mode objfpc}{$H+}
  4. interface
  5. uses
  6. Classes, SysUtils, Fpcunit, Testutils, Testregistry,
  7. dateutils, sdfdata;
  8. type
  9. { Ttestexport1 }
  10. Ttestexport1 = class(Ttestcase)
  11. protected
  12. TestDataset: TSDFDataset;
  13. procedure Setup; override;
  14. procedure Teardown; override;
  15. published
  16. procedure TestOutput;
  17. procedure TestInputOurFormat;
  18. procedure TestDelimitedTextOutput;
  19. end;
  20. implementation
  21. procedure Ttestexport1.TestOutput;
  22. const
  23. OutputFilename='output.csv';
  24. begin
  25. TestDataSet.Close;
  26. if FileExists(OutputFilename) then DeleteFile(OutputFileName);
  27. TestDataset.FileName:=OutputFileName;
  28. TestDataset.Open;
  29. // Fill test data
  30. TestDataset.Append;
  31. TestDataset.FieldByName('ID').AsInteger := 1;
  32. // Data with quotes
  33. TestDataset.FieldByName('NAME').AsString := 'J"T"';
  34. TestDataset.FieldByName('BIRTHDAY').AsDateTime := ScanDateTime('yyyymmdd', '19761231', 1);
  35. TestDataset.Post;
  36. TestDataset.Append;
  37. TestDataset.FieldByName('ID').AsInteger := 2;
  38. // Data with delimiter
  39. TestDataset.FieldByName('NAME').AsString := 'Hello'+TestDataset.Delimiter+' goodbye';
  40. TestDataset.FieldByName('BIRTHDAY').AsDateTime := ScanDateTime('yyyymmdd', '19761231', 1);
  41. TestDataset.Post;
  42. TestDataset.Append;
  43. TestDataset.FieldByName('ID').AsInteger := 3;
  44. //Data with delimiter and quote (to test 19376)
  45. TestDataset.FieldByName('NAME').AsString := 'Delimiter,"and";quote';
  46. TestDataset.FieldByName('BIRTHDAY').AsDateTime := ScanDateTime('yyyymmdd', '19761231', 1);
  47. TestDataset.Post;
  48. TestDataset.Append;
  49. TestDataset.FieldByName('ID').AsInteger := 4;
  50. // Regular data
  51. TestDataset.FieldByName('NAME').AsString := 'Just a long line of text without anything special';
  52. TestDataset.FieldByName('BIRTHDAY').AsDateTime := ScanDateTime('yyyymmdd', '19761231', 1);
  53. TestDataset.Post;
  54. TestDataset.Last;
  55. TestDataset.First;
  56. // This fails - seems it sees the header as a record, too?
  57. AssertEquals('Number of records in test dataset', 4, TestDataset.RecordCount);
  58. TestDataset.Close;
  59. end;
  60. procedure Ttestexport1.TestInputOurFormat;
  61. // Test if input works with our format
  62. // Mainly check if reading quotes is according to Delphi sdf specs and works.
  63. // See test results from bug 19610 for evidence that the strings below should work.
  64. // If this works, we can switch to this and be RFC 4180 compliant and Delphi compliant.
  65. const
  66. OutputFileName='input.csv';
  67. //Value1 is the on disk format; it should translate to Expected1
  68. Value1='"Delimiter,""and"";quote"';
  69. Expected1='Delimiter,"and";quote';
  70. Value2='"J""T"""';
  71. Expected2='J"T"';
  72. Value3='Just a long line';
  73. Expected3='Just a long line';
  74. //Note: Delphi can read this, see evidence in bug 19610 (the "quoted and space" value)
  75. Value4='"Just a quoted long line"';
  76. Expected4='Just a quoted long line';
  77. // Delphi can read multiline, see evidence in bug 19610 (the multiline entry)
  78. Value5='"quoted_multi'+#13+#10+'line"';
  79. Expected5='quoted_multi'+#13+#10+'line';
  80. Value6='"Delimiter,and;quoted"';
  81. Expected6='Delimiter,and;quoted';
  82. Value7='"A random""quote"';
  83. Expected7='A random"quote';
  84. var
  85. FileStrings: TStringList;
  86. begin
  87. TestDataset.Close;
  88. TestDataset.AllowMultiLine:=true;
  89. if FileExists(OutputFilename) then DeleteFile(OutputFileName);
  90. FileStrings:=TStringList.Create;
  91. try
  92. FileStrings.Add('ID,NAME,BIRTHDAY');
  93. FileStrings.Add('1,'+Value1+',31-12-1976');
  94. FileStrings.Add('2,'+Value2+',31-12-1976');
  95. FileStrings.Add('3,'+Value3+',31-12-1976');
  96. FileStrings.Add('4,'+Value4+',31-12-1976');
  97. FileStrings.Add('5,'+Value5+',31-12-1976');
  98. FileStrings.Add('6,'+Value6+',31-12-1976');
  99. FileStrings.Add('7,'+Value7+',31-12-1976');
  100. FileStrings.SaveToFile(OutputFileName);
  101. finally
  102. FileStrings.Free;
  103. end;
  104. // Load our dataset
  105. TestDataset.FileName:=OutputFileName;
  106. TestDataset.Open;
  107. TestDataset.First;
  108. AssertEquals(Expected1, TestDataSet.FieldByName('NAME').AsString);
  109. TestDataSet.Next;
  110. AssertEquals(Expected2, TestDataSet.FieldByName('NAME').AsString);
  111. TestDataSet.Next;
  112. AssertEquals(Expected3, TestDataSet.FieldByName('NAME').AsString);
  113. TestDataSet.Next;
  114. AssertEquals(Expected4, TestDataSet.FieldByName('NAME').AsString);
  115. TestDataSet.Next;
  116. AssertEquals(Expected5, TestDataSet.FieldByName('NAME').AsString);
  117. TestDataSet.Next;
  118. AssertEquals(Expected6, TestDataSet.FieldByName('NAME').AsString);
  119. TestDataSet.Next;
  120. AssertEquals(Expected7, TestDataSet.FieldByName('NAME').AsString);
  121. end;
  122. procedure Ttestexport1.TestDelimitedTextOutput;
  123. // Test if input works with our format
  124. // Mainly check if reading quotes is according to Delphi sdf specs and works.
  125. // See test results from bug 19610 for evidence that the strings below should work.
  126. // If this works, we can switch to this and be RFC 4180 compliant and Delphi compliant.
  127. const
  128. OutputFileName='delim.csv';
  129. //Value1 is the on disk format; it should translate to Expected1
  130. Value1='Delimiter,"and";quote';
  131. Value2='J"T"';
  132. Value3='Just a long line';
  133. Value4='Just a quoted long line';
  134. Value5='multi'+#13+#10+'line';
  135. Value6='Delimiter,and;done';
  136. Value7='Some "random" quotes';
  137. var
  138. FileStrings: TStringList;
  139. OneRecord: TStringList;
  140. begin
  141. TestDataset.Close;
  142. TestDataset.AllowMultiLine:=true;
  143. if FileExists(OutputFileName) then DeleteFile(OutputFileName);
  144. FileStrings:=TStringList.Create;
  145. OneRecord:=TStringList.Create;
  146. try
  147. FileStrings.Add('Field1,Field2,Field3,Field4,Field5,Field6,Field7');
  148. OneRecord.Add(Value1);
  149. OneRecord.Add(Value2);
  150. OneRecord.Add(Value3);
  151. OneRecord.Add(Value4);
  152. OneRecord.Add(Value5);
  153. OneRecord.Add(Value6);
  154. OneRecord.Add(Value7);
  155. OneRecord.Delimiter:=',';
  156. OneRecord.QuoteChar:='"';
  157. OneRecord.StrictDelimiter:=true;
  158. FileStrings.Add(OneRecord.DelimitedText);
  159. FileStrings.SaveToFile(OutputFileName);
  160. finally
  161. FileStrings.Free;
  162. OneRecord.Free;
  163. end;
  164. // Load our dataset
  165. TestDataset.FileName:=OutputFileName;
  166. TestDataset.Open;
  167. TestDataset.First;
  168. AssertEquals(Value1, TestDataSet.Fields[0].AsString);
  169. AssertEquals(Value2, TestDataSet.Fields[1].AsString);
  170. AssertEquals(Value3, TestDataSet.Fields[2].AsString);
  171. AssertEquals(Value4, TestDataSet.Fields[3].AsString);
  172. AssertEquals(Value5, TestDataSet.Fields[4].AsString);
  173. AssertEquals(Value6, TestDataSet.Fields[5].AsString);
  174. AssertEquals(Value7, TestDataSet.Fields[6].AsString);
  175. end;
  176. procedure Ttestexport1.Setup;
  177. begin
  178. TestDataset := TSDFDataset.Create(nil);
  179. TestDataset.Delimiter := ',';
  180. TestDataset.FileMustExist:=false;
  181. TestDataset.FirstLineAsSchema := True;
  182. TestDataset.Schema.Add('ID');
  183. TestDataset.Schema.Add('NAME');
  184. TestDataset.Schema.Add('BIRTHDAY');
  185. end;
  186. procedure Ttestexport1.Teardown;
  187. begin
  188. try
  189. TestDataset.Close;
  190. except
  191. //swallow
  192. end;
  193. TestDataset.Free;
  194. try
  195. //DeleteFile(FCSVFileName);
  196. except
  197. //swallow
  198. end;
  199. end;
  200. initialization
  201. Registertest(Ttestexport1);
  202. end.