Skip to content

Commit f0c098a

Browse files
committed
fix for mock copying
1 parent 437eb4a commit f0c098a

1 file changed

Lines changed: 20 additions & 6 deletions

File tree

src/mock.zig

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

144144
pub 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

Comments
 (0)