85 lines
2.3 KiB
Zig
85 lines
2.3 KiB
Zig
const std = @import("std");
|
|
const weather_provider = @import("provider.zig");
|
|
const types = @import("types.zig");
|
|
|
|
const Mock = @This();
|
|
|
|
allocator: std.mem.Allocator,
|
|
responses: std.StringHashMap(types.WeatherData),
|
|
|
|
pub fn init(allocator: std.mem.Allocator) !Mock {
|
|
return Mock{
|
|
.allocator = allocator,
|
|
.responses = std.StringHashMap(types.WeatherData).init(allocator),
|
|
};
|
|
}
|
|
|
|
pub fn provider(self: *Mock) weather_provider.WeatherProvider {
|
|
return .{
|
|
.ptr = self,
|
|
.vtable = &.{
|
|
.fetch = fetch,
|
|
.deinit = deinitProvider,
|
|
},
|
|
};
|
|
}
|
|
|
|
pub fn addResponse(self: *Mock, location: []const u8, data: types.WeatherData) !void {
|
|
const key = try self.allocator.dupe(u8, location);
|
|
try self.responses.put(key, data);
|
|
}
|
|
|
|
fn fetch(ptr: *anyopaque, allocator: std.mem.Allocator, location: []const u8) !types.WeatherData {
|
|
const self: *Mock = @ptrCast(@alignCast(ptr));
|
|
const data = self.responses.get(location) orelse return error.LocationNotFound;
|
|
|
|
return types.WeatherData{
|
|
.location = try allocator.dupe(u8, data.location),
|
|
.current = data.current,
|
|
.forecast = try allocator.dupe(types.ForecastDay, data.forecast),
|
|
.allocator = allocator,
|
|
};
|
|
}
|
|
|
|
fn deinitProvider(ptr: *anyopaque) void {
|
|
const self: *Mock = @ptrCast(@alignCast(ptr));
|
|
self.deinit();
|
|
}
|
|
|
|
pub fn deinit(self: *Mock) void {
|
|
var it = self.responses.iterator();
|
|
while (it.next()) |entry| {
|
|
self.allocator.free(entry.key_ptr.*);
|
|
}
|
|
self.responses.deinit();
|
|
}
|
|
|
|
test "mock weather provider" {
|
|
var mock = try Mock.init(std.testing.allocator);
|
|
defer mock.deinit();
|
|
|
|
const data = types.WeatherData{
|
|
.location = "London",
|
|
.current = .{
|
|
.temp_c = 15.0,
|
|
.temp_f = 59.0,
|
|
.condition = "Clear",
|
|
.weather_code = 113,
|
|
.humidity = 65,
|
|
.wind_kph = 10.0,
|
|
.wind_dir = "N",
|
|
.pressure_mb = 1013.0,
|
|
.precip_mm = 0.0,
|
|
},
|
|
.forecast = &.{},
|
|
.allocator = std.testing.allocator,
|
|
};
|
|
|
|
try mock.addResponse("London", data);
|
|
|
|
const p = mock.provider();
|
|
const result = try p.fetch(std.testing.allocator, "London");
|
|
defer result.deinit();
|
|
|
|
try std.testing.expectEqual(@as(f32, 15.0), result.current.temp_c);
|
|
}
|