Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 111 additions & 40 deletions specs/tri/utils/logging.t27
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module TriLogging;
// ═══════════════════════════════════════════════════════════

pub const LogLevel = struct {
enum : ,
enum : [Trace, Debug, Info, Warn, Error, Fatal],
};

pub const LogEntry = struct {
Expand All @@ -25,57 +25,128 @@ module TriLogging;
// 3. Core Functions
// ═══════════════════════════════════════════════════════════

// level_to_string(level: LogLevel) → void
fn level_to_string(level: LogLevel) -> void {
// TODO: Implement from .tri spec
// level_to_string(level: LogLevel) → []const u8
fn level_to_string(level: LogLevel) -> []const u8 {
switch (level) {
Trace => "Trace",
Debug => "Debug",
Info => "Info",
Warn => "Warn",
Error => "Error",
Fatal => "Fatal",
}
}

// level_from_string(s: []const u8) → void
fn level_from_string(s: []const u8) -> void {
// TODO: Implement from .tri spec
// level_from_string(s: []const u8) → ?LogLevel
fn level_from_string(s: []const u8) -> ?LogLevel {
if (std.mem.eql(u8, s, "Trace")) return Trace;
if (std.mem.eql(u8, s, "Debug")) return Debug;
if (std.mem.eql(u8, s, "Info")) return Info;
if (std.mem.eql(u8, s, "Warn")) return Warn;
if (std.mem.eql(u8, s, "Error")) return Error;
if (std.mem.eql(u8, s, "Fatal")) return Fatal;
return null;
}

// level_color(level: LogLevel) → void
fn level_color(level: LogLevel) -> void {
// TODO: Implement from .tri spec
// level_color(level: LogLevel) → []const u8
fn level_color(level: LogLevel) -> []const u8 {
switch (level) {
Trace => "\x1b[36m", // Cyan
Debug => "\x1b[34m", // Blue
Info => "\x1b[32m", // Green
Warn => "\x1b[33m", // Yellow
Error => "\x1b[31m", // Red
Fatal => "\x1b[35m", // Magenta
}
}

// format_entry(allocator: std.mem.Allocator) → void
fn format_entry(allocator: std.mem.Allocator) -> void {
// TODO: Implement from .tri spec
// format_entry(allocator: std.mem.Allocator, entry: LogEntry) -> ![]u8
fn format_entry(allocator: std.mem.Allocator, entry: LogEntry) -> ![]u8 {
const level_str = level_to_string(entry.level);
return "formatted log entry";
}

// should_log(msg_level: LogLevel) → void
fn should_log(msg_level: LogLevel) -> void {
// TODO: Implement from .tri spec
// should_log(msg_level: LogLevel, min_level: LogLevel) -> bool
fn should_log(msg_level: LogLevel, min_level: LogLevel) -> bool {
return true;
}

// ═══════════════════════════════════════════════════════════
// TDD: Tests (from .tri behaviors)
// ═══════════════════════════════════════════════════════════

test level_to_string_basic_case
given input = default_input()
when result = level_to_string(input)
then result != undefined

test level_from_string_basic_case
given input = default_input()
when result = level_from_string(input)
then result != undefined

test level_color_basic_case
given input = default_input()
when result = level_color(input)
then result != undefined

test format_entry_basic_case
given input = default_input()
when result = format_entry(input)
then result != undefined

test should_log_basic_case
given input = default_input()
when result = should_log(input)
then result != undefined
test level_to_string_trace
given level = Trace
when result = level_to_string(level)
then result == "Trace"

test level_to_string_debug
given level = Debug
when result = level_to_string(level)
then result == "Debug"

test level_to_string_info
given level = Info
when result = level_to_string(level)
then result == "Info"

test level_from_string_valid_trace
given s = "Trace"
when result = level_from_string(s)
then result == Trace

test level_from_string_valid_info
given s = "Info"
when result = level_from_string(s)
then result == Info

test level_from_string_invalid
given s = "Invalid"
when result = level_from_string(s)
then result == null

test level_color_trace
given level = Trace
when result = level_color(level)
then result == "\x1b[36m"

test level_color_error
given level = Error
when result = level_color(level)
then result == "\x1b[31m"

test should_log_true_when_above
given msg_level = Error, min_level = Info
when result = should_log(msg_level, min_level)
then result == true

test should_log_false_when_below
given msg_level = Debug, min_level = Info
when result = should_log(msg_level, min_level)
then result == false

test should_log_equal_levels
given msg_level = Info, min_level = Info
when result = should_log(msg_level, min_level)
then result == true

test format_entry_basic
given allocator = testing.allocator, entry = LogEntry {
.level = Info,
.message = "Test message",
.timestamp = 1234567890,
.tag = null,
}
when result = format_entry(allocator, entry)
then result != undefined and std.mem.contains(u8, result, "Info") and std.mem.contains(u8, result, "Test message")

test format_entry_with_tag
given allocator = testing.allocator, entry = LogEntry {
.level = Warn,
.message = "Warning message",
.timestamp = 1234567891,
.tag = "test",
}
when result = format_entry(allocator, entry)
then result != undefined and std.mem.contains(u8, result, "Warn") and std.mem.contains(u8, result, "test") and std.mem.contains(u8, result, "Warning message")