Files
promptfoo--promptfoo/test/assertions/contains.test.ts
T
wehub-resource-sync 0d3cb498a3
Deploy local.promptfoo.app / Deploy to Cloudflare Pages (push) Waiting to run
Test and Publish Multi-arch Docker Image / test (push) Waiting to run
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-amd64 platform:linux/amd64 runner:ubuntu-latest]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-arm64 platform:linux/arm64 runner:ubuntu-24.04-arm]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / merge-docker-digests (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / Attest Multi-arch Image (push) Blocked by required conditions
Validate Renovate Config / Validate Renovate Configuration (push) Waiting to run
CI / Shell Format Check (push) Has been cancelled
CI / Check Ruby (3.4) (push) Has been cancelled
CI / CI Config (push) Has been cancelled
CI / Test on Node ${{ matrix.node }} and ${{ matrix.os }}${{ matrix.shard && format(' (shard {0}/3)', matrix.shard) || '' }} (push) Has been cancelled
CI / Build on Node ${{ matrix.node }} (push) Has been cancelled
CI / Style Check (push) Has been cancelled
CI / Generate Assets (push) Has been cancelled
CI / Check Python (3.14) (push) Has been cancelled
CI / Check Python (3.9) (push) Has been cancelled
CI / Build Docs (push) Has been cancelled
CI / Code Scan Action (push) Has been cancelled
CI / Site tests (push) Has been cancelled
CI / webui tests (push) Has been cancelled
CI / Run Integration Tests (push) Has been cancelled
CI / Run Smoke Tests (push) Has been cancelled
CI / Go Tests (push) Has been cancelled
CI / Share Test (push) Has been cancelled
CI / Redteam (Production API) (push) Has been cancelled
CI / Redteam (Staging API) (push) Has been cancelled
CI / GitHub Actions Lint (push) Has been cancelled
CI / Check Ruby (3.0) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
release-please / build (push) Has been cancelled
release-please / publish-npm (push) Has been cancelled
release-please / publish-npm-backfill (push) Has been cancelled
release-please / docker (push) Has been cancelled
release-please / publish-code-scan-action (push) Has been cancelled
release-please / attest-code-scan-action (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:24:08 +08:00

954 lines
27 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
handleContains,
handleContainsAll,
handleContainsAny,
handleIContains,
handleIContainsAll,
handleIContainsAny,
} from '../../src/assertions/contains';
import { createMockProvider, createProviderResponse } from '../factories/provider';
import type { AssertionParams, AssertionValue, AtomicTestCase } from '../../src/types/index';
const mockProvider = createMockProvider({
id: 'mock',
response: createProviderResponse({ output: 'mock' }),
});
const defaultParams = {
baseType: 'contains' as const,
assertionValueContext: {
vars: {},
test: {} as AtomicTestCase,
prompt: 'test prompt',
logProbs: undefined,
provider: mockProvider,
providerResponse: { output: 'hello world' },
},
output: 'hello world',
providerResponse: { output: 'hello world' },
test: {} as AtomicTestCase,
};
describe('handleContains', () => {
it('should pass when output contains the expected string', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains', value: 'world' },
renderedValue: 'world' as AssertionValue,
outputString: 'hello world',
inverse: false,
};
const result = handleContains(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should fail when output does not contain the expected string', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains', value: 'universe' },
renderedValue: 'universe' as AssertionValue,
outputString: 'hello world',
inverse: false,
};
const result = handleContains(params);
expect(result).toEqual({
pass: false,
score: 0,
reason: 'Expected output to contain "universe"',
assertion: params.assertion,
});
});
it('should handle inverse assertion correctly', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'not-contains', value: 'universe' },
renderedValue: 'universe' as AssertionValue,
outputString: 'hello world',
inverse: true,
};
const result = handleContains(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should use valueFromScript over renderedValue when available', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains', value: 'unused' },
renderedValue: 'unused' as AssertionValue,
valueFromScript: 'world' as AssertionValue,
outputString: 'hello world',
inverse: false,
};
const result = handleContains(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should throw error when value is missing', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains' },
renderedValue: undefined,
outputString: 'hello world',
inverse: false,
};
expect(() => handleContains(params)).toThrow(
'"contains" assertion type must have a string or number value',
);
});
});
describe('handleIContains', () => {
it('should pass when output contains the expected string case-insensitively', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains', value: 'WORLD' },
renderedValue: 'WORLD' as AssertionValue,
outputString: 'hello world',
inverse: false,
};
const result = handleIContains(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle mixed case in output and value', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains', value: 'WoRlD' },
renderedValue: 'WoRlD' as AssertionValue,
outputString: 'Hello WORLD',
inverse: false,
};
const result = handleIContains(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
});
describe.each([
['contains', handleContains],
['icontains', handleIContains],
] as const)('%s numeric values', (type, handler) => {
it.each([
{
outputString: 'There are 0 errors',
pass: true,
reason: 'Assertion passed',
},
{
outputString: 'no digits here',
pass: false,
reason: 'Expected output to contain "0"',
},
])('should return pass=$pass for 0', ({ outputString, pass, reason }) => {
const params: AssertionParams = {
...defaultParams,
baseType: type,
assertion: { type, value: 0 },
renderedValue: 0,
outputString,
inverse: false,
};
expect(handler(params)).toEqual({
pass,
score: pass ? 1 : 0,
reason,
assertion: params.assertion,
});
});
it('should reject NaN', () => {
const params: AssertionParams = {
...defaultParams,
baseType: type,
assertion: { type, value: Number.NaN },
renderedValue: Number.NaN,
outputString: 'NaN',
inverse: false,
};
expect(() => handler(params)).toThrow(
`"${type}" assertion type must have a string or number value`,
);
});
});
describe('handleContainsAny', () => {
it('should pass when output contains any of the expected strings', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: ['world', 'universe'] },
renderedValue: ['world', 'universe'] as AssertionValue,
outputString: 'hello world',
inverse: false,
};
const result = handleContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle comma-separated string input', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: 'world,universe' },
renderedValue: 'world,universe' as AssertionValue,
outputString: 'hello world',
inverse: false,
};
const result = handleContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle quoted values with commas', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"hello, world",universe' },
renderedValue: '"hello, world",universe' as AssertionValue,
outputString: 'hello, world',
inverse: false,
};
const result = handleContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle complex quoted values with commas and spaces', () => {
const params: AssertionParams = {
...defaultParams,
assertion: {
type: 'contains-any',
value: '"hello, dear world", "goodbye, universe", simple',
},
renderedValue: '"hello, dear world", "goodbye, universe", simple' as AssertionValue,
outputString: 'hello, dear world is here',
inverse: false,
};
const result = handleContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle empty quoted strings', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"",' },
renderedValue: '"",' as AssertionValue,
outputString: '',
inverse: false,
};
const result = handleContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should not create false-positive empty token from tab after quoted field', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"hello, world"\t,foo' },
renderedValue: '"hello, world"\t,foo' as AssertionValue,
outputString: 'zzz',
inverse: false,
};
const result = handleContainsAny(params);
expect(result.pass).toBe(false);
});
it('should handle non-space whitespace between fields', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"hello, world"\t,\t"foo"' },
renderedValue: '"hello, world"\t,\t"foo"' as AssertionValue,
outputString: 'foo',
inverse: false,
};
const result = handleContainsAny(params);
expect(result.pass).toBe(true);
});
it('should handle CSV-style doubled quotes as literal quote', () => {
// "a""b" in CSV means the value a"b
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"a""b",c' },
renderedValue: '"a""b",c' as AssertionValue,
outputString: 'a"b',
inverse: false,
};
const result = handleContainsAny(params);
expect(result.pass).toBe(true);
});
it('should not false-positive on partial token from doubled quotes', () => {
// "a""b",c should parse as ["a\"b", "c"], not ["a", "b", "c"]
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"a""b",c' },
renderedValue: '"a""b",c' as AssertionValue,
outputString: 'b',
inverse: false,
};
const result = handleContainsAny(params);
expect(result.pass).toBe(false);
});
it('should handle escaped quotes and commas in quoted strings', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"hello\\"world,test", "another,test"' },
renderedValue: '"hello\\"world,test", "another,test"' as AssertionValue,
outputString: 'hello"world,test',
inverse: false,
};
const result = handleContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle null value after regex match', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '""' },
renderedValue: '""' as AssertionValue,
outputString: 'test',
inverse: false,
};
const result = handleContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle regex match with no groups', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"test"' },
renderedValue: '"test"' as AssertionValue,
outputString: 'test',
inverse: false,
};
const result = handleContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle regex match with escaped characters', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"test\\test"' },
renderedValue: '"test\\test"' as AssertionValue,
outputString: 'test\\test',
inverse: false,
};
const result = handleContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle regex match with complex escaping', () => {
// Value "test\\test" has an escaped backslash, which parses to test\test
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"test\\\\test"' },
renderedValue: '"test\\\\test"' as AssertionValue,
outputString: 'test\\test',
inverse: false,
};
const result = handleContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should correctly parse both fields with escaped quotes', () => {
// Verifies the second quoted field is parsed correctly (not split by comma)
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"hello\\"world,test", "another,test"' },
renderedValue: '"hello\\"world,test", "another,test"' as AssertionValue,
outputString: 'another,test',
inverse: false,
};
const result = handleContainsAny(params);
expect(result.pass).toBe(true);
});
it('should fail when escaped quote value does not match', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"hello\\"world,test", "another,test"' },
renderedValue: '"hello\\"world,test", "another,test"' as AssertionValue,
outputString: 'something completely different',
inverse: false,
};
const result = handleContainsAny(params);
expect(result.pass).toBe(false);
});
it('should reject unmatched quotes', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"test' },
renderedValue: '"test' as AssertionValue,
outputString: 'test',
inverse: false,
};
expect(() => handleContainsAny(params)).toThrow(
'Unterminated quoted field in contains assertion value',
);
});
it('should reject non-delimiter characters after quoted fields', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"hello"world' },
renderedValue: '"hello"world' as AssertionValue,
outputString: 'hello world',
inverse: false,
};
expect(() => handleContainsAny(params)).toThrow(
'Expected comma after quoted field in contains assertion value',
);
});
it('should reject whitespace-separated quoted and unquoted fields without a comma', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-any', value: '"hello" world' },
renderedValue: '"hello" world' as AssertionValue,
outputString: 'hello world',
inverse: false,
};
expect(() => handleContainsAny(params)).toThrow(
'Expected comma after quoted field in contains assertion value',
);
});
});
describe('handleIContainsAny', () => {
it('should handle escaped quotes with commas case-insensitively', () => {
const params: AssertionParams = {
...defaultParams,
assertion: {
type: 'icontains-any',
value: '"hello\\"world,test", "another,test"',
},
renderedValue: '"hello\\"world,test", "another,test"' as AssertionValue,
outputString: 'ANOTHER,TEST',
inverse: false,
};
const result = handleIContainsAny(params);
expect(result.pass).toBe(true);
});
it('should handle quoted values with commas', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-any', value: '"hello, world",universe' },
renderedValue: '"hello, world",universe' as AssertionValue,
outputString: 'HELLO, WORLD',
inverse: false,
};
const result = handleIContainsAny(params);
expect(result.pass).toBe(true);
});
it('should pass when output contains any of the expected strings case-insensitively', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-any', value: ['WORLD', 'UNIVERSE'] },
renderedValue: ['WORLD', 'UNIVERSE'] as AssertionValue,
outputString: 'hello world',
inverse: false,
};
const result = handleIContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle comma-separated string input case-insensitively', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-any', value: 'WORLD,UNIVERSE' },
renderedValue: 'WORLD,UNIVERSE' as AssertionValue,
outputString: 'hello world',
inverse: false,
};
const result = handleIContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle string input with multiple commas and spaces', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-any', value: 'HELLO, WORLD , UNIVERSE' },
renderedValue: 'HELLO, WORLD , UNIVERSE' as AssertionValue,
outputString: 'hello',
inverse: false,
};
const result = handleIContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should ignore empty entries in comma-separated list', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-any', value: ',WORLD,,' },
renderedValue: ',WORLD,,' as AssertionValue,
outputString: '',
inverse: false,
};
const result = handleIContainsAny(params);
expect(result).toEqual({
pass: false,
score: 0,
reason: 'Expected output to contain one of "WORLD"',
assertion: params.assertion,
});
});
it('should preserve quoted empty strings in comma-separated list', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-any', value: '"",WORLD' },
renderedValue: '"",WORLD' as AssertionValue,
outputString: '',
inverse: false,
};
const result = handleIContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle string value with spaces', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-any', value: ' HELLO ' },
renderedValue: ' HELLO ' as AssertionValue,
outputString: 'hello',
inverse: false,
};
const result = handleIContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle string value with multiple spaces between commas', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-any', value: 'HELLO , WORLD' },
renderedValue: 'HELLO , WORLD' as AssertionValue,
outputString: 'hello',
inverse: false,
};
const result = handleIContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle string value with multiple spaces and special characters', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-any', value: ' HELLO , WORLD ' },
renderedValue: ' HELLO , WORLD ' as AssertionValue,
outputString: 'hello',
inverse: false,
};
const result = handleIContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle string value with multiple spaces and commas', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-any', value: ' HELLO , , WORLD ' },
renderedValue: ' HELLO , , WORLD ' as AssertionValue,
outputString: 'hello',
inverse: false,
};
const result = handleIContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle string value with multiple consecutive commas', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-any', value: 'HELLO,,,,WORLD' },
renderedValue: 'HELLO,,,,WORLD' as AssertionValue,
outputString: 'hello',
inverse: false,
};
const result = handleIContainsAny(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should handle string value with only spaces and commas', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-any', value: ' , , ' },
renderedValue: ' , , ' as AssertionValue,
outputString: '',
inverse: false,
};
const result = handleIContainsAny(params);
expect(result).toEqual({
pass: false,
score: 0,
reason: 'Expected output to contain one of ""',
assertion: params.assertion,
});
});
});
describe('handleContainsAll', () => {
it('should handle quoted values with commas', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-all', value: '"hello, world","foo"' },
renderedValue: '"hello, world","foo"' as AssertionValue,
outputString: 'hello, world and foo',
inverse: false,
};
const result = handleContainsAll(params);
expect(result.pass).toBe(true);
});
it('should fail when quoted value is missing', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-all', value: '"hello, world","bar"' },
renderedValue: '"hello, world","bar"' as AssertionValue,
outputString: 'hello, world and foo',
inverse: false,
};
const result = handleContainsAll(params);
expect(result.pass).toBe(false);
});
it('should handle single value without commas', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-all', value: 'hello' },
renderedValue: 'hello' as AssertionValue,
outputString: 'hello world',
inverse: false,
};
const result = handleContainsAll(params);
expect(result.pass).toBe(true);
});
it('should handle escaped quotes in contains-all', () => {
const params: AssertionParams = {
...defaultParams,
assertion: {
type: 'contains-all',
value: '"say \\"hello\\"", "another,phrase"',
},
renderedValue: '"say \\"hello\\"", "another,phrase"' as AssertionValue,
outputString: 'say "hello" and another,phrase here',
inverse: false,
};
const result = handleContainsAll(params);
expect(result.pass).toBe(true);
});
it('should fail when escaped-quote value is missing from output', () => {
const params: AssertionParams = {
...defaultParams,
assertion: {
type: 'contains-all',
value: '"say \\"hello\\"", "missing,value"',
},
renderedValue: '"say \\"hello\\"", "missing,value"' as AssertionValue,
outputString: 'say "hello" only',
inverse: false,
};
const result = handleContainsAll(params);
expect(result.pass).toBe(false);
});
it('should pass when output contains all expected strings', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-all', value: ['hello', 'world'] },
renderedValue: ['hello', 'world'] as AssertionValue,
outputString: 'hello world',
inverse: false,
};
const result = handleContainsAll(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should fail when output is missing some expected strings', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'contains-all', value: ['hello', 'world', 'universe'] },
renderedValue: ['hello', 'world', 'universe'] as AssertionValue,
outputString: 'hello world',
inverse: false,
};
const result = handleContainsAll(params);
expect(result).toEqual({
pass: false,
score: 0,
reason: 'Expected output to contain all of [hello, world, universe]. Missing: [universe]',
assertion: params.assertion,
});
});
});
describe('handleIContainsAll', () => {
it('should handle escaped quotes case-insensitively', () => {
const params: AssertionParams = {
...defaultParams,
assertion: {
type: 'icontains-all',
value: '"say \\"hello\\"", "another,phrase"',
},
renderedValue: '"say \\"hello\\"", "another,phrase"' as AssertionValue,
outputString: 'SAY "HELLO" AND ANOTHER,PHRASE HERE',
inverse: false,
};
const result = handleIContainsAll(params);
expect(result.pass).toBe(true);
});
it('should handle quoted values with commas case-insensitively', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-all', value: '"Hello, World","Foo"' },
renderedValue: '"Hello, World","Foo"' as AssertionValue,
outputString: 'HELLO, WORLD AND FOO',
inverse: false,
};
const result = handleIContainsAll(params);
expect(result.pass).toBe(true);
});
it('should handle empty string value', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-all', value: '""' },
renderedValue: '""' as AssertionValue,
outputString: 'hello',
inverse: false,
};
const result = handleIContainsAll(params);
expect(result.pass).toBe(true);
});
it('should pass when output contains all expected strings case-insensitively', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-all', value: ['HELLO', 'WORLD'] },
renderedValue: ['HELLO', 'WORLD'] as AssertionValue,
outputString: 'hello world',
inverse: false,
};
const result = handleIContainsAll(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
it('should fail when output is missing some expected strings case-insensitively', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-all', value: ['HELLO', 'WORLD', 'UNIVERSE'] },
renderedValue: ['HELLO', 'WORLD', 'UNIVERSE'] as AssertionValue,
outputString: 'hello world',
inverse: false,
};
const result = handleIContainsAll(params);
expect(result).toEqual({
pass: false,
score: 0,
reason: 'Expected output to contain all of [HELLO, WORLD, UNIVERSE]. Missing: [UNIVERSE]',
assertion: params.assertion,
});
});
it('should handle mixed case in both output and expected values', () => {
const params: AssertionParams = {
...defaultParams,
assertion: { type: 'icontains-all', value: ['HeLLo', 'WoRLD'] },
renderedValue: ['HeLLo', 'WoRLD'] as AssertionValue,
outputString: 'HELLO world',
inverse: false,
};
const result = handleIContainsAll(params);
expect(result).toEqual({
pass: true,
score: 1,
reason: 'Assertion passed',
assertion: params.assertion,
});
});
});