Skip to content

Commit d23166d

Browse files
committed
first pass at using jest for testing
1 parent ca796e2 commit d23166d

File tree

4 files changed

+2093
-1142
lines changed

4 files changed

+2093
-1142
lines changed

src/danfojs-node/jest.config.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// @ts-check
2+
/** @type {import('jest').Config} */
3+
4+
const config = {
5+
preset: 'ts-jest',
6+
testEnvironment: 'node',
7+
testMatch: ['**/test/**/*.test.ts'],
8+
moduleFileExtensions: ['ts', 'js'],
9+
transform: {
10+
'^.+\\.ts$': ['ts-jest', {
11+
tsconfig: 'tsconfig.json'
12+
}]
13+
},
14+
globals: {
15+
'ts-jest': {
16+
tsconfig: 'tsconfig.json'
17+
}
18+
},
19+
coverageDirectory: 'coverage',
20+
collectCoverageFrom: [
21+
'src/**/*.ts',
22+
'!src/**/*.d.ts'
23+
]
24+
};
25+
26+
module.exports = config;

src/danfojs-node/package.json

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,24 @@
1919
"dist/"
2020
],
2121
"dependencies": {
22-
"@tensorflow/tfjs-node": "^3.13.0",
23-
"mathjs": "^9.4.4",
24-
"node-fetch": "^2.6.1",
25-
"papaparse": "^5.3.1",
22+
"@tensorflow/tfjs-node": "^4.22.0",
23+
"mathjs": "^14.4.0",
24+
"node-fetch": "2.6.7",
25+
"papaparse": "^5.5.2",
2626
"request": "^2.88.2",
27-
"stream-json": "^1.7.3",
28-
"table": "6.7.1",
29-
"xlsx": "https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz"
27+
"stream-json": "^1.9.1",
28+
"table": "6.9.0",
29+
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
3030
},
3131
"scripts": {
32-
"test": "nyc mocha --require ts-node/register test/**/*.test.ts",
32+
"test": "jest",
33+
"test:watch": "jest --watch",
34+
"test:coverage": "jest --coverage",
3335
"test:clean": "yarn build:clean && yarn test",
3436
"dev": "nodemon",
3537
"build": "tsc",
3638
"build:clean": "rm -rf ./dist && node ./scripts/prebuild.js && tsc",
3739
"lint": "eslint ./src",
38-
"coveralls": "cat ./coverage/lcov.info | ./node_modules/.bin/coveralls",
39-
"coverage": "nyc report --reporter=text-lcov | coveralls && nyc report --reporter=lcov",
4040
"patch": "npm version patch"
4141
},
4242
"publishConfig": {
@@ -67,33 +67,22 @@
6767
"@babel/plugin-transform-runtime": "^7.12.10",
6868
"@babel/preset-env": "^7.10.4",
6969
"@babel/register": "^7.10.1",
70-
"@types/chai": "^4.2.19",
71-
"@types/chai-as-promised": "^7.1.5",
72-
"@types/mocha": "^9.0.0",
73-
"@types/node": "^16.9.6",
74-
"@types/papaparse": "^5.2.6",
75-
"@types/request": "^2.48.7",
76-
"@types/stream-json": "^1.7.1",
70+
"@jest/globals": "^29.7.0",
71+
"@types/jest": "^29.5.12",
72+
"@types/node": "^20.14.0",
73+
"@types/papaparse": "^5.3.15",
74+
"@types/request": "^2.48.12",
75+
"@types/stream-json": "^1.7.8",
7776
"@types/table": "^6.3.2",
78-
"chai": "^4.2.0",
79-
"chai-as-promised": "^7.1.1",
80-
"coveralls": "^3.1.0",
8177
"dotenv": "^10.0.0",
8278
"dts-bundle-generator": "^5.9.0",
8379
"eslint": "^7.1.0",
84-
"mocha": "^7.2.0",
80+
"jest": "^29.7.0",
8581
"nodemon": "^2.0.7",
86-
"nyc": "^15.1.0",
8782
"rimraf": "^3.0.2",
88-
"ts-mocha": "^10.0.0",
89-
"ts-node": "^10.0.0",
90-
"typescript": "^4.4.2",
83+
"ts-jest": "^29.1.2",
84+
"ts-node": "^10.9.2",
85+
"typescript": "^5.8.2",
9186
"yarn": "^1.22.10"
92-
},
93-
"nyc": {
94-
"reporter": [
95-
"lcov",
96-
"text"
97-
]
9887
}
9988
}
Lines changed: 52 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
import path from "path";
2-
import chai, { assert, expect } from "chai";
3-
import { describe, it } from "mocha";
4-
import chaiAsPromised from "chai-as-promised";
52
import { DataFrame, readCSV, Series, streamCSV, toCSV, toJSON } from "../../dist/danfojs-node/src";
63
import fs from 'fs';
74
import process from 'process';
85

