3
\$\begingroup\$

This is the problem:

Write a function to create a table from CSV data.

The input to the function is a list of strings. Each string is formatted as a CSV record. Here’s an example for a possible input:

Name;Street;City;Age
Peter Pan;Am Hang 5;12345 Einsam;42
Maria Schmitz;Kölner Straße 45;50123 Köln;43
Paul Meier;Münchener Weg 1;87654 München;65

In the input a semicolon separates values within a line. More complicated features of CSV (e.g. delimiters within a value) need not be implemented. The input always is correctly formatted; no validation necessary.

The output should be the data formatted as an “ASCII table”. The first record is interpreted as a header line. A separator line should follow the header line. The column width follows the longest value in a column (which includes the header). Here’s an example output for the above input:

Name         |Street          |City         |Age|
-------------+----------------+-------------+---+
Peter Pan    |Am Hang 5       |12345 Einsam |42 |
Maria Schmitz|Kölner Straße 45|50123 Köln   |43 |
Paul Meier   |Münchener Weg 1 |87654 München|65 |

And my implementation:

Tests:

describe("CV", function() {
  var CV = require('../../lib/cv/CV');
  var cv;
  var cvData;


  beforeEach(function() {    
    cvData = 
      `Name;Street;City;Age
Peter Pan;Am Hang 5;12345 Einsam;42
Maria Schmitz;Kölner Straße 45;50123 Köln;43
Paul Meier;Münchener Weg 1;87654 München;65`;
    cv = new CV(cvData);
  });

  it("should fetch table header data", function () {
    expect(cv.getHeader()).toEqual(["Name", "Street", "City", "Age"]);
  });

  it("should fetch table body data", function () {
    expect(cv.getBody()[0]).toEqual(["Peter Pan", "Am Hang 5", "12345 Einsam", "42"]);
    expect(cv.getBody()[1]).toEqual(["Maria Schmitz", "Kölner Straße 45", "50123 Köln", "43"]);
  });

  it("should calc columns max lenght", function () {
    expect(cv.calcColumnsMaxSize()).toEqual([13, 16, 13, 3]);
  });
});

describe("Table", function () {
    var Table = require('../../lib/cv/Table');
    var table;
    var cvData;

    beforeEach(function () {
        cvData =
            `Name;Street;City;Age
Peter Pan;Am Hang 5;12345 Einsam;42
Maria Schmitz;Kölner Straße 45;50123 Köln;43
Paul Meier;Münchener Weg 1;87654 München;65`;
        table = new Table();
    });

    it("should makes a column content", function () {
        let content = "test 1";
        let columnMaxSize = 10;
        expect(table.getColumnContent(content, columnMaxSize)).toBe("test 1    ")
    });
    it("should makes a row of header", function () {
        let contents = ["test 1", "test 2", "test 3"];
        let columnsMaxSizes = [10, 9, 15];
        expect(table.createHeader(contents, columnsMaxSizes)).
            toBe(`test 1    |test 2   |test 3         |\n----------+---------+----------------\n`)
    })
    it("should makes body rows", function () {
        let contents = [["test 1", "test 2", "test 3"], ["test 4", "test5", "test6"]];
        let columnsMaxSizes = [10, 9, 15];
        expect(table.createBody(contents, columnsMaxSizes)).
            toBe(`test 1    |test 2   |test 3         |\ntest 4    |test5    |test6          |\n`)
    });

});

And classes:

class CV{
  constructor(cvData) {
    this.cvRawData = cvData.split("\n");
    this.cvData = [];
    this.header = [];
    this.body = [];  
    this.columnsMaxSize;
    this.fetchHeaderColumns();
    this.fetchBodyColumns();
  }

  getHeader() {
    return this.header;
  }

  getBody() {
    return this.body;
  }

  fetchHeaderColumns() {
    this.header = this.cvRawData[0].split(";");
  }

  fetchBodyColumns() { 
    if (this.cvRawData.length <= 1)
      return;
    for (var i = 1; i < this.cvRawData.length; i++)
      this.body.push(this.cvRawData[i].split(";"));
  }

  calcColumnsMaxSize() {
    var columnsMaxSize = new Array(this.header.length).fill(0);    
    for (var j = 0; j < this.body.length; j++)
      for (var i = 0; i < columnsMaxSize.length; i++){
        if (this.body[j][i].length > columnsMaxSize[i])
          columnsMaxSize[i] = this.body[j][i].length;
      }
    for (var i = 0; i < columnsMaxSize.length; i++) {
      if (this.header[i].length > columnsMaxSize[i])
        columnsMaxSize[i] = this.header[i].length;
    }

    return columnsMaxSize;
  }
}
module.exports = CV;


class Table {

  getColumnContent(content, columnMaxSize) {
    return content + " ".repeat(columnMaxSize - content.length)
  }

  createHeader(contents, columnsMaxSizes) {
    let header = "";
    let separator = ""
    let totalCharactersSize = 0;
    for (let i = 0; i < contents.length; i++) {
      let columnContent = this.getColumnContent(contents[i], columnsMaxSizes[i]) + "|";
      header += columnContent;
      if (separator.length > 0) separator += "+";
      separator += "-".repeat(columnsMaxSizes[i]);
      totalCharactersSize += columnContent.length;
    }
    header += "\n" + separator + "-\n";
    return header;
  }

  createBody(contents, columnsMaxSizes) {
    let body = "";
    for (let i = 0; i < contents.length; i++) {
      for (let j = 0; j < columnsMaxSizes.length; j++) {
        body += this.getColumnContent(contents[i][j], columnsMaxSizes[j]) + "|";
      }
      body += "\n";
    }
    return body;
  }

  createTable(header, body, columnsMaxSizes) {
    let headerContent = this.createHeader(header, columnsMaxSizes);
    let bodyContent = this.createBody(body, columnsMaxSizes);
    return headerContent + bodyContent;
  }
}

module.exports = Table;

I'm new in BDD and even TDD. Please help me to do it correctly. Thank you

\$\endgroup\$
  • \$\begingroup\$ You ask whether your application is written in a correct way, but I assume you're asking whether it's written in a clean way. After all, you've written this TDD, so it should work as expected, right? \$\endgroup\$ – Mast May 26 at 11:06
  • \$\begingroup\$ Yes it is. I want to know if my senarios ans refactors are correct and clean enough. \$\endgroup\$ – Boolood May 26 at 12:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.