aboutsummaryrefslogtreecommitdiffstats
path: root/tests/CMakeLists.txt
blob: 24da10b5b33fcdf25f4e6dff935de32f221d7197 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# add_qtmaildir_test(<name>) builds tests/test_<name>.cpp and registers it.
#
# resources.qrc is compiled into each test binary for the same reason the app
# compiles it rather than the static library: a qrc inside a .a registers from
# a global initialiser the linker then drops. Library code reads :/fonts/ when
# it builds the placeholder pane, so a test that never links the qrc would
# exercise only the missing-resource fallback and pass against a broken build.
#
# Every test runs under the OFFSCREEN platform, set here rather than left to
# whatever the invoking session happens to use. This is not tidiness: a test
# that renders needs deterministic geometry, and a real windowing system does
# not provide it.
#
# The case that forced it (item 52). theDescriptionSurvivesAModestPopupWidth
# sizes a line edit to 550px and asserts a description survives the popup that
# results. Under Wayland the compositor gave the popup a viewport of 1278x0: the
# zero height made the grab return a null pixmap, which is what failed, but the
# 1278 width is the worse half. Had the grab succeeded, the test would have
# measured a popup more than twice the width it claims to be testing and passed
# while proving nothing about the 550px case.
#
# So the platform is pinned for correctness, not to dodge a red result. `ctest`
# sets no QT_QPA_PLATFORM of its own, so without this the suite's verdict
# depends on how it was invoked: it passed for a developer exporting `offscreen`
# by hand and failed under `ctest` in the same tree, which cost one wrong
# diagnosis before the cause was found.
function(add_qtmaildir_test name)
    add_executable(test_${name} test_${name}.cpp ${CMAKE_SOURCE_DIR}/src/resources.qrc)
    target_link_libraries(test_${name} PRIVATE qtmaildir_lib Qt6::Test)
    add_test(NAME ${name} COMMAND test_${name})
    set_tests_properties(${name} PROPERTIES
        ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
endfunction()

add_qtmaildir_test(keymap)
add_qtmaildir_test(config)
# One test installs the real Italian translation, to prove startup_query still
# resolves when a filter's displayed name is not its English one. It needs the
# compiled .qm, so it depends on the target that builds it.
if(Qt6LinguistTools_FOUND)
    target_compile_definitions(test_config PRIVATE
        TRANSLATIONS_QM="${CMAKE_BINARY_DIR}/src/translations/qtmaildir_it_IT.qm")
    add_dependencies(test_config qtmaildir_translations)
else()
    target_compile_definitions(test_config PRIVATE TRANSLATIONS_QM="")
endif()
add_qtmaildir_test(mimeparser)
target_compile_definitions(test_mimeparser PRIVATE
    FIXTURE_DIR="${CMAKE_CURRENT_SOURCE_DIR}/fixtures")
add_qtmaildir_test(interceptor)
add_qtmaildir_test(htmlbuilder)
add_qtmaildir_test(htmlsanitiser)
add_qtmaildir_test(notmuchworker)
add_qtmaildir_test(tagcolors)
add_qtmaildir_test(cardlayout)
add_qtmaildir_test(pendingchangesdialog)
add_qtmaildir_test(avatar)
add_qtmaildir_test(businesssenders)
add_qtmaildir_test(marks)
add_qtmaildir_test(carddelegate)
add_qtmaildir_test(threadlistmodel)
add_qtmaildir_test(mailsync)
add_qtmaildir_test(syncmonitor)
add_qtmaildir_test(threadcidmap)
add_qtmaildir_test(mainwindow)
add_qtmaildir_test(messageview)
add_qtmaildir_test(querycompleter)
add_qtmaildir_test(tagdialog)
add_qtmaildir_test(tagrules)
add_qtmaildir_test(rulequery)
add_qtmaildir_test(searchterm)
add_qtmaildir_test(signatures)
add_qtmaildir_test(busyindicator)
add_qtmaildir_test(tagstrip)
add_qtmaildir_test(threaddashboard)
add_qtmaildir_test(messagedetailsdialog)
add_qtmaildir_test(markdownrenderer)
add_qtmaildir_test(messagebuilder)
add_qtmaildir_test(maildirname)
add_qtmaildir_test(draftstore)
add_qtmaildir_test(messagesender)
add_qtmaildir_test(composecontext)
add_qtmaildir_test(composewindow)
add_qtmaildir_test(formattoolbar)
add_qtmaildir_test(senddialog)
add_qtmaildir_test(translations)
# Asserts on the tracked .ts rather than the generated .qm: an untranslated
# string is dropped by lrelease, so it is invisible in the .qm and shows up
# only as English in a running Italian UI.
target_compile_definitions(test_translations PRIVATE
    TRANSLATIONS_DIR="${CMAKE_SOURCE_DIR}/translations")

# One test reads composewindow.cpp itself, to assert that m_dirty has a single
# writer. The property is structural, so no runtime probe can see it: a
# mutation restoring a direct assignment in the send path left the suite green.
target_compile_definitions(test_composewindow PRIVATE
    SOURCE_DIR="${CMAKE_SOURCE_DIR}")

# One test RUNS assets/mailsync.sh with stubbed binaries and reads the status
# file it wrote, which is the guard against the bash writer and the C++ reader
# drifting apart. Every other test in that file writes what it believes the
# script emits, and would go on passing after the script changed.
target_compile_definitions(test_mailsync PRIVATE
    SOURCE_DIR="${CMAKE_SOURCE_DIR}")

# The notmuch hooks (assets/hooks/), which are Python rather than C++ and are
# therefore registered directly rather than through add_qtmaildir_test().
#
# They run against the user's REAL mail on every sync, so they belong in the
# suite rather than beside it as scripts someone remembers to run. Two of the
# three need `notmuch` on PATH and build a throwaway database in a temp
# directory; none of them touches the real one.
#
# No QT_QPA_PLATFORM here: nothing Qt is involved.
find_package(Python3 COMPONENTS Interpreter)
if(Python3_Interpreter_FOUND)
    foreach(hook_test mailrules post_new qtmaildirconf)
        add_test(NAME hooks_${hook_test}
                 COMMAND ${Python3_EXECUTABLE}
                         ${CMAKE_SOURCE_DIR}/assets/hooks/test_${hook_test}.py)
    endforeach()

    # The sync script, which lives in assets/ rather than assets/hooks/ and so
    # is registered on its own rather than through the loop above.
    #
    # It belongs in the suite for a stronger reason than the hooks do: the
    # user's ~/bin/mailsync.sh is a SYMLINK to assets/mailsync.sh, so an edit
    # here is live on their next cron tick with no deploy step in between. The
    # test stubs mbsync and notmuch, points HOME at a temp directory and
    # redirects the lock file, so it can neither reach the network nor take the
    # real sync lock, which is the mutex their cron run uses.
    add_test(NAME mailsync_script
             COMMAND ${Python3_EXECUTABLE}
                     ${CMAKE_SOURCE_DIR}/assets/test_mailsync.py)
else()
    message(STATUS "Python3 not found: the notmuch hook tests will not run")
endif()