Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2493a22
first pass
kanadgupta Nov 12, 2025
a599961
chore: see if this import alias will get tests passing
kanadgupta Nov 12, 2025
614dcf0
refactor: slightly cleaner test cleanup
kanadgupta Nov 12, 2025
5244ba3
chore: fix up export path
kanadgupta Nov 12, 2025
1acc8e5
chore: tsconfig tweak
kanadgupta Nov 12, 2025
6d30b08
chore: convert yet another file to TS
kanadgupta Nov 12, 2025
a27c9f9
chore: test script tweak
kanadgupta Nov 12, 2025
609e0d7
Update vitest.setup.ts
kanadgupta Nov 12, 2025
347993c
ci: rework build process a bit
kanadgupta Nov 12, 2025
bc8b134
chore: try tweaking exports object
kanadgupta Nov 12, 2025
4628ebf
Update .eslintignore
kanadgupta Nov 12, 2025
6671600
chore: remove redundant rimraf
kanadgupta Nov 12, 2025
d5e7821
chore: attempt to revert some TS conversions to see if that fixes things
kanadgupta Nov 12, 2025
8242e38
fix: don't optimize deps, transpile only
kanadgupta Nov 12, 2025
5063845
fix: don't `--write` during test step
kanadgupta Nov 12, 2025
5b5c035
chore: reconvert TS since that wasn't actually the problem
kanadgupta Nov 12, 2025
b02d0bc
chore: shift around for better diff
kanadgupta Nov 12, 2025
3226d1a
chore: run it back
kanadgupta Nov 12, 2025
8976403
Revert "chore: run it back"
kanadgupta Nov 12, 2025
e2f7789
revert: actually we don't need that top-level describe
kanadgupta Nov 12, 2025
6c9c737
chore: deps cleanup
kanadgupta Nov 12, 2025
4dfcd0f
chore!: bump min node version to 22
kanadgupta Nov 12, 2025
69a9d3c
chore: remove identity-obj-proxy
kanadgupta Nov 12, 2025
465341a
chore: remove `defaultProps` to address warning
kanadgupta Nov 12, 2025
48be9e4
chore: install knip, rip out a few things
kanadgupta Nov 12, 2025
83593b2
chore: format command
kanadgupta Nov 12, 2025
705b5db
chore: suppress vitest lint warnings
kanadgupta Nov 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
node_modules/
coverage/
dist/
dist-utils/
public/index*
__tests__/__fixtures__/**/sample.*
8 changes: 7 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
{
"extends": ["@readme/eslint-config", "@readme/eslint-config/react"],
"root": true
"overrides": [
{
"files": ["**/*.ts", "**/*.tsx"],
"extends": ["@readme/eslint-config/typescript"],
},
],
"root": true,
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
dist/
dist-utils/
node_modules/
coverage/
2 changes: 1 addition & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ __tests__/
coverage/
.eslint*
.prettier*
jest.config.js
vitest*
7 changes: 4 additions & 3 deletions __tests__/.eslintrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"extends": [
"@readme/eslint-config/testing/jest",
"@readme/eslint-config/testing/vitest",
"@readme/eslint-config/testing/jest-dom",
"@readme/eslint-config/testing/react"
]
"@readme/eslint-config/testing/react",
"@readme/eslint-config/typescript",
],
}

Large diffs are not rendered by default.

24 changes: 21 additions & 3 deletions __tests__/codeEditor.test.js → __tests__/codeEditor.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
import { render, screen, waitFor } from '@testing-library/react';
import React from 'react';
import { afterEach, beforeEach, describe, expect, vi, it } from 'vitest';

import CodeEditor from '../src/codeEditor';

