From de56035276ae0a4a5b21297cb701432a6c26a1b3 Mon Sep 17 00:00:00 2001 From: Piotr Lewandowski Date: Sun, 13 Jul 2025 16:42:39 +0200 Subject: [PATCH 1/3] chore(ci): add GitHub Actions workflow for testing and linting **Goal:** Establish automated CI for testing, linting, and building changes to ensure code quality and maintainability. **`.github/workflows/ci.yml`:** - Added a GitHub Actions workflow to trigger on `push` and `pull_request` events for `main` and `master` branches. - Configured matrix testing for Node.js versions 20.x and 22.x. - Defined steps to checkout code, set up Node.js with caching enabled, install dependencies, run lint checks, execute tests, and build the project. This workflow ensures consistent quality checks for all contributions and supports streamlined development. Related to `chore/github-actions-for-tests-lint`. --- .github/workflows/ci.yml | 37 +++++++++++++++++++++++++++++++++++++ tsconfig.json | 13 ++++++++++--- 2 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8e2347f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: CI + +on: + pull_request: + branches: [ main, master ] + push: + branches: [ main, master ] + +jobs: + test: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [22.x] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Run linter + run: npm run lint + + - name: Run tests + run: npm test + + - name: Run build + run: npm run build diff --git a/tsconfig.json b/tsconfig.json index f8b000d..b72571a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,11 +2,18 @@ "compilerOptions": { "outDir": "./dist/", "noImplicitAny": false, - "module": "es2015", + "module": "es2022", "target": "es2017", "sourceMap": true, "allowJs": true, "esModuleInterop": true, - "allowSyntheticDefaultImports": true - } + "allowSyntheticDefaultImports": true, + "moduleResolution": "nodenext", + "strict": false, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "types": ["jest", "node"] + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] } From a631f903cf05d228a2b0c89e25c03b05a032d136 Mon Sep 17 00:00:00 2001 From: Piotr Lewandowski Date: Sun, 13 Jul 2025 17:26:20 +0200 Subject: [PATCH 2/3] fix(tests): migrate to ESM imports for CI setup --- build.js | 12 ++++++------ src/gh-cache-storage.spec.ts | 1 + src/gh-data-loader.spec.ts | 20 ++++++++++++++------ src/gh-dom-operator.spec.ts | 1 + src/gh-dom.utils.spec.ts | 1 + src/gh-profile-card.spec.ts | 1 + src/gh-widget-init.spec.ts | 3 ++- src/testing/fetch-mock.ts | 14 ++++++++------ src/testing/test-setup.ts | 2 +- 9 files changed, 35 insertions(+), 20 deletions(-) diff --git a/build.js b/build.js index 03d0d8f..a9496c5 100644 --- a/build.js +++ b/build.js @@ -1,8 +1,8 @@ -const esbuild = require('esbuild'); -const { sassPlugin } = require('esbuild-sass-plugin'); -const fs = require('fs'); -const path = require('path'); -const PACKAGE = require('./package.json'); +import esbuild from 'esbuild'; +import { sassPlugin } from 'esbuild-sass-plugin'; +import fs from 'fs'; +import path from 'path'; +import PACKAGE from './package.json' with { type: 'json' }; const ENV = process.env.WEBPACK_ENV; const libraryName = 'gh-profile-card'; @@ -12,7 +12,7 @@ const banner = `/** */ `; -const outfilePath = path.resolve(__dirname, 'dist', `${libraryName}.min.js`); +const outfilePath = path.resolve('dist', `${libraryName}.min.js`); esbuild .build({ diff --git a/src/gh-cache-storage.spec.ts b/src/gh-cache-storage.spec.ts index 54112f1..0419218 100644 --- a/src/gh-cache-storage.spec.ts +++ b/src/gh-cache-storage.spec.ts @@ -1,3 +1,4 @@ +import { beforeEach, describe, expect, it, jest } from '@jest/globals'; import { CacheStorage, CacheEntry } from './gh-cache-storage'; import { InMemoryStorage } from './testing/in-memory-storage'; import { BrowserStorage } from './interface/storage'; diff --git a/src/gh-data-loader.spec.ts b/src/gh-data-loader.spec.ts index a75af6c..e868724 100644 --- a/src/gh-data-loader.spec.ts +++ b/src/gh-data-loader.spec.ts @@ -1,3 +1,11 @@ +import { + beforeEach, + describe, + expect, + it, + afterEach, + jest, +} from '@jest/globals'; import { GitHubApiLoader } from './gh-data-loader'; import { CacheStorage } from './gh-cache-storage'; @@ -168,15 +176,15 @@ describe('GitHubApiLoader', () => { headers: { get: jest.fn().mockReturnValue('Mon, 18 Mar 2019 20:40:35 GMT'), }, - json: jest.fn().mockResolvedValue(mockProfile), - }) + json: jest.fn(() => Promise.resolve(mockProfile)), + } as any) .mockResolvedValueOnce({ status: 200, headers: { get: jest.fn().mockReturnValue('Mon, 18 Mar 2019 20:40:35 GMT'), }, - json: jest.fn().mockResolvedValue(mockRepositories), - }); + json: jest.fn(() => Promise.resolve(mockRepositories)), + } as any); // When const result = await loader.loadUserData('testuser'); @@ -242,7 +250,7 @@ describe('GitHubApiLoader', () => { ); done(); } catch (error) { - done(error); + done(error as Error); } }, ); @@ -279,7 +287,7 @@ describe('GitHubApiLoader', () => { ); done(); } catch (error) { - done(error); + done(error as Error); } }, ); diff --git a/src/gh-dom-operator.spec.ts b/src/gh-dom-operator.spec.ts index 0307a67..8deee4b 100644 --- a/src/gh-dom-operator.spec.ts +++ b/src/gh-dom-operator.spec.ts @@ -1,3 +1,4 @@ +import { beforeEach, describe, expect, it } from '@jest/globals'; import { DOMOperator } from './gh-dom-operator'; import { ApiError, ApiProfile, ApiRepository } from './interface/IGitHubApi'; diff --git a/src/gh-dom.utils.spec.ts b/src/gh-dom.utils.spec.ts index 6a5561b..da93300 100644 --- a/src/gh-dom.utils.spec.ts +++ b/src/gh-dom.utils.spec.ts @@ -1,3 +1,4 @@ +import { beforeEach, describe, expect, it } from '@jest/globals'; import { createProfile, createName, diff --git a/src/gh-profile-card.spec.ts b/src/gh-profile-card.spec.ts index 7fecd8b..9415b52 100644 --- a/src/gh-profile-card.spec.ts +++ b/src/gh-profile-card.spec.ts @@ -1,3 +1,4 @@ +import { beforeEach, describe, expect, it, jest } from '@jest/globals'; import { GitHubCardWidget } from './gh-profile-card'; import { GitHubApiLoader } from './gh-data-loader'; import { DOMOperator } from './gh-dom-operator'; diff --git a/src/gh-widget-init.spec.ts b/src/gh-widget-init.spec.ts index c60d424..9bea632 100644 --- a/src/gh-widget-init.spec.ts +++ b/src/gh-widget-init.spec.ts @@ -1,4 +1,5 @@ -// Mock the GitHubCardWidget +import { beforeEach, describe, expect, it, jest } from '@jest/globals'; + jest.mock('./gh-profile-card'); import { GitHubCardWidget } from './gh-profile-card'; diff --git a/src/testing/fetch-mock.ts b/src/testing/fetch-mock.ts index 3450680..7e57cd1 100644 --- a/src/testing/fetch-mock.ts +++ b/src/testing/fetch-mock.ts @@ -1,6 +1,5 @@ -/** - * Fetch mock utilities for testing - */ +import { jest } from '@jest/globals'; +import { ApiProfile, ApiRepository } from '../interface/IGitHubApi'; export interface MockResponse { status: number; @@ -25,8 +24,8 @@ export function setupFetchMock(): void { /** * Creates a successful HTTP response mock */ -export function createSuccessResponse( - data: any, +export function createSuccessResponse( + data: T, headers: Record = {}, ): MockResponse { return { @@ -88,7 +87,10 @@ export function resetFetchMock(): void { /** * Sets up common fetch mock responses for user data loading */ -export function setupUserDataMocks(profile: any, repositories: any[]): void { +export function setupUserDataMocks( + profile: ApiProfile, + repositories: ApiRepository[], +): void { mockFetch .mockResolvedValueOnce( createSuccessResponse(profile, { diff --git a/src/testing/test-setup.ts b/src/testing/test-setup.ts index 5c11dd0..fe3c9c2 100644 --- a/src/testing/test-setup.ts +++ b/src/testing/test-setup.ts @@ -1,4 +1,4 @@ -// import { jest } from '@jest/globals'; +import { jest, beforeEach, expect, afterEach } from '@jest/globals'; // Mock console methods during tests to reduce noise const originalError = console.error; From f7239101067f797aec08976c7c7e130c0fa86a19 Mon Sep 17 00:00:00 2001 From: Piotr Lewandowski Date: Sun, 13 Jul 2025 17:28:18 +0200 Subject: [PATCH 3/3] fix(tests): add missing CSS mocking --- .gitignore | 1 - src/testing/style-mock.js | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 src/testing/style-mock.js diff --git a/.gitignore b/.gitignore index e72a01e..889b6d7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ tmp/ .idea/ *.iml node_modules/ -src/**/*.js # SASS .sass-cache diff --git a/src/testing/style-mock.js b/src/testing/style-mock.js new file mode 100644 index 0000000..f053ebf --- /dev/null +++ b/src/testing/style-mock.js @@ -0,0 +1 @@ +module.exports = {};