mirror of
				https://codeberg.org/ziglings/exercises.git
				synced 2025-11-04 04:35:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			113 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Zig
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Zig
		
	
	
	
	
	
//
 | 
						|
// A big advantage of Zig is the integration of its own test system.
 | 
						|
// This allows the philosophy of Test Driven Development (TDD) to be
 | 
						|
// implemented perfectly. Zig even goes one step further than other
 | 
						|
// languages, the tests can be included directly in the source file.
 | 
						|
//
 | 
						|
// This has several advantages. On the one hand it is much clearer to
 | 
						|
// have everything in one file, both the source code and the associated
 | 
						|
// test code. On the other hand, it is much easier for third parties
 | 
						|
// to understand what exactly a function is supposed to do if they can
 | 
						|
// simply look at the test inside the source and compare both.
 | 
						|
//
 | 
						|
// Especially if you want to understand how e.g. the standard library
 | 
						|
// of Zig works, this approach is very helpful. Furthermore it is very
 | 
						|
// practical, if you want to report a bug to the Zig community, to
 | 
						|
// illustrate it with a small example including a test.
 | 
						|
//
 | 
						|
// Therefore, in this exercise we will deal with the basics of testing
 | 
						|
// in Zig. Basically, tests work as follows: you pass certain parameters
 | 
						|
// to a function, for which you get a return - the result. This is then
 | 
						|
// compared with the EXPECTED value. If both values match, the test is
 | 
						|
// passed, otherwise an error message is displayed.
 | 
						|
//
 | 
						|
//          testing.expect(foo(param1, param2) == expected);
 | 
						|
//
 | 
						|
// Also other comparisons are possible, deviations or also errors can
 | 
						|
// be provoked, which must lead to an appropriate behavior of the
 | 
						|
// function, so that the test is passed.
 | 
						|
//
 | 
						|
// Tests can be run via Zig build system or applied directly to
 | 
						|
// individual modules using "zig test xyz.zig".
 | 
						|
//
 | 
						|
// Both can be used script-driven to execute tests automatically, e.g.
 | 
						|
// after checking into a Git repository. Something we also make extensive
 | 
						|
// use of here at Ziglings.
 | 
						|
//
 | 
						|
const std = @import("std");
 | 
						|
const testing = std.testing;
 | 
						|
 | 
						|
// This is a simple function
 | 
						|
// that builds a sum from the
 | 
						|
// passed parameters and returns.
 | 
						|
fn add(a: f16, b: f16) f16 {
 | 
						|
    return a + b;
 | 
						|
}
 | 
						|
 | 
						|
// The associated test.
 | 
						|
// It always starts with the keyword "test",
 | 
						|
// followed by a description of the tasks
 | 
						|
// of the test. This is followed by the
 | 
						|
// test cases in curly brackets.
 | 
						|
test "add" {
 | 
						|
 | 
						|
    // The first test checks if the sum
 | 
						|
    // of '41' and '1' gives '42', which
 | 
						|
    // is correct.
 | 
						|
    try testing.expect(add(41, 1) == 42);
 | 
						|
 | 
						|
    // Another way to perform this test
 | 
						|
    // is as follows:
 | 
						|
    try testing.expectEqual(42, add(41, 1));
 | 
						|
 | 
						|
    // This time a test with the addition
 | 
						|
    // of a negative number:
 | 
						|
    try testing.expect(add(5, -4) == 1);
 | 
						|
 | 
						|
    // And a floating point operation:
 | 
						|
    try testing.expect(add(1.5, 1.5) == 3);
 | 
						|
}
 | 
						|
 | 
						|
// Another simple function
 | 
						|
// that returns the result
 | 
						|
// of subtracting the two
 | 
						|
// parameters.
 | 
						|
fn sub(a: f16, b: f16) f16 {
 | 
						|
    return a - b;
 | 
						|
}
 | 
						|
 | 
						|
// The corresponding test
 | 
						|
// is not much different
 | 
						|
// from the previous one.
 | 
						|
// Except that it contains
 | 
						|
// an error that you need
 | 
						|
// to correct.
 | 
						|
test "sub" {
 | 
						|
    try testing.expect(sub(10, 5) == 6);
 | 
						|
 | 
						|
    try testing.expect(sub(3, 1.5) == 1.5);
 | 
						|
}
 | 
						|
 | 
						|
// This function divides the
 | 
						|
// numerator by the denominator.
 | 
						|
// Here it is important that the
 | 
						|
// denominator must not be zero.
 | 
						|
// This is checked and if it
 | 
						|
// occurs an error is returned.
 | 
						|
fn divide(a: f16, b: f16) !f16 {
 | 
						|
    if (b == 0) return error.DivisionByZero;
 | 
						|
    return a / b;
 | 
						|
}
 | 
						|
 | 
						|
test "divide" {
 | 
						|
    try testing.expect(divide(2, 2) catch unreachable == 1);
 | 
						|
    try testing.expect(divide(-1, -1) catch unreachable == 1);
 | 
						|
    try testing.expect(divide(10, 2) catch unreachable == 5);
 | 
						|
    try testing.expect(divide(1, 3) catch unreachable == 0.3333333333333333);
 | 
						|
 | 
						|
    // Now we test if the function returns an error
 | 
						|
    // if we pass a zero as denominator.
 | 
						|
    // But which error needs to be tested?
 | 
						|
    try testing.expectError(error.???, divide(15, 0));
 | 
						|
}
 |