describe('<CodeEditor/>', () => {
const getClientRectSpy = jest.fn(() => ({ width: 100 }));
Range.prototype.getBoundingClientRect = getClientRectSpy;
Range.prototype.getClientRects = getClientRectSpy;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let originalGetBoundingClientRect: any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let originalGetClientRects: any;
const getClientRectSpy = vi.fn(() => ({ width: 100 }));

Check warning on line 12 in __tests__/codeEditor.test.tsx

View workflow job for this annotation

GitHub Actions / build (lts/* w/ React 18

Missing type parameters

Check warning on line 12 in __tests__/codeEditor.test.tsx

View workflow job for this annotation

GitHub Actions / build (lts/-1 w/ React 18

Missing type parameters

Check warning on line 12 in __tests__/codeEditor.test.tsx

View workflow job for this annotation

GitHub Actions / build (latest w/ React 18

Missing type parameters

beforeEach(() => {
originalGetBoundingClientRect = Range.prototype.getBoundingClientRect;
originalGetClientRects = Range.prototype.getClientRects;
// @ts-expect-error mock types
Range.prototype.getBoundingClientRect = getClientRectSpy;
// @ts-expect-error mock types
Range.prototype.getClientRects = getClientRectSpy;
});

afterEach(() => {
Range.prototype.getBoundingClientRect = originalGetBoundingClientRect;
Range.prototype.getClientRects = originalGetClientRects;
getClientRectSpy.mockRestore();
});

it('should display a <CodeEditor> element', () => {
render(<CodeEditor code="console.log('Hello, world.');" lang="javascript" />);
Expand Down Expand Up @@ -35,7 +53,7 @@
expect(screen.getByText('console')).toHaveClass('cm-variable');
});

it.skip('should set new language via props', () => {

Check warning on line 56 in __tests__/codeEditor.test.tsx

View workflow job for this annotation

GitHub Actions / build (lts/* w/ React 18

Disabled test - if you want to skip a test temporarily, use .todo() instead

Check warning on line 56 in __tests__/codeEditor.test.tsx

View workflow job for this annotation

GitHub Actions / build (lts/-1 w/ React 18

Disabled test - if you want to skip a test temporarily, use .todo() instead

Check warning on line 56 in __tests__/codeEditor.test.tsx

View workflow job for this annotation

GitHub Actions / build (latest w/ React 18

Disabled test - if you want to skip a test temporarily, use .todo() instead
const { rerender } = render(<CodeEditor code="console.log('Hello, world.');" />);
expect(screen.getByText("console.log('Hello, world.');")).toBeVisible();

Expand Down
35 changes: 28 additions & 7 deletions __tests__/codeMirror.test.js → __tests__/codeMirror.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/* eslint-disable testing-library/no-node-access */
/* eslint-disable testing-library/no-container */
import { promises as fs } from 'fs';
import { promises as fs, globSync } from 'fs';
import path from 'path';

// eslint-disable-next-line testing-library/no-manual-cleanup
import { render, screen, cleanup } from '@testing-library/react';
import { globSync } from 'glob';
import { cleanup, render, screen } from '@testing-library/react';
import { beforeAll, beforeEach, describe, expect, it, vi, test } from 'vitest';

import syntaxHighlighter, { uppercase, canonical } from '../src';

Expand Down Expand Up @@ -51,6 +51,7 @@
});

test('should keep trailing json bracket if highlightMode is enabled', () => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter('{ "a": 1 }', 'json', { highlightMode: true }));

expect(screen.getByTestId('CodeMirror').outerHTML).toBe(
Expand All @@ -59,27 +60,32 @@
});

test('should have a dark theme', () => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter('{ "a": 1 }', 'json', { dark: true }));
expect(screen.getByTestId('SyntaxHighlighter')).toHaveClass('cm-s-material-palenight');
});

describe('variable substitution', () => {
it('should tokenize variables (double quotes)', () => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter('"<<apiKey>>"', 'json', { tokenizeVariables: true }));
expect(screen.getByText('APIKEY')).toBeVisible();
});

it('should tokenize variables (single quotes)', () => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter("'<<apiKey>>'", 'json', { tokenizeVariables: true }));
expect(screen.getByText('APIKEY')).toBeVisible();
});

it('should keep enclosing characters around the variable', () => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter("'<<apiKey>>'", 'json', { tokenizeVariables: true }));
expect(screen.getByTestId('SyntaxHighlighter')).toHaveTextContent("'APIKEY'");
});

it('should tokenize variables outside of quotes', () => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter('<<apiKey>>', 'json', { tokenizeVariables: true }));
expect(screen.getByText('APIKEY')).toBeVisible();
});
Expand All @@ -92,38 +98,45 @@
fetch({ foo, bar, baz: <<token>> });
`;

// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter(codeBlock, 'json', { tokenizeVariables: true }));
expect(screen.getByTestId('SyntaxHighlighter').textContent).toMatchSnapshot();
});

it('should tokenize multiple variables per line', () => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter('<<apiKey>> <<name>>', 'json', { tokenizeVariables: true }));
expect(screen.getByTestId('SyntaxHighlighter')).toHaveTextContent('APIKEY NAME');
});

it.each(['\\<<wat>>', '<<wat\\>>', '\\<<wat\\>>'])('should NOT tokenize escaped variables %s', code => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter(code, 'json', { tokenizeVariables: true }));
expect(screen.getByTestId('SyntaxHighlighter')).toHaveTextContent('<<wat>>');
});
});

describe('variable substitution { mdx: true }', () => {
it('should tokenize variables (double quotes)', () => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter('"{user.apiKey}"', 'json', { tokenizeVariables: true }, { mdx: true }));
expect(screen.getByText('APIKEY')).toBeVisible();
});

it('should tokenize variables (single quotes)', () => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter("'{user.apiKey}'", 'json', { tokenizeVariables: true }, { mdx: true }));
expect(screen.getByText('APIKEY')).toBeVisible();
});

it('should keep enclosing characters around the variable', () => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter("'{user.apiKey}'", 'json', { tokenizeVariables: true }, { mdx: true }));
expect(screen.getByTestId('SyntaxHighlighter')).toHaveTextContent("'APIKEY'");
});

it('should tokenize variables outside of quotes', () => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter('{user.apiKey}', 'json', { tokenizeVariables: true }, { mdx: true }));
expect(screen.getByText('APIKEY')).toBeVisible();
});
Expand All @@ -136,6 +149,7 @@
fetch({ foo, bar, baz: {user.token} });
`;

// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter(codeBlock, 'json', { tokenizeVariables: true }, { mdx: true }));
expect(screen.getByTestId('SyntaxHighlighter').textContent).toMatchInlineSnapshot(`
"
Expand All @@ -148,16 +162,19 @@
});

it('should tokenize multiple variables per line', () => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter('{user.apiKey} {user.name}', 'json', { tokenizeVariables: true }, { mdx: true }));
expect(screen.getByTestId('SyntaxHighlighter')).toHaveTextContent('APIKEY NAME');
});

it('should not tokenize bracket style', () => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter('<<wat>>', 'json', { tokenizeVariables: true }, { mdx: true }));
expect(screen.getByTestId('SyntaxHighlighter')).toHaveTextContent('<<wat>>');
});

it.each(['\\{user.wat}', '{user.wat\\}', '\\{user.wat\\}'])('should NOT tokenize escaped variables %s', code => {
// @ts-expect-error this component's types are currently ill-defined
render(syntaxHighlighter(code, 'json', { tokenizeVariables: true }, { mdx: true }));
expect(screen.getByTestId('SyntaxHighlighter')).toHaveTextContent('{user.wat}');
});
Expand All @@ -169,9 +186,9 @@
});

describe.each(languages)('%s', (language, fixtureDir) => {
let testCase;
let testCase: string;

// eslint-disable-next-line global-require, import/no-dynamic-require
// eslint-disable-next-line global-require, import/no-dynamic-require, @typescript-eslint/no-require-imports
const instructions = require(path.join(fixtureDir, 'index.js'));

beforeEach(async () => {
Expand Down Expand Up @@ -253,6 +270,7 @@
render(
syntaxHighlighter(code, 'curl', {
dark: true,
// @ts-expect-error this component's types are currently ill-defined
highlightMode: true,
tokenizeVariables: true,
ranges: [
Expand Down Expand Up @@ -293,6 +311,7 @@
render(
syntaxHighlighter(code, 'c', {
dark: true,
// @ts-expect-error this component's types are currently ill-defined
highlightMode: true,
tokenizeVariables: true,
ranges: [
Expand All @@ -315,9 +334,10 @@
document.createRange = () => {
const range = new Range();

range.getBoundingClientRect = jest.fn();
range.getBoundingClientRect = vi.fn();

Check warning on line 337 in __tests__/codeMirror.test.ts

View workflow job for this annotation

GitHub Actions / build (lts/* w/ React 18

Missing type parameters

Check warning on line 337 in __tests__/codeMirror.test.ts

View workflow job for this annotation

GitHub Actions / build (lts/-1 w/ React 18

Missing type parameters

Check warning on line 337 in __tests__/codeMirror.test.ts

View workflow job for this annotation

GitHub Actions / build (latest w/ React 18

Missing type parameters

range.getClientRects = jest.fn(() => ({
// @ts-expect-error this component's types are currently ill-defined
range.getClientRects = vi.fn(() => ({

Check warning on line 340 in __tests__/codeMirror.test.ts

View workflow job for this annotation

GitHub Actions / build (lts/* w/ React 18

Missing type parameters

Check warning on line 340 in __tests__/codeMirror.test.ts

View workflow job for this annotation

GitHub Actions / build (lts/-1 w/ React 18

Missing type parameters

Check warning on line 340 in __tests__/codeMirror.test.ts

View workflow job for this annotation

GitHub Actions / build (latest w/ React 18

Missing type parameters
item: () => null,
length: 0,
}));
Expand All @@ -328,6 +348,7 @@

it('renders folders in the gutter', () => {
const { container } = render(
// @ts-expect-error this component's types are currently ill-defined
syntaxHighlighter('{ "a": { "b": { "c": 1 } }', 'json', { foldGutter: true, readOnly: true }),
);

Expand Down
1 change: 0 additions & 1 deletion __tests__/jest.setup.js

This file was deleted.

2 changes: 2 additions & 0 deletions __tests__/uppercase.test.js → __tests__/uppercase.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { expect, test } from 'vitest';

import { uppercase } from '../src';

test('should uppercase known languages', () => {
Expand Down
21 changes: 0 additions & 21 deletions jest.config.js

This file was deleted.

Loading