mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-16 20:53:57 +08:00
85aad42f6f
Strategy 3's scoring already skipped a test double (`Mock…`, `Fake…`, `Stub…`, `Dummy…`, `Spy…`) the receiver and the calling file never name (#2175), but the unique-method shortcut before it did not: django-allauth's `resp.json()` on a Django test-client response went to `MockedResponse.json` 193 times, as the project's one `json`. The shortcut now applies the same rule. django-allauth -193, pytest -15 (`MockTiming`), mealie -8 (`FakeSession`, `_FakePostClient`); netbox, healthchecks, typeorm, eShop, BookStack unchanged. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
64 lines
1.9 KiB
TypeScript
64 lines
1.9 KiB
TypeScript
/**
|
|
* A receiver's method guessed from its name alone is never a test double's
|
|
* the calling file never names: django-allauth's `resp.json()` on a Django
|
|
* test-client response went to its `MockedResponse.json` 193 times, as the
|
|
* one `json` method in the project. A test that names the double keeps it.
|
|
*/
|
|
import { describe, it, expect, afterAll, beforeAll } from 'vitest';
|
|
import * as fs from 'fs';
|
|
import * as os from 'os';
|
|
import * as path from 'path';
|
|
import { CodeGraph } from '../src';
|
|
|
|
let root = '';
|
|
let cg: CodeGraph;
|
|
|
|
beforeAll(async () => {
|
|
root = fs.mkdtempSync(path.join(os.tmpdir(), 'cg-test-double-'));
|
|
const files: Record<string, string> = {
|
|
'tests/mocking.py': `class MockedResponse:
|
|
def __init__(self, data):
|
|
self.data = data
|
|
|
|
def json(self):
|
|
return self.data
|
|
`,
|
|
'tests/test_api.py': `def test_profile(client):
|
|
resp = client.get("/profile")
|
|
assert resp.json()["ok"]
|
|
`,
|
|
'tests/test_mocking.py': `from tests.mocking import MockedResponse
|
|
|
|
|
|
def test_mocked():
|
|
resp = MockedResponse({"ok": True})
|
|
assert resp.json()["ok"]
|
|
`,
|
|
};
|
|
for (const [rel, content] of Object.entries(files)) {
|
|
fs.mkdirSync(path.dirname(path.join(root, rel)), { recursive: true });
|
|
fs.writeFileSync(path.join(root, rel), content);
|
|
}
|
|
cg = await CodeGraph.init(root, { index: true });
|
|
});
|
|
|
|
afterAll(() => {
|
|
cg?.close();
|
|
if (root) fs.rmSync(root, { recursive: true, force: true });
|
|
});
|
|
|
|
const callsTo = (file: string, name: string) => {
|
|
const ids = cg.getNodesInFile(file).map((n) => n.id);
|
|
return cg.getOutgoingEdgesFrom(ids).filter((e) => e.kind === 'calls' && cg.getNode(e.target)!.name === name).length;
|
|
};
|
|
|
|
describe('test doubles as guessed receivers', () => {
|
|
it('are not what an unrelated `resp.json()` calls', () => {
|
|
expect(callsTo('tests/test_api.py', 'json')).toBe(0);
|
|
});
|
|
|
|
it('are what a test that names them calls', () => {
|
|
expect(callsTo('tests/test_mocking.py', 'json')).toBe(1);
|
|
});
|
|
});
|