@@ -800,6 +800,66 @@ describe("validateFixtures", () => {
800800 expect ( validateFixtures ( fixtures ) ) . toHaveLength ( 0 ) ;
801801 } ) ;
802802
803+ // --- match.turnIndex / match.hasToolResult type checks ---
804+
805+ it ( "error: turnIndex is negative" , ( ) => {
806+ const fixtures = [ makeFixture ( { match : { userMessage : "test" , turnIndex : - 1 } } ) ] ;
807+ const results = validateFixtures ( fixtures ) ;
808+ expect ( results . some ( ( r ) => r . severity === "error" && r . message . includes ( "turnIndex" ) ) ) . toBe (
809+ true ,
810+ ) ;
811+ } ) ;
812+
813+ it ( "error: turnIndex is a float" , ( ) => {
814+ const fixtures = [ makeFixture ( { match : { userMessage : "test" , turnIndex : 1.5 } } ) ] ;
815+ const results = validateFixtures ( fixtures ) ;
816+ expect ( results . some ( ( r ) => r . severity === "error" && r . message . includes ( "turnIndex" ) ) ) . toBe (
817+ true ,
818+ ) ;
819+ } ) ;
820+
821+ it ( "error: turnIndex is a string" , ( ) => {
822+ const fixtures = [ makeFixture ( { match : { userMessage : "test" , turnIndex : "zero" as never } } ) ] ;
823+ const results = validateFixtures ( fixtures ) ;
824+ expect ( results . some ( ( r ) => r . severity === "error" && r . message . includes ( "turnIndex" ) ) ) . toBe (
825+ true ,
826+ ) ;
827+ } ) ;
828+
829+ it ( "no error: turnIndex is 0 (falsy but valid)" , ( ) => {
830+ const fixtures = [ makeFixture ( { match : { userMessage : "test" , turnIndex : 0 } } ) ] ;
831+ const results = validateFixtures ( fixtures ) ;
832+ expect ( results . filter ( ( r ) => r . message . includes ( "turnIndex" ) ) ) . toHaveLength ( 0 ) ;
833+ } ) ;
834+
835+ it ( "no error: turnIndex is a positive integer" , ( ) => {
836+ const fixtures = [ makeFixture ( { match : { userMessage : "test" , turnIndex : 3 } } ) ] ;
837+ const results = validateFixtures ( fixtures ) ;
838+ expect ( results . filter ( ( r ) => r . message . includes ( "turnIndex" ) ) ) . toHaveLength ( 0 ) ;
839+ } ) ;
840+
841+ it ( "error: hasToolResult is a string" , ( ) => {
842+ const fixtures = [
843+ makeFixture ( { match : { userMessage : "test" , hasToolResult : "yes" as never } } ) ,
844+ ] ;
845+ const results = validateFixtures ( fixtures ) ;
846+ expect ( results . some ( ( r ) => r . severity === "error" && r . message . includes ( "hasToolResult" ) ) ) . toBe (
847+ true ,
848+ ) ;
849+ } ) ;
850+
851+ it ( "no error: hasToolResult is false (falsy but valid)" , ( ) => {
852+ const fixtures = [ makeFixture ( { match : { userMessage : "test" , hasToolResult : false } } ) ] ;
853+ const results = validateFixtures ( fixtures ) ;
854+ expect ( results . filter ( ( r ) => r . message . includes ( "hasToolResult" ) ) ) . toHaveLength ( 0 ) ;
855+ } ) ;
856+
857+ it ( "no error: hasToolResult is true" , ( ) => {
858+ const fixtures = [ makeFixture ( { match : { userMessage : "test" , hasToolResult : true } } ) ] ;
859+ const results = validateFixtures ( fixtures ) ;
860+ expect ( results . filter ( ( r ) => r . message . includes ( "hasToolResult" ) ) ) . toHaveLength ( 0 ) ;
861+ } ) ;
862+
803863 // --- Warning checks ---
804864
805865 it ( "warning: duplicate userMessage" , ( ) => {
@@ -813,6 +873,53 @@ describe("validateFixtures", () => {
813873 ) ;
814874 } ) ;
815875
876+ it ( "no warning: same userMessage but different turnIndex" , ( ) => {
877+ const fixtures = [
878+ makeFixture ( { match : { userMessage : "hello" , turnIndex : 0 } } ) ,
879+ makeFixture ( { match : { userMessage : "hello" , turnIndex : 1 } } ) ,
880+ ] ;
881+ const results = validateFixtures ( fixtures ) ;
882+ const duplicateWarnings = results . filter (
883+ ( r ) => r . severity === "warning" && r . message . includes ( "duplicate" ) ,
884+ ) ;
885+ expect ( duplicateWarnings ) . toHaveLength ( 0 ) ;
886+ } ) ;
887+
888+ it ( "no warning: same userMessage but different hasToolResult" , ( ) => {
889+ const fixtures = [
890+ makeFixture ( { match : { userMessage : "hello" , hasToolResult : false } } ) ,
891+ makeFixture ( { match : { userMessage : "hello" , hasToolResult : true } } ) ,
892+ ] ;
893+ const results = validateFixtures ( fixtures ) ;
894+ const duplicateWarnings = results . filter (
895+ ( r ) => r . severity === "warning" && r . message . includes ( "duplicate" ) ,
896+ ) ;
897+ expect ( duplicateWarnings ) . toHaveLength ( 0 ) ;
898+ } ) ;
899+
900+ it ( "no warning: same userMessage but different sequenceIndex" , ( ) => {
901+ const fixtures = [
902+ makeFixture ( { match : { userMessage : "hello" , sequenceIndex : 0 } } ) ,
903+ makeFixture ( { match : { userMessage : "hello" , sequenceIndex : 1 } } ) ,
904+ ] ;
905+ const results = validateFixtures ( fixtures ) ;
906+ const duplicateWarnings = results . filter (
907+ ( r ) => r . severity === "warning" && r . message . includes ( "duplicate" ) ,
908+ ) ;
909+ expect ( duplicateWarnings ) . toHaveLength ( 0 ) ;
910+ } ) ;
911+
912+ it ( "warning: same userMessage with identical turnIndex/hasToolResult/sequenceIndex" , ( ) => {
913+ const fixtures = [
914+ makeFixture ( { match : { userMessage : "hello" , turnIndex : 1 , hasToolResult : true } } ) ,
915+ makeFixture ( { match : { userMessage : "hello" , turnIndex : 1 , hasToolResult : true } } ) ,
916+ ] ;
917+ const results = validateFixtures ( fixtures ) ;
918+ expect ( results . some ( ( r ) => r . severity === "warning" && r . message . includes ( "duplicate" ) ) ) . toBe (
919+ true ,
920+ ) ;
921+ } ) ;
922+
816923 it ( "warning: catch-all not in last position" , ( ) => {
817924 const fixtures = [ makeFixture ( { match : { } } ) , makeFixture ( { match : { userMessage : "hello" } } ) ] ;
818925 const results = validateFixtures ( fixtures ) ;
0 commit comments