@@ -100,7 +100,7 @@ fn verify_mock_call(self: anytype, comptime method_name: [:0]const u8, args: any
100100 };
101101
102102 if (expectations .len () == 0 ) {
103- std .debug .print ("No more expectations left for method: {s}.{s}\n " , .{ @typeName (deduce_type (@TypeOf (self ))), method_name });
103+ std .debug .print ("No more expectations left for method: {s}.{s}, called with: {any} \n " , .{ @typeName (deduce_type (@TypeOf (self ))), method_name , args });
104104 unreachable ;
105105 }
106106
@@ -142,6 +142,11 @@ fn verify_mock_call(self: anytype, comptime method_name: [:0]const u8, args: any
142142}
143143
144144pub fn MockDestructorCall (self : anytype ) ! void {
145+ self .ref_counter .* -= 1 ;
146+ if (self .ref_counter .* > 0 ) {
147+ return ;
148+ }
149+
145150 var it = self .expectations .iterator ();
146151 // clean expectation with any times call
147152 while (it .next ()) | entry | {
@@ -156,7 +161,10 @@ pub fn MockDestructorCall(self: anytype) !void {
156161 node_it = next_node ;
157162 }
158163 }
164+
165+ self .allocator .destroy (self .ref_counter );
159166 self .expectations .deinit ();
167+ self .allocator .destroy (self .expectations );
160168}
161169
162170// Type-erased argument matcher that can store any type
@@ -456,7 +464,8 @@ pub fn MockInterface(comptime InterfaceType: type) type {
456464 const Self = @This ();
457465 allocator : std.mem.Allocator ,
458466 interface : InterfaceType ,
459- expectations : std .StringHashMap (std .DoublyLinkedList ),
467+ expectations : * std .StringHashMap (std .DoublyLinkedList ),
468+ ref_counter : * i32 ,
460469
461470 // Helper to extract function signature types from VTable
462471 fn getMethodTypes (comptime method_name : [:0 ]const u8 ) struct { args : type , ret : type } {
@@ -498,7 +507,6 @@ pub fn MockInterface(comptime InterfaceType: type) type {
498507 const types = getMethodTypes (method_name );
499508 const ArgsType = types .args ;
500509 const ReturnType = types .ret ;
501-
502510 var list = self .expectations .getPtr (method_name ) orelse blk : {
503511 self .expectations .put (method_name , std.DoublyLinkedList {}) catch unreachable ;
504512 break :blk self .expectations .getPtr (method_name ) orelse unreachable ;
@@ -536,6 +544,8 @@ pub fn MockInterface(comptime InterfaceType: type) type {
536544 };
537545
538546 const self = try allocator .create (Self );
547+ const refcount_mock : * i32 = try allocator .create (i32 );
548+ refcount_mock .* = 1 ;
539549
540550 const release = struct {
541551 fn call (p : * anyopaque , alloc : std.mem.Allocator ) void {
@@ -548,7 +558,7 @@ pub fn MockInterface(comptime InterfaceType: type) type {
548558 const s : * Self = @ptrCast (@alignCast (p ));
549559 const copy = alloc .create (Self ) catch return null ;
550560 copy .* = s .* ;
551- copy .expectations = std . StringHashMap ( std . DoublyLinkedList ). init ( alloc ) ;
561+ copy .ref_counter .* += 1 ;
552562 copy .interface .__ptr = copy ;
553563 return copy ;
554564 }
@@ -569,8 +579,10 @@ pub fn MockInterface(comptime InterfaceType: type) type {
569579 },
570580 .__refcount = refcount ,
571581 },
572- .expectations = std .StringHashMap (std .DoublyLinkedList ).init (allocator ),
582+ .expectations = try allocator .create (std .StringHashMap (std .DoublyLinkedList )),
583+ .ref_counter = refcount_mock ,
573584 };
585+ self .expectations .* = std .StringHashMap (std .DoublyLinkedList ).init (allocator );
574586 inline for (std .meta .fields (InterfaceType .VTable )) | field | {
575587 self .expectations .put (field .name , std.DoublyLinkedList {}) catch unreachable ;
576588 }
@@ -586,8 +598,10 @@ pub fn MockInterface(comptime InterfaceType: type) type {
586598 .dupe = & dupe .call ,
587599 },
588600 },
589- .expectations = std .StringHashMap (std .DoublyLinkedList ).init (allocator ),
601+ .expectations = try allocator .create (std .StringHashMap (std .DoublyLinkedList )),
602+ .ref_counter = refcount_mock ,
590603 };
604+ self .expectations .* = std .StringHashMap (std .DoublyLinkedList ).init (allocator );
591605 inline for (std .meta .fields (InterfaceType .VTable )) | field | {
592606 self .expectations .put (field .name , std.DoublyLinkedList {}) catch unreachable ;
593607 }
0 commit comments