9-
chai.use(chaiAsPromised);
10-
11-
describe("readCSV", function () {
12-
this.timeout(10000);
6+
// Add Jest types for TypeScript support
7+
import { describe, expect, it } from '@jest/globals';
138

9+
describe("readCSV", () => {
1410
const testSamplesDir = path.join(process.cwd(), "test", "samples");
1511

16-
it("Read local csv file works", async function () {
12+
it("Read local csv file works", async () => {
1713
const filePath = path.join(testSamplesDir, "titanic.csv");
1814
let df = await readCSV(filePath, { header: true, preview: 5 });
19-
assert.deepEqual(df.shape, [5, 8]);
20-
assert.deepEqual(df.columns, [
15+
expect(df.shape).toEqual([5, 8]);
16+
expect(df.columns).toEqual([
2117
'Survived',
2218
'Pclass',
2319
'Name',
@@ -27,15 +23,15 @@ describe("readCSV", function () {
2723
'Parents/Children Aboard',
2824
'Fare'
2925
]);
30-
assert.deepEqual(df.dtypes, [
26+
expect(df.dtypes).toEqual([
3127
'int32', 'int32',
3228
'string', 'string',
3329
'int32', 'int32',
3430
'int32', 'float32'
3531
]);
3632
});
3733

38-
it("Read local CSV file with config works", async function () {
34+
it("Read local CSV file with config works", async () => {
3935
const filePath = path.join(testSamplesDir, "titanic.csv");
4036
const frameConfig = {
4137
columns: [
@@ -50,8 +46,8 @@ describe("readCSV", function () {
5046
]
5147
};
5248
let df = await readCSV(filePath, { frameConfig, header: true, preview: 5 });
53-
assert.deepEqual(df.shape, [5, 8]);
54-
assert.deepEqual(df.columns, [
49+
expect(df.shape).toEqual([5, 8]);
50+
expect(df.columns).toEqual([
5551
'A',
5652
'B',
5753
'C',
@@ -61,15 +57,15 @@ describe("readCSV", function () {
6157
'G',
6258
'H'
6359
]);
64-
assert.deepEqual(df.dtypes, [
60+
expect(df.dtypes).toEqual([
6561
'int32', 'int32',
6662
'string', 'string',
6763
'int32', 'int32',
6864
'int32', 'float32'
6965
]);
7066
});
7167

72-
it("Read local csv with correct types and format works", async function () {
68+
it("Read local csv with correct types and format works", async () => {
7369
const filePath = path.join(testSamplesDir, "iris.csv");
7470
let df = await readCSV(filePath, { header: true, preview: 5 });
7571
const values = [
@@ -79,105 +75,50 @@ describe("readCSV", function () {
7975
[4.6, 3.1, 1.5, 0.2, 0.0],
8076
[5.0, 3.6, 1.4, 0.2, 0.0]
8177
];
82-
assert.deepEqual(df.values, values);
78+
expect(df.values).toEqual(values);
8379
});
8480

85-
it("Throws error if file not found", async function () {
81+
it("Throws error if file not found", async () => {
8682
const filePath = "notfound.csv";
87-
await expect(readCSV(filePath)).to.be.rejectedWith("ENOENT: no such file or directory");
83+
await expect(readCSV(filePath)).rejects.toThrow("ENOENT: no such file or directory");
8884
});
8985

90-
it("Throws error if file not found over http", async function () {
86+
it("Throws error if file not found over http", async () => {
9187
const filePath = "https://getdata.com/notfound.csv";
92-
await expect(readCSV(filePath)).to.be.rejectedWith(/HTTP \d+:/);
88+
await expect(readCSV(filePath)).rejects.toThrow(/HTTP \d+:/);
9389
});
9490

95-
it("Throws error when reading empty CSV file", async function () {
91+
it("Throws error when reading empty CSV file", async () => {
9692
const filePath = path.join(testSamplesDir, "empty.csv");
9793
// Create empty file
9894
fs.writeFileSync(filePath, "");
99-
await expect(readCSV(filePath)).to.be.rejectedWith("No data found in CSV file");
95+
await expect(readCSV(filePath)).rejects.toThrow("No data found in CSV file");
10096
fs.unlinkSync(filePath); // Clean up
10197
});
10298

103-
it("Throws error when reading malformed CSV", async function () {
99+
it("Throws error when reading malformed CSV", async () => {
104100
const filePath = path.join(testSamplesDir, "malformed.csv");
105101
// Create malformed CSV file
106102
fs.writeFileSync(filePath, "a,b,c\n1,2\n3,4,5,6");
107-
await expect(readCSV(filePath)).to.be.rejectedWith("CSV parsing errors");
103+
await expect(readCSV(filePath)).rejects.toThrow("CSV parsing errors");
108104
fs.unlinkSync(filePath); // Clean up
109105
});
110106

111-
it("Throws error when DataFrame creation fails", async function () {
107+
it("Throws error when DataFrame creation fails", async () => {
112108
const filePath = path.join(testSamplesDir, "invalid.csv");
113-
await expect(readCSV(filePath)).to.be.rejectedWith("ENOENT: no such file or directory");
114-
});
115-
116-
it("Preserves leading zeros when dtype is string", async function () {
117-
const filePath = path.join(testSamplesDir, "leading_zeros.csv");
118-
// Create test CSV file
119-
fs.writeFileSync(filePath, "codes\n012345\n001234");
120-
121-
try {
122-
const df = await readCSV(filePath, {
123-
frameConfig: {
124-
dtypes: ["string"]
125-
}
126-
});
127-
128-
assert.deepEqual(df.values, [["012345"], ["001234"]]);
129-
assert.deepEqual(df.dtypes, ["string"]);
130-
131-
// Verify the values are actually strings
132-
const jsonData = toJSON(df);
133-
assert.deepEqual(jsonData, [{ codes: "012345" }, { codes: "001234" }]);
134-
135-
// Clean up
136-
fs.unlinkSync(filePath);
137-
} catch (error) {
138-
// Clean up even if test fails
139-
fs.unlinkSync(filePath);
140-
throw error;
141-
}
142-
});
143-
144-
it("Converts to numbers when dtype is not string", async function () {
145-
const filePath = path.join(testSamplesDir, "leading_zeros.csv");
146-
// Create test CSV file
147-
fs.writeFileSync(filePath, "codes\n012345\n001234");
148-
149-
try {
150-
const df = await readCSV(filePath); // default behavior without string dtype
151-
152-
// Values should be converted to numbers
153-
assert.deepEqual(df.values, [[12345], [1234]]);
154-
assert.deepEqual(df.dtypes, ["int32"]);
155-
156-
// Verify JSON output
157-
const jsonData = toJSON(df);
158-
assert.deepEqual(jsonData, [{ codes: 12345 }, { codes: 1234 }]);
159-
160-
// Clean up
161-
fs.unlinkSync(filePath);
162-
} catch (error) {
163-
// Clean up even if test fails
164-
fs.unlinkSync(filePath);
165-
throw error;
166-
}
109+
await expect(readCSV(filePath)).rejects.toThrow("ENOENT: no such file or directory");
167110
});
168111
});
169112

170-
describe("streamCSV", function () {
171-
this.timeout(100000);
172-
113+
describe("streamCSV", () => {
173114
const testSamplesDir = path.join(process.cwd(), "test", "samples");
174115

175-
it("Streaming local csv file with callback works", async function () {
116+
it("Streaming local csv file with callback works", async () => {
176117
const filePath = path.join(testSamplesDir, "titanic.csv");
177118
await streamCSV(filePath, (df) => {
178119
if (df) {
179-
assert.deepEqual(df.shape, [1, 8]);
180-
assert.deepEqual(df.columns, [
120+
expect(df.shape).toEqual([1, 8]);
121+
expect(df.columns).toEqual([
181122
'Survived',
182123
'Pclass',
183124
'Name',
@@ -188,58 +129,68 @@ describe("streamCSV", function () {
188129
'Fare'
189130
]);
190131
} else {
191-
assert.deepEqual(df, null);
132+
expect(df).toBeNull();
192133
}
193134
}, { header: true });
194135
});
195136

196-
it("Throws error when streaming non-existent file", async function () {
137+
it("Throws error when streaming non-existent file", async () => {
197138
const filePath = "notfound.csv";
198-
await expect(streamCSV(filePath, () => {})).to.be.rejectedWith("ENOENT: no such file or directory");
139+
await expect(streamCSV(filePath, () => {})).rejects.toThrow("ENOENT: no such file or directory");
199140
});
200141

201-
it("Throws error when streaming malformed CSV", async function () {
142+
it("Throws error when streaming malformed CSV", async () => {
202143
const filePath = path.join(testSamplesDir, "malformed_stream.csv");
203144
// Create malformed CSV file
204145
fs.writeFileSync(filePath, "a,b,c\n1,2\n3,4,5,6");
205-
await expect(streamCSV(filePath, () => {})).to.be.rejectedWith("CSV parsing errors");
146+
await expect(streamCSV(filePath, () => {})).rejects.toThrow("CSV parsing errors");
206147
fs.unlinkSync(filePath); // Clean up
207148
});
208149
});
209150

210-
describe("toCSV", function () {
151+
describe("toCSV", () => {
211152
const testSamplesDir = path.join(process.cwd(), "test", "samples");
212153

213-
it("toCSV works", async function () {
154+
it("toCSV works", async () => {
214155
const data = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]];
215156
let df = new DataFrame(data, { columns: ["a", "b", "c", "d"] });
216-
assert.deepEqual(toCSV(df, {}), `a,b,c,d\n1,2,3,4\n5,6,7,8\n9,10,11,12\n`);
157+
expect(toCSV(df, {})).toBe(`a,b,c,d\n1,2,3,4\n5,6,7,8\n9,10,11,12\n`);
217158
});
218159

219-
it("toCSV works for specified separator", async function () {
160+
it("toCSV works for specified separator", async () => {
220161
const data = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]];
221162
let df = new DataFrame(data, { columns: ["a", "b", "c", "d"] });
222-
assert.deepEqual(toCSV(df, { sep: "+" }), `a+b+c+d\n1+2+3+4\n5+6+7+8\n9+10+11+12\n`);
163+
expect(toCSV(df, { sep: "+" })).toBe(`a+b+c+d\n1+2+3+4\n5+6+7+8\n9+10+11+12\n`);
223164
});
224165

225-
it("toCSV write to local file works", async function () {
166+
it("toCSV write to local file works", async () => {
226167
const data = [[1, 2, 3, "4"], [5, 6, 7, "8"], [9, 10, 11, "12"]];
227168
let df = new DataFrame(data, { columns: ["a", "b", "c", "d"] });
228169
const filePath = path.join(testSamplesDir, "test_write.csv");
170+
171+
// Write file
229172
toCSV(df, { sep: ",", filePath });
173+
174+
// Verify file was written
175+
expect(fs.existsSync(filePath)).toBe(true);
176+
177+
// Read and verify contents
178+
const fileContent = fs.readFileSync(filePath, 'utf-8');
179+
expect(fileContent).toBe(`a,b,c,d\n1,2,3,4\n5,6,7,8\n9,10,11,12\n`);
180+
230181
// Clean up
231182
fs.unlinkSync(filePath);
232183
});
233184

234-
it("toCSV works for series", async function () {
185+
it("toCSV works for series", async () => {
235186
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
236187
let df = new Series(data);
237-
assert.deepEqual(toCSV(df, { sep: "+" }), `1+2+3+4+5+6+7+8+9+10+11+12`);
188+
expect(toCSV(df, { sep: "+" })).toBe(`1+2+3+4+5+6+7+8+9+10+11+12`);
238189
});
239190

240-
it("calling df.toCSV works", async function () {
191+
it("calling df.toCSV works", async () => {
241192
const data = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]];
242193
let df = new DataFrame(data, { columns: ["a", "b", "c", "d"] });
243-
assert.deepEqual(df.toCSV(), `a,b,c,d\n1,2,3,4\n5,6,7,8\n9,10,11,12\n`);
194+
expect(df.toCSV()).toBe(`a,b,c,d\n1,2,3,4\n5,6,7,8\n9,10,11,12\n`);
244195
});
245196
});

0 commit comments

Comments
 (0)