@@ -27,37 +27,80 @@ class MockDriver implements Driver {
2727 async find ( objectName : string , query : any ) {
2828 let items = this . data [ objectName ] || [ ] ;
2929
30- // Apply filters if provided
30+ // Apply filters if provided (supports FilterNode array format)
3131 if ( query && query . filters ) {
32- const filters = query . filters ;
33- if ( typeof filters === 'object' ) {
34- const filterKeys = Object . keys ( filters ) ;
35- if ( filterKeys . length > 0 ) {
36- items = items . filter ( item => {
37- for ( const [ key , value ] of Object . entries ( filters ) ) {
38- if ( item [ key ] !== value ) {
39- return false ;
40- }
41- }
42- return true ;
43- } ) ;
44- }
45- }
32+ items = items . filter ( item => this . matchesFilter ( item , query . filters ) ) ;
4633 }
4734
48- // Apply skip and limit if provided
35+ // Apply skip and top/ limit if provided (QueryAST uses 'top' for limit)
4936 if ( query ) {
5037 if ( query . skip ) {
5138 items = items . slice ( query . skip ) ;
5239 }
53- if ( query . limit ) {
54- items = items . slice ( 0 , query . limit ) ;
40+ if ( query . top || query . limit ) {
41+ items = items . slice ( 0 , query . top || query . limit ) ;
5542 }
5643 }
5744
5845 return items ;
5946 }
60-
47+
48+ private matchesFilter ( item : any , filter : any ) : boolean {
49+ if ( ! filter ) return true ;
50+
51+ // Handle FilterNode array format: [[field, op, value]] or [[field, op, value], 'and', [field2, op2, value2]]
52+ if ( Array . isArray ( filter ) ) {
53+ // Single condition: [field, op, value]
54+ if ( filter . length === 3 && typeof filter [ 0 ] === 'string' ) {
55+ const [ field , op , value ] = filter ;
56+ return this . evaluateCondition ( item , field , op , value ) ;
57+ }
58+
59+ // Multiple conditions with logical operators
60+ let result = true ;
61+ let currentOp = 'and' ;
62+ for ( let i = 0 ; i < filter . length ; i ++ ) {
63+ const element = filter [ i ] ;
64+ if ( typeof element === 'string' ) {
65+ currentOp = element ; // 'and' or 'or'
66+ } else if ( Array . isArray ( element ) ) {
67+ const conditionResult = this . matchesFilter ( item , element ) ;
68+ if ( currentOp === 'and' ) {
69+ result = result && conditionResult ;
70+ } else if ( currentOp === 'or' ) {
71+ result = result || conditionResult ;
72+ }
73+ }
74+ }
75+ return result ;
76+ }
77+
78+ // Handle simple object format: { field: value }
79+ if ( typeof filter === 'object' ) {
80+ for ( const [ key , value ] of Object . entries ( filter ) ) {
81+ if ( item [ key ] !== value ) {
82+ return false ;
83+ }
84+ }
85+ return true ;
86+ }
87+
88+ return true ;
89+ }
90+
91+ private evaluateCondition ( item : any , field : string , op : string , value : any ) : boolean {
92+ const fieldValue = item [ field ] ;
93+ switch ( op ) {
94+ case '=' : return fieldValue === value ;
95+ case '!=' : return fieldValue !== value ;
96+ case '>' : return fieldValue > value ;
97+ case '>=' : return fieldValue >= value ;
98+ case '<' : return fieldValue < value ;
99+ case '<=' : return fieldValue <= value ;
100+ case 'in' : return Array . isArray ( value ) && value . includes ( fieldValue ) ;
101+ default : return true ;
102+ }
103+ }
61104 async findOne ( objectName : string , id : string | number , query ?: any , options ?: any ) {
62105 const items = this . data [ objectName ] || [ ] ;
63106 if ( id !== undefined && id !== null ) {
@@ -97,7 +140,13 @@ class MockDriver implements Driver {
97140 }
98141
99142 async count ( objectName : string , query : any ) {
100- return ( this . data [ objectName ] || [ ] ) . length ;
143+ // Count should apply filters but not skip/limit
144+ const countQuery = { ...query } ;
145+ delete countQuery . skip ;
146+ delete countQuery . top ;
147+ delete countQuery . limit ;
148+ const items = await this . find ( objectName , countQuery ) ;
149+ return items . length ;
101150 }
102151
103152 async createMany ( objectName : string , data : any [ ] ) {
0 commit comments