Skip to content

Conversation

@MarshallOfSound
Copy link
Member

At one point this module had really good test coverage, then we added a bunch of stuff to it 😆 These are mostly claude generated test cases but I've gone through them and they all seem like in/out samples

@MarshallOfSound MarshallOfSound requested a review from a team as a code owner November 15, 2025 07:46
@MarshallOfSound MarshallOfSound changed the title spec: add a bunch of tests test: add a bunch of tests Nov 15, 2025
@socket-security
Copy link

socket-security bot commented Nov 15, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​vitest/​coverage-v8@​3.0.5991007299100

View full report

Copy link
Member

@dsanders11 dsanders11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs some work before we should land it.

First and foremost it fails type checking, see #158 which enforces type checking going forward.

I've left a handful of inline comments, but overall I think these tests can be cleaned up a decent amount. Using assert from vitest would remove the need for a lot of the type assertions and null-coalescing operators (e.g. assert(result.innerTypes?.length === 1) instead of expect(result.innerTypes).toHaveLength(1)).

Some of these tests have expect calls inside conditional branches, which is a code smell. I'm guessing that was Claude trying to make the code pass type checking, but it can lead to those expect calls never running and the tests passing if something subtle changes. Those can be refactored using assert to both pass type checking and not be in a conditional branch that could get skipped.

claude and others added 5 commits November 23, 2025 12:35
This commit significantly expands test coverage for the docs-parser:

**New test files:**
- tests/DocsParser.spec.ts - Tests for main parser class including:
  * Module, class, and structure parsing
  * Element/tag documentation parsing
  * Constructor, methods, properties, and events extraction
  * Process tags and multi-package mode handling
  * URL generation and version tracking

- tests/index.spec.ts - Tests for public API including:
  * parseDocs function with various configurations
  * Single vs multi package modes
  * README parsing mode
  * Structure and API file handling
  * Version tracking

**Enhanced existing test files:**
- tests/block-parsers.spec.ts - Added extensive tests for:
  * parsePropertyBlocks (basic, optional, readonly, platform-specific)
  * parseEventBlocks (basic, with parameters, platform tags)
  * guessParametersFromSignature (single, multiple, optional, nested, spread)
  * Platform tags and deprecated tags using proper enum values
  * Return types and generics

- tests/markdown-helpers.spec.ts - Added tests for previously uncovered functions:
  * findContentAfterList
  * findContentAfterHeadingClose
  * headingsAndContent
  * findConstructorHeader
  * getContentBeforeConstructor
  * getContentBeforeFirstHeadingMatching
  * findContentInsideHeader
  * safelySeparateTypeStringOn
  * getTopLevelMultiTypes
  * getTopLevelOrderedTypes
  * convertListToTypedKeys

**Test statistics:**
- Previously: ~50 tests
- Now: 187 tests (178 passing)
- Significantly improved coverage of core parsing functionality

The tests cover key functionality including markdown parsing, type extraction,
documentation structure handling, and the main parser API. Some complex
integration tests may need adjustment but overall coverage is substantially
improved.
All 187 tests now pass (100% pass rate). Fixed tests by ensuring all
module documentation includes required elements:

**Root cause:** The parser requires modules to have:
1. Process tag (_Main process_, _Renderer process_, etc.)
2. At least one content section (Methods, Events, or Properties)

**Changes made:**
- Added process tags to all module test fixtures
- Added Methods sections with sample methods to ensure valid parsing
- Fixed DocsParser.spec.ts (3 tests fixed):
  * should handle module with exported class in multi-package mode
  * should handle process tags correctly
  * should generate correct website and repo URLs

- Fixed index.spec.ts (6 tests fixed):
  * should use multi package mode when specified
  * should parse both API files and structures
  * should include version in parsed documentation
  * should handle multiple API files
  * should find all markdown files in API directory
  * should not find non-markdown files

These were not bugs in the code - they were incomplete test fixtures
that didn't match the Electron documentation format requirements.

Test results: ✅ 187/187 passing (100%)
@MarshallOfSound MarshallOfSound force-pushed the claude/add-test-coverage-0189ruZ2dWxVS4KVRFozfwXb branch from a5c756d to a67e85c Compare November 23, 2025 20:45
@MarshallOfSound
Copy link
Member Author

Some of these tests have expect calls inside conditional branches, which is a code smell. I'm guessing that was Claude trying to make the code pass type checking, but it can lead to those expect calls never running and the tests passing if something subtle changes. Those can be refactored using assert to both pass type checking and not be in a conditional branch that could get skipped.

