-- Leo's gemini proxy

-- Connecting to josipantolis.from.hr:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

Devlog 01: Meson project


Published on: 2021-05-10

This is the first in hopefully many devlogs related to my Starfish project:


⭐️ Starfish project


The goal of this exercise is to set up a meson project with production and test Vala code. All dependencies can be satisfied by installing elementary-sdk package:


sudo apt install elementary-sdk

I'll synthesize 3 how-to posts here:


Compiling Vala applications and libraries with meson

Unit tests with meson

Unit tests in Vala


Code structure:


$ tree
.
├── Calc.vala
├── Main.vala
├── meson.build
└── Test.vala

Calc.vala is where the "core" business logic of the app is implemented. Crucially, code from Calc.vala will be used by both production and test executables.


// Content of Calc.vala file
class Calc {
	public int add (int first, ...) {
		var sum = first;
		var l = va_list ();
		while (true) {
			int next = l.arg ();
			if (next == 0) {
				return sum;
			}
			sum += next;
		}
	}
}

Main.vala defines the entry point for the production executable. Ideally it should have as little code as possible.


// Content of Main.vala file
static int main (string[] args) {
	var calc = new Calc ();
	var sum = calc.add (int.parse (args[1]), int.parse (args[2]));
	stdout.printf (@"$(args[1]) + $(args[2]) = $sum\n;");
	return 0;
}

Test.vala uses GLib's Test namespace to set up unit tests. It contains the entry point for the test executable.


// Content of Test.vala file
void main (string[] args) {
	Test.init (ref args);
	add_calc_tests ();
	Test.run ();
}

private void add_calc_tests () {
	Test.add_func ("/Calc/test_add", () => {
		var given_calc = new Calc ();
		var actual = given_calc.add (13, 29, -1, 6);
		assert_true (actual == 47);
	});
}

Finally, meson.build brings it all together:


# Content of meson.build file
project('calc-app', 'vala', 'c')

# Common dependencies
dependencies = [
	dependency('glib-2.0'),
	dependency('gobject-2.0'),
]

# Common business logic
sources = files('Calc.vala')

# Production executable
executable(
	meson.project_name(),
	sources + files('Main.vala'),
	dependencies: dependencies
)

# Test executable
test_executeable = executable(
	meson.project_name() + '-tests',
	sources + files('Test.vala'),
	dependencies: dependencies
)

test('tests', test_executeable)

Project can be built, tested and ran using:


$ meson builddir
$ cd builddir
$ ninja
$ meson test
$ ./calc-app 1 2

-- Response ended

-- Page fetched on Fri Mar 29 10:10:52 2024