Anders Tornblad

All about the code

JavaScript Csv file generator, part 3

The Csv file generator is almost done. All we need to do is to enclose and escape certain special characters. Values containing the separator need to be enclosed in double quotes. Values containing double quotes need to be escaped and, just to be sure, enclosed in double quotes.

Two more requirements and two more unit tests coming up...

Requirements

  1. Values containing the current separator must be enclosed in double quotes.
  2. Values containing double quotes must be escaped (by doubling the double quote characters), and also enclosed in double quotes.
engine.add("Csv.getFileContents should quote fields containing the separator", function(testContext, the) { // Arrange var properties = ["name", "age"]; var csv = new Csv(properties); csv.add({"name" : "Doe, John", "age" : "Unknown"}); csv.add({"name" : "Bunny", "age" : "2"}); // Act var file = csv.getFileContents(); // Assert the(file).shouldBeSameAs("\"Doe, John\",Unknown\r\nBunny,2"); }); engine.add("Csv.getFileContents should quote and escape fields containing double quotes", function(testContext, the) { // Arrange var properties = ["model", "size"]; var csv = new Csv(properties); csv.add({"model" : "Punysonic", "size" : "28\""}); csv.add({"model" : "Philip", "size" : "42\""}); // Act var file = csv.getFileContents(); // Assert the(file).shouldBeSameAs('Punysonic,"28"""\r\nPhilip,"42"""'); }); // Helper function to create one line of text function createTextLine(values, separator) { var result = []; var doubleQuotes = new RegExp("\"", "g"); values.forEach(function(value) { var text = value.toString(); if (text.indexOf(separator) == -1 && text.indexOf("\"") == -1) { result.push(text); } else { result.push("\"" + text.replace(doubleQuotes, "\"\"") + "\""); } }); return result.join(separator); } // New getFileContents implementation Csv.prototype.getFileContents = function(separator, includePropertyNames) { separator = separator || ","; var textLines = []; if (includePropertyNames) { textLines.push(createTextLine(this.propertyOrder, separator)); } this.items.forEach((function(item) { var values = []; this.propertyOrder.forEach(function(propertyName) { values.push(item[propertyName]); }); textLines.push(createTextLine(values, separator)); }).bind(this)); return textLines.join("\r\n"); };

And we're done! EDIT: The finished code can be found on github at /lbrtw/csv.

JavaScript Csv file generator, part 1
JavaScript Csv file generator, part 2
JavaScript Csv file generator, part 3 (this part)

Add a comment