From 13efffbbffc36ae47848b41d8ece4fdb136aa7ed Mon Sep 17 00:00:00 2001 From: Jens <69081683+jenslys@users.noreply.github.com> Date: Sun, 24 Nov 2024 14:27:37 +0100 Subject: [PATCH] feat: jest tests + release script --- .github/workflows/publish.yml | 45 ++++++++++++++++++++++++++++++ jest.config.js | 11 ++++++++ package.json | 3 +- src/__tests__/index.test.ts | 28 +++++++++++++++++++ src/dev.ts | 51 ++++++++++++++++++++++++++++++++++ src/test.ts | 52 ----------------------------------- 6 files changed, 137 insertions(+), 53 deletions(-) create mode 100644 .github/workflows/publish.yml create mode 100644 jest.config.js create mode 100644 src/__tests__/index.test.ts create mode 100644 src/dev.ts delete mode 100644 src/test.ts diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..36c6bcf --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,45 @@ +name: Build, Test and Publish + +on: + push: + branches: + - main + +jobs: + build-and-publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20.x" + registry-url: "https://registry.npmjs.org" + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + + - name: Run tests + run: npm test + + - name: Check version change + id: check + run: | + git diff HEAD^ HEAD -G"\"version\": \"[^\"]*\"" package.json | grep "\"version\":" || echo "No version change" + if git diff HEAD^ HEAD -G"\"version\": \"[^\"]*\"" package.json | grep -q "\"version\":"; then + echo "version_changed=true" >> $GITHUB_OUTPUT + else + echo "version_changed=false" >> $GITHUB_OUTPUT + fi + + - name: Publish to npm + if: steps.check.outputs.version_changed == 'true' + run: npm publish --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..6727c66 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,11 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + transform: { + '^.+\\.tsx?$': 'ts-jest', + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], + testMatch: ['**/__tests__/**/*.ts?(x)', '**/?(*.)+(spec|test).ts?(x)'], + testPathIgnorePatterns: ['/node_modules/', '/dist/'], +}; diff --git a/package.json b/package.json index 64f8ccf..55a0b1c 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "build": "tsc", "test": "jest", "prepare": "npm run build", - "dev:test": "ts-node -r dotenv/config src/test.ts" + "dev:test": "ts-node -r dotenv/config src/test.ts", + "dev": "ts-node -r dotenv/config src/dev.ts" }, "author": "", "license": "MIT", diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts new file mode 100644 index 0000000..018a739 --- /dev/null +++ b/src/__tests__/index.test.ts @@ -0,0 +1,28 @@ +import { Skrape, SkrapeError } from '../index'; +import { z } from 'zod'; + +describe('Skrape', () => { + let skrape: Skrape; + + beforeEach(() => { + skrape = new Skrape({ + apiKey: 'test-key', + }); + }); + + it('should create a Skrape instance', () => { + expect(skrape).toBeInstanceOf(Skrape); + }); + + it('should throw error if apiKey is missing', () => { + expect(() => new Skrape({} as any)).toThrow(); + }); + + it('should have correct default baseUrl', () => { + expect((skrape as any).baseUrl).toBe('https://skrape.ai/api'); + }); + + it('should store API key', () => { + expect((skrape as any).apiKey).toBe('test-key'); + }); +}); diff --git a/src/dev.ts b/src/dev.ts new file mode 100644 index 0000000..719d85f --- /dev/null +++ b/src/dev.ts @@ -0,0 +1,51 @@ +import { Skrape, SkrapeError } from "./index"; +import { z } from "zod"; +import dotenv from "dotenv"; + +dotenv.config(); + +const apiKey = process.env.SKRAPE_API_KEY; +if (!apiKey) { + throw new Error("SKRAPE_API_KEY is required"); +} + +const skrape = new Skrape({ + apiKey, + baseUrl: "http://localhost:3000/api", +}); + +const newsSchema = z.object({ + topStories: z + .array( + z.object({ + title: z.string(), + url: z.string(), + score: z.number(), + author: z.string(), + commentCount: z.number(), + }) + ) + .max(3), +}); + +async function test() { + try { + const result = await skrape.extract( + "https://news.ycombinator.com", + newsSchema + ); + console.log(JSON.stringify(result, null, 2)); + } catch (error) { + if (error instanceof SkrapeError) { + console.error("SkrapeError:", error.message); + console.error("Status:", error.status); + if (error.retryAfter) { + console.error("Retry after:", error.retryAfter, "seconds"); + } + } else { + console.error("Error:", error); + } + } +} + +test(); diff --git a/src/test.ts b/src/test.ts deleted file mode 100644 index a635db7..0000000 --- a/src/test.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Skrape, SkrapeError } from "./index"; -import { z } from "zod"; - -const newsSchema = z.object({ - topStories: z - .array( - z.object({ - title: z.string(), - url: z.string(), - score: z.number(), - author: z.string(), - commentCount: z.number(), - }) - ) - .max(3), -}); - -async function test() { - if (!process.env.SKRAPE_API_KEY) { - console.error("Error: SKRAPE_API_KEY environment variable is not set"); - process.exit(1); - } - - const skrape = new Skrape({ - apiKey: process.env.SKRAPE_API_KEY, - baseUrl: "http://localhost:3000/api", - }); - - try { - const result = await skrape.extract( - "https://news.ycombinator.com/", - newsSchema, - { render_js: false } - ); - - console.log("Extracted data:", JSON.stringify(result, null, 2)); - } catch (error) { - if (error instanceof SkrapeError) { - console.error(`Error ${error.status}: ${error.message}`); - if (error.retryAfter) { - console.error(`Rate limited. Retry after ${error.retryAfter} seconds`); - } - } else { - console.error("Unexpected error:", error); - } - process.exit(1); - } -} - -if (require.main === module) { - test(); -}