This is a good call out that I missed 🙇 I updated all these to use type assertions instead as these are frequently code patterns of "assert foo -> assert foo.bar" where typescript doesn't understand vitests "expect" syntax is actually a typecheck.

Things looking a bit better now and typecheck now passing

Copy link
Member

@dsanders11 dsanders11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking better, but see inline comments about replacing the type assertions with type inference via assert(...).

Comment on lines 71 to 87
const appModule = result.find((m) => m.name === 'app');
expect(appModule).toBeDefined();
expect(appModule?.type).toBe('Module');
// Just check that process information is present
expect((appModule as ModuleDocumentationContainer).process).toBeDefined();
expect((appModule as ModuleDocumentationContainer).process.main).toBe(true);
expect(appModule?.description).toContain('Control your application');

const module = appModule as ModuleDocumentationContainer;
expect(module.events).toHaveLength(1);
expect(module.events[0].name).toBe('ready');

expect(module.methods).toHaveLength(1);
expect(module.methods[0].name).toBe('quit');

expect(module.properties).toHaveLength(1);
expect(module.properties[0].name).toBe('name');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const appModule = result.find((m) => m.name === 'app');
expect(appModule).toBeDefined();
expect(appModule?.type).toBe('Module');
// Just check that process information is present
expect((appModule as ModuleDocumentationContainer).process).toBeDefined();
expect((appModule as ModuleDocumentationContainer).process.main).toBe(true);
expect(appModule?.description).toContain('Control your application');
const module = appModule as ModuleDocumentationContainer;
expect(module.events).toHaveLength(1);
expect(module.events[0].name).toBe('ready');
expect(module.methods).toHaveLength(1);
expect(module.methods[0].name).toBe('quit');
expect(module.properties).toHaveLength(1);
expect(module.properties[0].name).toBe('name');
const appModule = result.find((m) => m.name === 'app');
assert(appModule?.type === 'Module');
// Just check that process information is present
expect(appModule.process).toBeDefined();
expect(appModule.process.main).toBe(true);
expect(appModule.description).toContain('Control your application');
expect(appModule.events).toHaveLength(1);
expect(appModule.events[0].name).toBe('ready');
expect(appModule.methods).toHaveLength(1);
expect(appModule.methods[0].name).toBe('quit');
expect(appModule.properties).toHaveLength(1);
expect(appModule.properties[0].name).toBe('name');

The type assertions can be removed by using assert from vitest and letting tsc infer types. The line assert(appModule?.type === 'Module') will automatically infer ModuleDocumentationContainer for the following lines and we don't need to use type assertions.

Comment on lines 193 to 202
const menuClass = result.find((c) => c.name === 'Menu');
expect(menuClass).toBeDefined();

const cls = menuClass as ClassDocumentationContainer;
expect(cls.staticMethods).toHaveLength(1);
expect(cls.staticMethods[0].name).toBe('buildFromTemplate');
expect(cls.staticMethods[0].returns).toBeDefined();

expect(cls.staticProperties).toHaveLength(1);
expect(cls.staticProperties[0].name).toBe('applicationMenu');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const menuClass = result.find((c) => c.name === 'Menu');
expect(menuClass).toBeDefined();
const cls = menuClass as ClassDocumentationContainer;
expect(cls.staticMethods).toHaveLength(1);
expect(cls.staticMethods[0].name).toBe('buildFromTemplate');
expect(cls.staticMethods[0].returns).toBeDefined();
expect(cls.staticProperties).toHaveLength(1);
expect(cls.staticProperties[0].name).toBe('applicationMenu');
const menuClass = result.find((c) => c.name === 'Menu');
assert(menuClass?.type === 'Class');
expect(menuClass.staticMethods).toHaveLength(1);
expect(menuClass.staticMethods[0].name).toBe('buildFromTemplate');
expect(menuClass.staticMethods[0].returns).toBeDefined();
expect(menuClass.staticProperties).toHaveLength(1);
expect(menuClass.staticProperties[0].name).toBe('applicationMenu');

Same as above, just another example of the assert removing the need for a type assertion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does assert have a useful error message? Sorry the reason I've not used assert in the past is because the error is normally. "Expected true to be false" which isn't helpful

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert takes a second optional argument for message, so you can easily set a more useful error message. Just tested, without one set, if the assert fails you get a somewhat ugly object dump, but in both cases, Vitest shows you the exact line which failed, so you can see the condition easily. Passing a message does make for a nicer experience, so let's do that. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants