Skip to content

Commit cec55d9

Browse files
Introduce a first simple test (#2565)
Co-authored-by: Danielle Foré <[email protected]>
1 parent 3f61d3e commit cec55d9

File tree

7 files changed

+246
-2
lines changed

7 files changed

+246
-2
lines changed

.github/workflows/main.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
- synchronize
99

1010
jobs:
11-
build:
11+
build-and-test:
1212

1313
runs-on: ubuntu-22.04
1414

@@ -36,9 +36,12 @@ jobs:
3636
env:
3737
DESTDIR: out
3838
run: |
39-
meson build -Ddocumentation=true
39+
meson build -Ddocumentation=true -Dtests=true
4040
ninja -C build
4141
ninja -C build install
42+
- name: Run Tests
43+
run: |
44+
meson test -v -C build
4245
4346
fedora:
4447
runs-on: ubuntu-latest
@@ -93,3 +96,4 @@ jobs:
9396
io.elementary.vala-lint -d lib
9497
io.elementary.vala-lint -d plugins
9598
io.elementary.vala-lint -d src
99+
io.elementary.vala-lint -d tests

meson.build

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ subdir('plugins/template')
176176
if get_option('documentation')
177177
subdir('docs')
178178
endif
179+
if get_option('tests')
180+
subdir('tests')
181+
endif
179182
subdir('po')
180183

181184
vapigen = find_program('vapigen', required: false)

meson_options.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
option ('documentation', type : 'boolean', value : false)
2+
option ('tests', type : 'boolean', value : false)
23
option ('systemd', type : 'boolean', value : true)
34
option ('systemduserunitdir', type : 'string', value : '')
45
option ('old-icon-groups', type : 'boolean', value : false)

tests/TestCase.vala

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2025 elementary, Inc. (https://elementary.io)
3+
* SPDX-License-Identifier: GPL-3.0-or-later
4+
*/
5+
6+
/**
7+
* A simple test case class. To use it inherit from it and add test methods
8+
* in the constructor using {@link add_test}. Override {@link set_up} and {@link tear_down}
9+
* to provide per-test-method setup and teardown. Then add a `main()` function
10+
* and return the result of {@link run}.
11+
*/
12+
public abstract class Gala.TestCase : Object {
13+
public delegate void TestMethod ();
14+
15+
public string name { get; construct; }
16+
17+
private GLib.TestSuite suite;
18+
19+
construct {
20+
suite = new GLib.TestSuite (name);
21+
}
22+
23+
public int run (string[] args) {
24+
Test.init (ref args);
25+
TestSuite.get_root ().add_suite ((owned) suite);
26+
return Test.run ();
27+
}
28+
29+
protected void add_test (string name, TestMethod test) {
30+
var test_case = new GLib.TestCase (
31+
name,
32+
set_up,
33+
(TestFixtureFunc) test,
34+
tear_down
35+
);
36+
37+
suite.add ((owned) test_case);
38+
}
39+
40+
public virtual void set_up () {
41+
}
42+
43+
public virtual void tear_down () {
44+
}
45+
46+
public void assert_finalize_object<G> (ref G data) {
47+
unowned var weak_pointer = data;
48+
((Object) data).add_weak_pointer (&weak_pointer);
49+
data = null;
50+
assert_null (weak_pointer);
51+
}
52+
}

tests/lib/PropertyTargetTest.vala

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
* Copyright 2025 elementary, Inc. (https://elementary.io)
3+
* SPDX-License-Identifier: GPL-3.0-or-later
4+
*/
5+
6+
public class MockObject : Object {
7+
public int int_value { get; set; }
8+
public double double_value { get; set; }
9+
}
10+
11+
public class Gala.PropertyTargetTest : TestCase {
12+
private MockObject? target;
13+
private PropertyTarget? default_int_prop_target;
14+
15+
public PropertyTargetTest () {
16+
Object (name: "PropertyTarget");
17+
}
18+
19+
construct {
20+
add_test ("simple propagation", test_simple_propagation);
21+
add_test ("double propagation", test_double_propagation);
22+
add_test ("other actions", test_other_actions);
23+
add_test ("finalize object first", test_finalize_object_first);
24+
add_test ("finalize property target first", test_finalize_property_target_first);
25+
}
26+
27+
public override void set_up () {
28+
target = new MockObject ();
29+
default_int_prop_target = new PropertyTarget (
30+
MULTITASKING_VIEW,
31+
target,
32+
"int-value",
33+
typeof (int),
34+
0,
35+
10
36+
);
37+
}
38+
39+
public override void tear_down () {
40+
target = null;
41+
default_int_prop_target = null;
42+
}
43+
44+
private void test_simple_propagation () {
45+
assert_nonnull (&default_int_prop_target);
46+
assert_nonnull (&target);
47+
assert_cmpint (target.int_value, EQ, 0);
48+
49+
default_int_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 0.0);
50+
assert_cmpint (target.int_value, EQ, 0);
51+
52+
default_int_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 0.5);
53+
assert_cmpint (target.int_value, EQ, 5);
54+
55+
default_int_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 1.0);
56+
assert_cmpint (target.int_value, EQ, 10);
57+
58+
default_int_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 0.8);
59+
assert_cmpint (target.int_value, EQ, 8);
60+
61+
default_int_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 0.3);
62+
assert_cmpint (target.int_value, EQ, 3);
63+
64+
default_int_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 0.6);
65+
assert_cmpint (target.int_value, EQ, 6);
66+
67+
assert_finalize_object<MockObject> (ref target);
68+
assert_finalize_object<PropertyTarget> (ref default_int_prop_target);
69+
}
70+
71+
private void test_double_propagation () {
72+
var double_prop_target = new PropertyTarget (
73+
MULTITASKING_VIEW,
74+
target,
75+
"double-value",
76+
typeof (double),
77+
0.0,
78+
2.0
79+
);
80+
81+
assert_nonnull (&double_prop_target);
82+
assert_nonnull (&target);
83+
assert_cmpfloat (target.double_value, EQ, 0.0);
84+
85+
double_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 0.0);
86+
assert_cmpfloat (target.double_value, EQ, 0.0);
87+
88+
double_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 0.5);
89+
assert_cmpfloat (target.double_value, EQ, 1.0);
90+
91+
double_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 1.0);
92+
assert_cmpfloat (target.double_value, EQ, 2.0);
93+
94+
double_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 0.8);
95+
assert_cmpfloat (target.double_value, EQ, 1.6);
96+
97+
double_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 0.3);
98+
assert_cmpfloat (target.double_value, EQ, 0.6);
99+
100+
double_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 0.6);
101+
assert_cmpfloat (target.double_value, EQ, 1.2);
102+
103+
assert_finalize_object<MockObject> (ref target);
104+
assert_finalize_object<PropertyTarget> (ref double_prop_target);
105+
}
106+
107+
private void test_other_actions () {
108+
assert_nonnull (&default_int_prop_target);
109+
110+
assert_nonnull (&target);
111+
assert_cmpint (target.int_value, EQ, 0);
112+
113+
default_int_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 0.0);
114+
assert_cmpint (target.int_value, EQ, 0);
115+
116+
default_int_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 0.5);
117+
assert_cmpint (target.int_value, EQ, 5);
118+
119+
default_int_prop_target.propagate (UPDATE, SWITCH_WORKSPACE, 1.0);
120+
assert_cmpint (target.int_value, EQ, 5);
121+
122+
default_int_prop_target.propagate (UPDATE, CUSTOM, 1.0);
123+
assert_cmpint (target.int_value, EQ, 5);
124+
125+
default_int_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 1.0);
126+
assert_cmpint (target.int_value, EQ, 10);
127+
128+
assert_finalize_object<MockObject> (ref target);
129+
assert_finalize_object<PropertyTarget> (ref default_int_prop_target);
130+
}
131+
132+
private void test_finalize_object_first () {
133+
assert_nonnull (&target);
134+
assert_nonnull (&default_int_prop_target);
135+
136+
// We can finalize the object before the property target because it doesn't hold a strong reference to it
137+
assert_finalize_object<MockObject> (ref target);
138+
139+
default_int_prop_target.propagate (UPDATE, MULTITASKING_VIEW, 0.5);
140+
141+
assert_finalize_object<PropertyTarget> (ref default_int_prop_target);
142+
}
143+
144+
private void test_finalize_property_target_first () {
145+
assert_nonnull (&target);
146+
assert_nonnull (&default_int_prop_target);
147+
148+
// Finalize the property target before the object and make sure we don't have weak references
149+
// to the object (i.e. we don't crash when finalizing the object)
150+
assert_finalize_object<PropertyTarget> (ref default_int_prop_target);
151+
assert_finalize_object<MockObject> (ref target);
152+
}
153+
}
154+
155+
public int main (string[] args) {
156+
return new Gala.PropertyTargetTest ().run (args);
157+
}

tests/lib/meson.build

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
lib_test_sources = files(
2+
meson.project_source_root() / 'lib' / 'Gestures' / 'Gesture.vala',
3+
meson.project_source_root() / 'lib' / 'Gestures' / 'GestureTarget.vala',
4+
meson.project_source_root() / 'lib' / 'Gestures' / 'PropertyTarget.vala',
5+
)
6+
7+
tests = [
8+
'PropertyTargetTest',
9+
]
10+
11+
foreach test : tests
12+
test_executable = executable(
13+
test,
14+
'@[email protected]'.format(test),
15+
common_test_sources,
16+
lib_test_sources,
17+
dependencies: gala_base_dep,
18+
install: false,
19+
)
20+
21+
test(test, test_executable, suite: ['Gala', 'Gala/lib'])
22+
endforeach

tests/meson.build

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
common_test_sources = files(
2+
'TestCase.vala',
3+
)
4+
5+
subdir('lib')

0 commit comments

Comments
 (0)