diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 0000000..a7dfac5 --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,24 @@ +name: Integration + +on: + push: + branches: ['main'] + pull_request: + branches: ['main'] + +jobs: + testing: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20.x] + + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + - run: npm run test \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..f26d4d2 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "nodetest", + "version": "1.0.0", + "description": "", + "main": "src/index.js", + "type": "module", + "scripts": { + "test": "node --experimental-test-coverage --test src/tests/" + }, + "keywords": [], + "author": "", + "license": "ISC" +} \ No newline at end of file diff --git a/src/fetchDemo.js b/src/fetchDemo.js new file mode 100644 index 0000000..5547310 --- /dev/null +++ b/src/fetchDemo.js @@ -0,0 +1,15 @@ +async function fetchDemo() { + const response = await fetch("https://jsonplaceholder.typicode.com/todos/1") + + if (!response.ok) { + const message = `An error has occured: ${response.statusText}` + throw new Error(message) + } + + const data = await response.json() + console.log(data) +} + +fetchDemo().catch(function (error) { + console.log(error.message) +}) \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..dffc010 --- /dev/null +++ b/src/index.js @@ -0,0 +1,27 @@ +class MakeRequest { + constructor() { } + static async fetchDataFromAPI(id) { + const response = await fetch(`https://jsonplaceholder.typicode.com/todos/1`) + + if (!response.ok) { + const message = `An error has occured: ${response.statusText}` + throw new Error(message) + } + + const todo = await response.json() + return todo + } + + static slugifyTitle(todo) { + const slug = `${todo.title.replace(/ /g, "-")}${todo.id}` + return { ...todo, slug } + } + + static async addToDB() { + const todo = await this.fetchDataFromAPI() + this.slugifyTitle(todo) + return this.slugifyTitle(todo) + } +} + +export default MakeRequest diff --git a/src/parallelFetch.js b/src/parallelFetch.js new file mode 100644 index 0000000..c147742 --- /dev/null +++ b/src/parallelFetch.js @@ -0,0 +1,21 @@ +async function fetchTodos() { + const [res1, res2, res3] = await Promise.all([ + fetch("https://jsonplaceholder.typicode.com/todos/1"), + fetch("https://jsonplaceholder.typicode.com/todos/2"), + fetch("https://jsonplaceholder.typicode.com/todos/3") + ]) + + if (!res1.ok || !res2.ok || !res3.ok) { + throw new Error("An error has occured while fetching todos") + } + + const todo1 = await res1.json() + const todo2 = await res2.json() + const todo3 = await res3.json() + + console.log([todo1, todo2, todo3]) +} + +fetchTodos().catch(function (error) { + console.log(error.message) +}) \ No newline at end of file diff --git a/src/tests/basic.test.js b/src/tests/basic.test.js new file mode 100644 index 0000000..dacbfb1 --- /dev/null +++ b/src/tests/basic.test.js @@ -0,0 +1,22 @@ +import { test, describe, it } from "node:test" +import assert from "node:assert" + +test("some test", function (t) { + assert.strictEqual(1, 1) +}) + +test("second basic test", function () { + assert.equal(2, 2) +}) + +// group test +describe("testing", function () { + it("some test", function () { + assert.strictEqual(1, 1) + }) +}) + +// skip test +test.skip("Skipping tests", function () { + assert.notEqual(1, 1) +}) \ No newline at end of file diff --git a/src/tests/makeRequest.test.js b/src/tests/makeRequest.test.js new file mode 100644 index 0000000..a3015b8 --- /dev/null +++ b/src/tests/makeRequest.test.js @@ -0,0 +1,45 @@ +import { test, describe, it, mock, beforeEach } from "node:test" +import assert from "node:assert" +import MakeRequest from "../index.js" + +describe("testing", function () { + beforeEach(() => mock.restoreAll()) + it("fetchDataFromAPI should return a product", async function (t) { + mock + .method(MakeRequest, MakeRequest.fetchDataFromAPI.name) + .mock.mockImplementation(async function () { + return { userId: 1, id: 1, title: 'delectus aut autem', completed: false } + }) + + const res = await MakeRequest.fetchDataFromAPI() + assert.strictEqual(res.userId, 1) + assert.strictEqual(res.completed, false) + }) + + it("fetchDataFromAPI should return product with given ID", async function (t) { + const id = 3 + mock + .method(MakeRequest, MakeRequest.fetchDataFromAPI.name) + .mock.mockImplementation(async function (id) { + return { userId: 1, id: 3, title: 'delectus aut autem', completed: false } + }) + + const res = await MakeRequest.fetchDataFromAPI(id) + assert.deepEqual(res.id, id) + }) + + it("should create a slug based on the title", async function (t) { + const slugSpy = mock.method(MakeRequest, "slugifyTitle") + mock + .method(MakeRequest, "fetchDataFromAPI") + .mock.mockImplementation(async function () { + return { userId: 1, id: 1, title: 'delectus aut autem', completed: false } + }) + + await MakeRequest.addToDB() + const call = MakeRequest.slugifyTitle.mock.calls[0] + assert.deepEqual(slugSpy.mock.calls.length, 2) + assert.deepEqual(MakeRequest.fetchDataFromAPI.mock.callCount(), 1) + assert.strictEqual(call.result.slug, `delectus-aut-autem1`) + }) +}) \ No newline at end of file diff --git a/src/tests/spy.test.js b/src/tests/spy.test.js new file mode 100644 index 0000000..ac043e6 --- /dev/null +++ b/src/tests/spy.test.js @@ -0,0 +1,27 @@ +import { test, describe, it, beforeEach, mock } from "node:test" +import assert from "node:assert" + +function sumArray(arr) { + return arr.reduce((a, b) => a + b, 0) +} + +describe("Spies test: it should call sumArray function with arguments", async function () { + it("some test", async function (t) { + const spy = mock.fn(sumArray) + assert.strictEqual(spy([1, 5, 3]), 9) + assert.strictEqual(spy([2, 7, 5]), 14) + assert.strictEqual(spy.mock.calls.length, 2) + + const call1 = spy.mock.calls[0] + assert.deepEqual(call1.arguments[0], [1, 5, 3]) + assert.strictEqual(call1.result, 9) + + const call2 = spy.mock.calls[1] + assert.deepEqual(call2.arguments[0], [2, 7, 5]) + assert.strictEqual(call2.result, 14) + }) +}) + +test.skip("Skipping tests", function () { + assert.notEqual(1, 2) +}) \ No newline at end of file diff --git a/src/tests/stub.test.js b/src/tests/stub.test.js new file mode 100644 index 0000000..56191e3 --- /dev/null +++ b/src/tests/stub.test.js @@ -0,0 +1,3 @@ +import { test, describe, it, mock } from "node:test" +import assert from "node:assert" + diff --git a/src/timeoutFetch.js b/src/timeoutFetch.js new file mode 100644 index 0000000..2b8b6e1 --- /dev/null +++ b/src/timeoutFetch.js @@ -0,0 +1,17 @@ +async function fetchWithTimeout() { + const response = await fetch("https://jsonplaceholder.typicode.com/todos/1", { + signal: AbortSignal.timeout(500) + }) + + if (!response.ok) { + const message = `An error has occured: ${response.statusText}` + throw new Error(message) + } + + const data = await response.json() + console.log(data) +} + +fetchWithTimeout().catch(function (error) { + console.log(error.message) +}) \ No newline at end of file