ai-output-assert 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=edge-cases.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-cases.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/edge-cases.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const structural_1 = require("../matchers/structural");
5
+ const tone_1 = require("../matchers/tone");
6
+ const content_1 = require("../matchers/content");
7
+ const safety_1 = require("../matchers/safety");
8
+ const quality_1 = require("../matchers/quality");
9
+ (0, vitest_1.describe)('edge cases — empty and whitespace input', () => {
10
+ (0, vitest_1.it)('toBeValidJSON fails for empty string', () => {
11
+ (0, vitest_1.expect)((0, structural_1.toBeValidJSON)('').pass).toBe(false);
12
+ });
13
+ (0, vitest_1.it)('toBeValidJSON fails for whitespace only', () => {
14
+ (0, vitest_1.expect)((0, structural_1.toBeValidJSON)(' \n\t ').pass).toBe(false);
15
+ });
16
+ (0, vitest_1.it)('toBeValidMarkdown passes for empty string', () => {
17
+ // Empty string has no markdown issues
18
+ (0, vitest_1.expect)((0, structural_1.toBeValidMarkdown)('').pass).toBe(true);
19
+ });
20
+ (0, vitest_1.it)('toBeConcise passes for empty string', () => {
21
+ (0, vitest_1.expect)((0, tone_1.toBeConcise)('', 100).pass).toBe(true);
22
+ });
23
+ (0, vitest_1.it)('toNotContain passes for empty string', () => {
24
+ (0, vitest_1.expect)((0, content_1.toNotContain)('', 'forbidden').pass).toBe(true);
25
+ });
26
+ });
27
+ (0, vitest_1.describe)('edge cases — Unicode and special characters', () => {
28
+ (0, vitest_1.it)('toContainAllOf works with Unicode text', () => {
29
+ (0, vitest_1.expect)((0, content_1.toContainAllOf)('日本語のテスト', ['日本']).pass).toBe(true);
30
+ });
31
+ (0, vitest_1.it)('toHaveSentiment handles emoji-heavy text', () => {
32
+ const r = (0, tone_1.toHaveSentiment)('🎉🎊🥳 Celebration time! 🎉', 'neutral');
33
+ // Should not crash; result is either pass or fail
34
+ (0, vitest_1.expect)(typeof r.pass).toBe('boolean');
35
+ });
36
+ (0, vitest_1.it)('toBeValidJSON handles unicode content', () => {
37
+ (0, vitest_1.expect)((0, structural_1.toBeValidJSON)('{"emoji":"🎉","japanese":"日本語"}').pass).toBe(true);
38
+ });
39
+ });
40
+ (0, vitest_1.describe)('edge cases — large input', () => {
41
+ (0, vitest_1.it)('toNotRepeat handles large input without error', () => {
42
+ const large = 'This is sentence number one. '.repeat(1000);
43
+ const r = (0, quality_1.toNotRepeat)(large);
44
+ (0, vitest_1.expect)(typeof r.pass).toBe('boolean');
45
+ });
46
+ (0, vitest_1.it)('toNotContainPII handles large input', () => {
47
+ const large = 'Normal text without any personal info. '.repeat(500);
48
+ const r = (0, safety_1.toNotContainPII)(large);
49
+ (0, vitest_1.expect)(r.pass).toBe(true);
50
+ });
51
+ });
52
+ (0, vitest_1.describe)('edge cases — special content', () => {
53
+ (0, vitest_1.it)('toNotContainToxicContent passes for clean text', () => {
54
+ (0, vitest_1.expect)((0, safety_1.toNotContainToxicContent)('The weather is nice today.').pass).toBe(true);
55
+ });
56
+ (0, vitest_1.it)('toNotBeTruncated passes for complete sentence', () => {
57
+ (0, vitest_1.expect)((0, quality_1.toNotBeTruncated)('This is a complete sentence.').pass).toBe(true);
58
+ });
59
+ (0, vitest_1.it)('toNotBeTruncated detects truncation', () => {
60
+ (0, vitest_1.expect)((0, quality_1.toNotBeTruncated)('This sentence is clearly cut off mid').pass).toBe(false);
61
+ });
62
+ (0, vitest_1.it)('toContainCodeBlock handles inline backticks (not code blocks)', () => {
63
+ (0, vitest_1.expect)((0, structural_1.toContainCodeBlock)('Use `console.log` for debugging.').pass).toBe(false);
64
+ });
65
+ });
66
+ //# sourceMappingURL=edge-cases.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-cases.test.js","sourceRoot":"","sources":["../../src/__tests__/edge-cases.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=structural.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structural.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/matchers/structural.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const structural_1 = require("../../matchers/structural");
5
+ (0, vitest_1.describe)('toBeValidJSON', () => {
6
+ (0, vitest_1.it)('passes for valid JSON object', () => {
7
+ (0, vitest_1.expect)((0, structural_1.toBeValidJSON)('{"name":"John","age":30}').pass).toBe(true);
8
+ });
9
+ (0, vitest_1.it)('passes for valid JSON array', () => {
10
+ (0, vitest_1.expect)((0, structural_1.toBeValidJSON)('[1, 2, 3]').pass).toBe(true);
11
+ });
12
+ (0, vitest_1.it)('fails for invalid JSON', () => {
13
+ const r = (0, structural_1.toBeValidJSON)('not json');
14
+ (0, vitest_1.expect)(r.pass).toBe(false);
15
+ (0, vitest_1.expect)(r.message()).toContain('valid JSON');
16
+ });
17
+ (0, vitest_1.it)('passes for JSON in code fence', () => {
18
+ (0, vitest_1.expect)((0, structural_1.toBeValidJSON)('```json\n{"a":1}\n```').pass).toBe(true);
19
+ });
20
+ (0, vitest_1.it)('fails for empty string', () => {
21
+ (0, vitest_1.expect)((0, structural_1.toBeValidJSON)('').pass).toBe(false);
22
+ });
23
+ (0, vitest_1.it)('passes for string "null"', () => {
24
+ (0, vitest_1.expect)((0, structural_1.toBeValidJSON)('null').pass).toBe(true);
25
+ });
26
+ });
27
+ (0, vitest_1.describe)('toMatchSchema', () => {
28
+ const schema = {
29
+ type: 'object',
30
+ properties: {
31
+ name: { type: 'string' },
32
+ age: { type: 'number' },
33
+ },
34
+ required: ['name', 'age'],
35
+ };
36
+ (0, vitest_1.it)('passes for valid data matching schema', () => {
37
+ (0, vitest_1.expect)((0, structural_1.toMatchSchema)('{"name":"John","age":30}', schema).pass).toBe(true);
38
+ });
39
+ (0, vitest_1.it)('fails when required field is missing', () => {
40
+ const r = (0, structural_1.toMatchSchema)('{"name":"John"}', schema);
41
+ (0, vitest_1.expect)(r.pass).toBe(false);
42
+ (0, vitest_1.expect)(r.message()).toContain('schema');
43
+ });
44
+ (0, vitest_1.it)('fails when field type is wrong', () => {
45
+ const r = (0, structural_1.toMatchSchema)('{"name":"John","age":"thirty"}', schema);
46
+ (0, vitest_1.expect)(r.pass).toBe(false);
47
+ });
48
+ (0, vitest_1.it)('fails for non-JSON input', () => {
49
+ const r = (0, structural_1.toMatchSchema)('not json', schema);
50
+ (0, vitest_1.expect)(r.pass).toBe(false);
51
+ (0, vitest_1.expect)(r.message()).toContain('not valid JSON');
52
+ });
53
+ });
54
+ (0, vitest_1.describe)('toHaveJSONFields', () => {
55
+ (0, vitest_1.it)('passes when all fields are present', () => {
56
+ (0, vitest_1.expect)((0, structural_1.toHaveJSONFields)('{"a":1,"b":2,"c":3}', ['a', 'b']).pass).toBe(true);
57
+ });
58
+ (0, vitest_1.it)('fails when a field is missing', () => {
59
+ const r = (0, structural_1.toHaveJSONFields)('{"a":1}', ['a', 'b']);
60
+ (0, vitest_1.expect)(r.pass).toBe(false);
61
+ (0, vitest_1.expect)(r.message()).toContain('missing');
62
+ (0, vitest_1.expect)(r.message()).toContain('b');
63
+ });
64
+ (0, vitest_1.it)('supports nested field paths', () => {
65
+ (0, vitest_1.expect)((0, structural_1.toHaveJSONFields)('{"user":{"name":"John","age":30}}', ['user.name', 'user.age']).pass).toBe(true);
66
+ });
67
+ (0, vitest_1.it)('fails for non-JSON input', () => {
68
+ (0, vitest_1.expect)((0, structural_1.toHaveJSONFields)('not json', ['field']).pass).toBe(false);
69
+ });
70
+ });
71
+ (0, vitest_1.describe)('toBeValidMarkdown', () => {
72
+ (0, vitest_1.it)('passes for valid markdown', () => {
73
+ const md = '# Title\n\nSome text.\n\n## Subtitle\n\nMore text.';
74
+ (0, vitest_1.expect)((0, structural_1.toBeValidMarkdown)(md).pass).toBe(true);
75
+ });
76
+ (0, vitest_1.it)('fails for unclosed code fence', () => {
77
+ const r = (0, structural_1.toBeValidMarkdown)('```python\nprint("hi")\n');
78
+ (0, vitest_1.expect)(r.pass).toBe(false);
79
+ (0, vitest_1.expect)(r.message()).toContain('code fence');
80
+ });
81
+ (0, vitest_1.it)('fails for heading hierarchy skip', () => {
82
+ const r = (0, structural_1.toBeValidMarkdown)('# H1\n\n### H3\n');
83
+ (0, vitest_1.expect)(r.pass).toBe(false);
84
+ (0, vitest_1.expect)(r.message()).toContain('Heading hierarchy');
85
+ });
86
+ (0, vitest_1.it)('passes for plain text (no markdown features)', () => {
87
+ (0, vitest_1.expect)((0, structural_1.toBeValidMarkdown)('Just plain text.').pass).toBe(true);
88
+ });
89
+ (0, vitest_1.it)('fails for unbalanced brackets', () => {
90
+ const r = (0, structural_1.toBeValidMarkdown)('A [link without closing bracket');
91
+ (0, vitest_1.expect)(r.pass).toBe(false);
92
+ (0, vitest_1.expect)(r.message()).toContain('bracket');
93
+ });
94
+ });
95
+ (0, vitest_1.describe)('toContainCodeBlock', () => {
96
+ (0, vitest_1.it)('passes when code block is present', () => {
97
+ (0, vitest_1.expect)((0, structural_1.toContainCodeBlock)('Here:\n```\ncode\n```').pass).toBe(true);
98
+ });
99
+ (0, vitest_1.it)('fails when no code block', () => {
100
+ const r = (0, structural_1.toContainCodeBlock)('No code here');
101
+ (0, vitest_1.expect)(r.pass).toBe(false);
102
+ });
103
+ (0, vitest_1.it)('passes for specific language', () => {
104
+ (0, vitest_1.expect)((0, structural_1.toContainCodeBlock)('```python\nprint("hi")\n```', 'python').pass).toBe(true);
105
+ });
106
+ (0, vitest_1.it)('fails for wrong language', () => {
107
+ (0, vitest_1.expect)((0, structural_1.toContainCodeBlock)('```javascript\nconsole.log()\n```', 'python').pass).toBe(false);
108
+ });
109
+ (0, vitest_1.it)('language match is case-insensitive', () => {
110
+ (0, vitest_1.expect)((0, structural_1.toContainCodeBlock)('```Python\nprint("hi")\n```', 'python').pass).toBe(true);
111
+ });
112
+ });
113
+ //# sourceMappingURL=structural.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structural.test.js","sourceRoot":"","sources":["../../../src/__tests__/matchers/structural.test.ts"],"names":[],"mappings":";;AAAA,mCAA8C;AAC9C,0DAAkI;AAElI,IAAA,iBAAQ,EAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAA,WAAE,EAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,IAAA,eAAM,EAAC,IAAA,0BAAa,EAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,IAAA,eAAM,EAAC,IAAA,0BAAa,EAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,GAAG,IAAA,0BAAa,EAAC,UAAU,CAAC,CAAC;QACpC,IAAA,eAAM,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAA,eAAM,EAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,IAAA,eAAM,EAAC,IAAA,0BAAa,EAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,IAAA,eAAM,EAAC,IAAA,0BAAa,EAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,IAAA,eAAM,EAAC,IAAA,0BAAa,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SACxB;QACD,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC;KAC1B,CAAC;IAEF,IAAA,WAAE,EAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,IAAA,eAAM,EAAC,IAAA,0BAAa,EAAC,0BAA0B,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,GAAG,IAAA,0BAAa,EAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;QACnD,IAAA,eAAM,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAA,eAAM,EAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,CAAC,GAAG,IAAA,0BAAa,EAAC,gCAAgC,EAAE,MAAM,CAAC,CAAC;QAClE,IAAA,eAAM,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,GAAG,IAAA,0BAAa,EAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC5C,IAAA,eAAM,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAA,eAAM,EAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,IAAA,WAAE,EAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,IAAA,eAAM,EAAC,IAAA,6BAAgB,EAAC,qBAAqB,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,GAAG,IAAA,6BAAgB,EAAC,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QAClD,IAAA,eAAM,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAA,eAAM,EAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACzC,IAAA,eAAM,EAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,IAAA,eAAM,EAAC,IAAA,6BAAgB,EAAC,mCAAmC,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3G,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,IAAA,eAAM,EAAC,IAAA,6BAAgB,EAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,IAAA,WAAE,EAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,EAAE,GAAG,oDAAoD,CAAC;QAChE,IAAA,eAAM,EAAC,IAAA,8BAAiB,EAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,GAAG,IAAA,8BAAiB,EAAC,0BAA0B,CAAC,CAAC;QACxD,IAAA,eAAM,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAA,eAAM,EAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,GAAG,IAAA,8BAAiB,EAAC,kBAAkB,CAAC,CAAC;QAChD,IAAA,eAAM,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAA,eAAM,EAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,IAAA,eAAM,EAAC,IAAA,8BAAiB,EAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,GAAG,IAAA,8BAAiB,EAAC,iCAAiC,CAAC,CAAC;QAC/D,IAAA,eAAM,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAA,eAAM,EAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,IAAA,WAAE,EAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,IAAA,eAAM,EAAC,IAAA,+BAAkB,EAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,GAAG,IAAA,+BAAkB,EAAC,cAAc,CAAC,CAAC;QAC7C,IAAA,eAAM,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,IAAA,eAAM,EAAC,IAAA,+BAAkB,EAAC,6BAA6B,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,IAAA,eAAM,EAAC,IAAA,+BAAkB,EAAC,mCAAmC,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IACH,IAAA,WAAE,EAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,IAAA,eAAM,EAAC,IAAA,+BAAkB,EAAC,6BAA6B,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tone.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tone.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/matchers/tone.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const tone_1 = require("../../matchers/tone");
5
+ (0, vitest_1.describe)('toHaveSentiment', () => {
6
+ (0, vitest_1.it)('detects positive sentiment', () => {
7
+ (0, vitest_1.expect)((0, tone_1.toHaveSentiment)('This is excellent, amazing, and wonderful!', 'positive').pass).toBe(true);
8
+ });
9
+ (0, vitest_1.it)('detects negative sentiment', () => {
10
+ (0, vitest_1.expect)((0, tone_1.toHaveSentiment)('This is terrible, awful, and horrible.', 'negative').pass).toBe(true);
11
+ });
12
+ (0, vitest_1.it)('detects neutral sentiment', () => {
13
+ (0, vitest_1.expect)((0, tone_1.toHaveSentiment)('The meeting is scheduled for Tuesday at 3pm.', 'neutral').pass).toBe(true);
14
+ });
15
+ (0, vitest_1.it)('fails for mismatched sentiment', () => {
16
+ const r = (0, tone_1.toHaveSentiment)('This is terrible and awful.', 'positive');
17
+ (0, vitest_1.expect)(r.pass).toBe(false);
18
+ (0, vitest_1.expect)(r.message()).toContain('positive');
19
+ });
20
+ });
21
+ (0, vitest_1.describe)('toHaveTone', () => {
22
+ (0, vitest_1.it)('detects formal tone', () => {
23
+ const formal = 'The committee has determined that the proposed amendments to the regulatory framework shall be implemented in accordance with established protocols and procedures.';
24
+ (0, vitest_1.expect)((0, tone_1.toHaveTone)(formal, 'formal').pass).toBe(true);
25
+ });
26
+ (0, vitest_1.it)('detects casual tone', () => {
27
+ const casual = "Hey, I'm gonna check this out. Yeah, it's kinda cool stuff!";
28
+ (0, vitest_1.expect)((0, tone_1.toHaveTone)(casual, 'casual').pass).toBe(true);
29
+ });
30
+ (0, vitest_1.it)('detects technical tone', () => {
31
+ const technical = 'The implementation leverages polymorphic dispatching through vtable indirection, enabling subtype-specific `handleRequest` invocations.';
32
+ (0, vitest_1.expect)((0, tone_1.toHaveTone)(technical, 'technical').pass).toBe(true);
33
+ });
34
+ (0, vitest_1.it)('detects friendly tone', () => {
35
+ const friendly = "You're doing great! I'm happy to help you with this wonderful project!";
36
+ (0, vitest_1.expect)((0, tone_1.toHaveTone)(friendly, 'friendly').pass).toBe(true);
37
+ });
38
+ });
39
+ (0, vitest_1.describe)('toBeConcise', () => {
40
+ (0, vitest_1.it)('passes when word count is within limit', () => {
41
+ (0, vitest_1.expect)((0, tone_1.toBeConcise)('Short and sweet.', 100).pass).toBe(true);
42
+ });
43
+ (0, vitest_1.it)('fails when word count exceeds limit', () => {
44
+ const long = 'word '.repeat(150);
45
+ const r = (0, tone_1.toBeConcise)(long, 100);
46
+ (0, vitest_1.expect)(r.pass).toBe(false);
47
+ (0, vitest_1.expect)(r.message()).toContain('100');
48
+ });
49
+ (0, vitest_1.it)('uses default limit of 100', () => {
50
+ (0, vitest_1.expect)((0, tone_1.toBeConcise)('Short text.').pass).toBe(true);
51
+ });
52
+ });
53
+ (0, vitest_1.describe)('toNotBeVerbose', () => {
54
+ (0, vitest_1.it)('passes for short text', () => {
55
+ (0, vitest_1.expect)((0, tone_1.toNotBeVerbose)('Short text.').pass).toBe(true);
56
+ });
57
+ (0, vitest_1.it)('fails for too many words', () => {
58
+ const long = 'word '.repeat(250);
59
+ (0, vitest_1.expect)((0, tone_1.toNotBeVerbose)(long, { maxWords: 200 }).pass).toBe(false);
60
+ });
61
+ (0, vitest_1.it)('fails for too many sentences', () => {
62
+ const manySentences = Array(15).fill('This is a sentence.').join(' ');
63
+ (0, vitest_1.expect)((0, tone_1.toNotBeVerbose)(manySentences, { maxSentences: 10 }).pass).toBe(false);
64
+ });
65
+ (0, vitest_1.it)('uses default limits', () => {
66
+ (0, vitest_1.expect)((0, tone_1.toNotBeVerbose)('Short and sweet.').pass).toBe(true);
67
+ });
68
+ });
69
+ //# sourceMappingURL=tone.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tone.test.js","sourceRoot":"","sources":["../../../src/__tests__/matchers/tone.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-output-assert",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Rich assertion library for LLM outputs as Jest/Vitest matchers",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",