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/.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/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/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 = {}; 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; 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"] }