import 'dart:convert'; import 'package:flutter_test/flutter_test.dart'; import 'package:life_helper/ai/tools/tool_envelope.dart'; void main() { group('ToolResult', () { test('ToolOk JSON 형태', () { const r = ToolOk({'a': 1}); expect(r.toJson(), { 'status': 'ok', 'data': {'a': 1} }); }); test('ToolErr JSON 형태', () { const r = ToolErr('validation', '잘못된 인자'); expect(r.toJson(), { 'status': 'error', 'code': 'validation', 'reason': '잘못된 인자', }); }); test('ToolCancelled JSON 형태', () { const r = ToolCancelled(); expect(r.toJson(), { 'status': 'cancelled', 'reason': 'user did not confirm', }); }); }); group('encodeToolResult 2KB cap', () { test('payload 작으면 그대로', () { const r = ToolOk({'k': 'v'}); final s = encodeToolResult(r); expect(jsonDecode(s), { 'status': 'ok', 'data': {'k': 'v'} }); }); test('payload 2KB 초과 시 truncation hint 로 대체', () { final big = ToolOk({'blob': 'x' * 5000}); final s = encodeToolResult(big); expect(s.length, lessThan(500)); final decoded = jsonDecode(s) as Map; expect(decoded['status'], 'ok'); final data = decoded['data'] as Map; expect(data['_truncated'], true); expect(data['_hint'], contains('query_protocol')); }); test('error/cancelled 는 작아서 그대로', () { expect( encodeToolResult(const ToolErr('e', 'r')).length, lessThan(100), ); expect( encodeToolResult(const ToolCancelled()).length, lessThan(100), ); }); }); }