11import { describe , expect , test } from "bun:test" ;
2- import { AgentCoreCLIError , InputValidationError } from "../errors" ;
2+ import { InputValidationError , MalformedServiceResponseError } from "../errors" ;
33import {
44 applyExampleIds ,
55 diffExamples ,
66 indexRemoteById ,
77 parseJsonl ,
8- stableStringify ,
98 stripExampleId ,
109} from "./datasetDiff" ;
1110
@@ -72,7 +71,7 @@ describe("indexRemoteById", () => {
7271 test ( "rejects a remote example without an id" , ( ) => {
7372 const remote = parseJsonl ( jsonl ( { scenario_id : "missing-id" } ) , "remote" ) ;
7473
75- expect ( ( ) => indexRemoteById ( remote ) ) . toThrow ( AgentCoreCLIError ) ;
74+ expect ( ( ) => indexRemoteById ( remote ) ) . toThrow ( MalformedServiceResponseError ) ;
7675 expect ( ( ) => indexRemoteById ( remote ) ) . toThrow ( / m i s s i n g a v a l i d e x a m p l e I d / ) ;
7776 try {
7877 indexRemoteById ( remote ) ;
@@ -84,7 +83,7 @@ describe("indexRemoteById", () => {
8483 test ( "rejects duplicate remote ids instead of overwriting an example" , ( ) => {
8584 const remote = parseJsonl ( jsonl ( withId ( "duplicate" ) , withId ( "duplicate" ) ) , "remote" ) ;
8685
87- expect ( ( ) => indexRemoteById ( remote ) ) . toThrow ( AgentCoreCLIError ) ;
86+ expect ( ( ) => indexRemoteById ( remote ) ) . toThrow ( MalformedServiceResponseError ) ;
8887 expect ( ( ) => indexRemoteById ( remote ) ) . toThrow ( / d u p l i c a t e e x a m p l e I d " d u p l i c a t e " / ) ;
8988 } ) ;
9089} ) ;
@@ -111,10 +110,16 @@ describe("diffExamples", () => {
111110 // must not read as modified.
112111 test ( "treats key reordering as unchanged" , ( ) => {
113112 const remote = indexRemoteById ( [
114- { exampleId : "a" , content : { exampleId : "a" , alpha : 1 , beta : 2 } } ,
113+ {
114+ exampleId : "a" ,
115+ content : { exampleId : "a" , alpha : 1 , nested : { first : 1 , second : 2 } } ,
116+ } ,
115117 ] ) ;
116118 const local : Parameters < typeof diffExamples > [ 0 ] = [
117- { exampleId : "a" , content : { beta : 2 , exampleId : "a" , alpha : 1 } } ,
119+ {
120+ exampleId : "a" ,
121+ content : { nested : { second : 2 , first : 1 } , exampleId : "a" , alpha : 1 } ,
122+ } ,
118123 ] ;
119124
120125 const diff = diffExamples ( local , remote ) ;
@@ -123,6 +128,20 @@ describe("diffExamples", () => {
123128 expect ( diff . updates ) . toEqual ( [ ] ) ;
124129 } ) ;
125130
131+ test ( "treats array reordering as an update" , ( ) => {
132+ const remote = indexRemoteById ( [
133+ { exampleId : "a" , content : { exampleId : "a" , values : [ 1 , 2 ] } } ,
134+ ] ) ;
135+ const local : Parameters < typeof diffExamples > [ 0 ] = [
136+ { exampleId : "a" , content : { exampleId : "a" , values : [ 2 , 1 ] } } ,
137+ ] ;
138+
139+ const diff = diffExamples ( local , remote ) ;
140+
141+ expect ( diff . unchanged ) . toBe ( 0 ) ;
142+ expect ( diff . updates ) . toEqual ( [ { exampleId : "a" , values : [ 2 , 1 ] } ] ) ;
143+ } ) ;
144+
126145 // An id absent remotely is stale (e.g. the dataset was recreated); re-adding is
127146 // recoverable, whereas failing would leave the file unusable.
128147 test ( "treats a stale exampleId as an addition and strips the id" , ( ) => {
@@ -227,7 +246,9 @@ describe("applyExampleIds", () => {
227246 const local = parseJsonl ( jsonl ( { scenario_id : "one" } , { scenario_id : "two" } ) , "file-path" ) ;
228247 const additions = diffExamples ( local , new Map ( ) ) . additions ;
229248
230- expect ( ( ) => applyExampleIds ( local , additions , assignedIds ) ) . toThrow ( AgentCoreCLIError ) ;
249+ expect ( ( ) => applyExampleIds ( local , additions , assignedIds ) ) . toThrow (
250+ MalformedServiceResponseError ,
251+ ) ;
231252 expect ( ( ) => applyExampleIds ( local , additions , assignedIds ) ) . toThrow (
232253 / r e t u r n e d \d + e x a m p l e I d s f o r 2 a d d i t i o n s / ,
233254 ) ;
@@ -237,7 +258,7 @@ describe("applyExampleIds", () => {
237258 const local = parseJsonl ( jsonl ( { scenario_id : "one" } ) , "file-path" ) ;
238259 const additions = diffExamples ( local , new Map ( ) ) . additions ;
239260
240- expect ( ( ) => applyExampleIds ( local , additions , [ "" ] ) ) . toThrow ( AgentCoreCLIError ) ;
261+ expect ( ( ) => applyExampleIds ( local , additions , [ "" ] ) ) . toThrow ( MalformedServiceResponseError ) ;
241262 expect ( ( ) => applyExampleIds ( local , additions , [ "" ] ) ) . toThrow ( / i n v a l i d e x a m p l e I d / ) ;
242263 } ) ;
243264
@@ -246,32 +267,14 @@ describe("applyExampleIds", () => {
246267 const additions = diffExamples ( local , new Map ( ) ) . additions ;
247268
248269 expect ( ( ) => applyExampleIds ( local , additions , [ "same-id" , "same-id" ] ) ) . toThrow (
249- AgentCoreCLIError ,
270+ MalformedServiceResponseError ,
250271 ) ;
251272 expect ( ( ) => applyExampleIds ( local , additions , [ "same-id" , "same-id" ] ) ) . toThrow (
252273 / d u p l i c a t e e x a m p l e I d " s a m e - i d " / ,
253274 ) ;
254275 } ) ;
255276} ) ;
256277
257- describe ( "stableStringify" , ( ) => {
258- test ( "sorts object keys at every depth" , ( ) => {
259- expect ( stableStringify ( { b : 1 , a : { d : 2 , c : 3 } } ) ) . toBe (
260- stableStringify ( { a : { c : 3 , d : 2 } , b : 1 } ) ,
261- ) ;
262- } ) ;
263-
264- // Arrays are ordered data — reordering them is a real change, unlike key order.
265- test ( "preserves array order" , ( ) => {
266- expect ( stableStringify ( [ 1 , 2 ] ) ) . not . toBe ( stableStringify ( [ 2 , 1 ] ) ) ;
267- } ) ;
268-
269- test ( "handles null and primitives" , ( ) => {
270- expect ( stableStringify ( null ) ) . toBe ( "null" ) ;
271- expect ( stableStringify ( { a : null } ) ) . toBe ( '{"a":null}' ) ;
272- } ) ;
273- } ) ;
274-
275278describe ( "stripExampleId" , ( ) => {
276279 test ( "removes only exampleId" , ( ) => {
277280 expect ( stripExampleId ( { exampleId : "a" , scenario_id : "x" } ) ) . toEqual ( { scenario_id : "x" } ) ;
0 commit comments