aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Contributing.md132
-rw-r--r--mesonbuild/build.py6
-rw-r--r--mesonbuild/environment.py8
-rwxr-xr-xrun_project_tests.py294
-rw-r--r--test cases/cmake/16 threads/test.json11
-rw-r--r--test cases/cmake/16 threads/test_matrix.json9
-rw-r--r--test cases/cmake/2 advanced/installed_files.txt4
-rw-r--r--test cases/cmake/2 advanced/test.json8
-rw-r--r--test cases/cmake/3 advanced no dep/installed_files.txt6
-rw-r--r--test cases/cmake/3 advanced no dep/test.json10
-rw-r--r--test cases/common/10 man install/installed_files.txt5
-rw-r--r--test cases/common/10 man install/test.json9
-rw-r--r--test cases/common/105 testframework options/test.json10
-rw-r--r--test cases/common/105 testframework options/test_args.txt4
-rw-r--r--test cases/common/113 custom target capture/installed_files.txt1
-rw-r--r--test cases/common/113 custom target capture/test.json5
-rw-r--r--test cases/common/12 data/installed_files.txt11
-rw-r--r--test cases/common/12 data/test.json15
-rw-r--r--test cases/common/121 shared module/installed_files.txt3
-rw-r--r--test cases/common/121 shared module/test.json7
-rw-r--r--test cases/common/125 object only target/installed_files.txt2
-rw-r--r--test cases/common/125 object only target/test.json6
-rw-r--r--test cases/common/127 custom target directory install/installed_files.txt3
-rw-r--r--test cases/common/127 custom target directory install/test.json7
-rw-r--r--test cases/common/14 configure file/installed_files.txt4
-rw-r--r--test cases/common/14 configure file/test.json8
-rw-r--r--test cases/common/144 custom target multiple outputs/installed_files.txt6
-rw-r--r--test cases/common/144 custom target multiple outputs/test.json10
-rw-r--r--test cases/common/145 special characters/installed_files.txt2
-rw-r--r--test cases/common/145 special characters/test.json6
-rw-r--r--test cases/common/176 initial c_args/test.json8
-rw-r--r--test cases/common/176 initial c_args/test_args.txt4
-rw-r--r--test cases/common/195 install_mode/installed_files.txt10
-rw-r--r--test cases/common/195 install_mode/test.json15
-rw-r--r--test cases/common/206 install name_prefix name_suffix/installed_files.txt12
-rw-r--r--test cases/common/206 install name_prefix name_suffix/test.json16
-rw-r--r--test cases/common/207 kwarg entry/installed_files.txt2
-rw-r--r--test cases/common/207 kwarg entry/test.json6
-rw-r--r--test cases/common/208 custom target build by default/installed_files.txt0
-rw-r--r--test cases/common/208 custom target build by default/test.json5
-rw-r--r--test cases/common/211 cmake module/installed_files.txt2
-rw-r--r--test cases/common/211 cmake module/test.json6
-rw-r--r--test cases/common/212 native file path override/installed_files.txt2
-rw-r--r--test cases/common/212 native file path override/test.json6
-rw-r--r--test cases/common/25 library versions/installed_files.txt3
-rw-r--r--test cases/common/25 library versions/test.json7
-rw-r--r--test cases/common/42 library chain/installed_files.txt2
-rw-r--r--test cases/common/42 library chain/test.json6
-rw-r--r--test cases/common/45 subproject/installed_files.txt3
-rw-r--r--test cases/common/45 subproject/test.json7
-rw-r--r--test cases/common/47 pkgconfig-gen/installed_files.txt5
-rw-r--r--test cases/common/47 pkgconfig-gen/test.json9
-rw-r--r--test cases/common/48 custom install dirs/installed_files.txt12
-rw-r--r--test cases/common/48 custom install dirs/test.json16
-rw-r--r--test cases/common/52 custom target/installed_files.txt1
-rw-r--r--test cases/common/52 custom target/meson.build2
-rw-r--r--test cases/common/52 custom target/test.json5
-rw-r--r--test cases/common/53 custom target chain/installed_files.txt2
-rw-r--r--test cases/common/53 custom target chain/test.json6
-rw-r--r--test cases/common/56 install script/installed_files.txt5
-rw-r--r--test cases/common/56 install script/test.json9
-rw-r--r--test cases/common/6 linkshared/installed_files.txt2
-rw-r--r--test cases/common/6 linkshared/test.json6
-rw-r--r--test cases/common/62 install subdir/installed_files.txt12
-rw-r--r--test cases/common/62 install subdir/test.json16
-rw-r--r--test cases/common/63 foreach/installed_files.txt6
-rw-r--r--test cases/common/63 foreach/test.json10
-rw-r--r--test cases/common/8 install/installed_files.txt3
-rw-r--r--test cases/common/8 install/test.json8
-rw-r--r--test cases/common/9 header install/installed_files.txt4
-rw-r--r--test cases/common/9 header install/test.json8
-rw-r--r--test cases/csharp/1 basic/installed_files.txt2
-rw-r--r--test cases/csharp/1 basic/test.json6
-rw-r--r--test cases/csharp/2 library/installed_files.txt5
-rw-r--r--test cases/csharp/2 library/test.json9
-rw-r--r--test cases/csharp/4 external dep/installed_files.txt1
-rw-r--r--test cases/csharp/4 external dep/test.json5
-rw-r--r--test cases/d/1 simple/installed_files.txt1
-rw-r--r--test cases/d/1 simple/test.json5
-rw-r--r--test cases/d/2 static library/installed_files.txt2
-rw-r--r--test cases/d/2 static library/test.json6
-rw-r--r--test cases/d/3 shared library/installed_files.txt5
-rw-r--r--test cases/d/3 shared library/test.json9
-rw-r--r--test cases/d/4 library versions/installed_files.txt17
-rw-r--r--test cases/d/4 library versions/test.json21
-rw-r--r--test cases/d/5 mixed/installed_files.txt7
-rw-r--r--test cases/d/5 mixed/test.json11
-rw-r--r--test cases/d/6 unittest/installed_files.txt1
-rw-r--r--test cases/d/6 unittest/test.json5
-rw-r--r--test cases/d/7 multilib/installed_files.txt11
-rw-r--r--test cases/d/7 multilib/test.json15
-rw-r--r--test cases/failing/38 libdir must be inside prefix/test.json3
-rw-r--r--test cases/failing/39 prefix absolute/test.json3
-rw-r--r--test cases/failing/42 custom target outputs not matching install_dirs/installed_files.txt6
-rw-r--r--test cases/failing/42 custom target outputs not matching install_dirs/test.json10
-rw-r--r--test cases/frameworks/1 boost/test.json21
-rw-r--r--test cases/frameworks/1 boost/test_matrix.json19
-rw-r--r--test cases/frameworks/10 gtk-doc/installed_files.txt57
-rw-r--r--test cases/frameworks/10 gtk-doc/test.json61
-rw-r--r--test cases/frameworks/11 gir subproject/installed_files.txt8
-rw-r--r--test cases/frameworks/11 gir subproject/test.json12
-rw-r--r--test cases/frameworks/12 multiple gir/installed_files.txt8
-rw-r--r--test cases/frameworks/12 multiple gir/test.json12
-rw-r--r--test cases/frameworks/13 yelp/installed_files.txt18
-rw-r--r--test cases/frameworks/13 yelp/test.json22
-rw-r--r--test cases/frameworks/14 doxygen/installed_files.txt83
-rw-r--r--test cases/frameworks/14 doxygen/test.json87
-rw-r--r--test cases/frameworks/23 hotdoc/installed_files.txt314
-rw-r--r--test cases/frameworks/23 hotdoc/test.json318
-rw-r--r--test cases/frameworks/6 gettext/installed_files.txt10
-rw-r--r--test cases/frameworks/6 gettext/test.json14
-rw-r--r--test cases/frameworks/7 gnome/installed_files.txt24
-rw-r--r--test cases/frameworks/7 gnome/test.json28
-rw-r--r--test cases/java/1 basic/installed_files.txt1
-rw-r--r--test cases/java/1 basic/test.json5
-rw-r--r--test cases/linuxlike/13 cmake dependency/setup_env.json3
-rw-r--r--test cases/linuxlike/13 cmake dependency/test.json5
-rw-r--r--test cases/linuxlike/7 library versions/installed_files.txt10
-rw-r--r--test cases/linuxlike/7 library versions/test.json14
-rw-r--r--test cases/linuxlike/8 subproject library install/installed_files.txt3
-rw-r--r--test cases/linuxlike/8 subproject library install/test.json7
-rw-r--r--test cases/osx/2 library versions/installed_files.txt8
-rw-r--r--test cases/osx/2 library versions/test.json12
-rw-r--r--test cases/osx/4 framework/installed_files.txt2
-rw-r--r--test cases/osx/4 framework/test.json6
-rw-r--r--test cases/osx/5 extra frameworks/installed_files.txt2
-rw-r--r--test cases/osx/5 extra frameworks/test.json6
-rw-r--r--test cases/rust/1 basic/installed_files.txt4
-rw-r--r--test cases/rust/1 basic/test.json8
-rw-r--r--test cases/rust/2 sharedlib/installed_files.txt6
-rw-r--r--test cases/rust/2 sharedlib/test.json10
-rw-r--r--test cases/rust/3 staticlib/installed_files.txt3
-rw-r--r--test cases/rust/3 staticlib/test.json7
-rw-r--r--test cases/rust/4 polyglot/installed_files.txt7
-rw-r--r--test cases/rust/4 polyglot/test.json10
-rw-r--r--test cases/rust/5 polyglot static/installed_files.txt3
-rw-r--r--test cases/rust/5 polyglot static/test.json7
-rw-r--r--test cases/rust/6 named staticlib/installed_files.txt3
-rw-r--r--test cases/rust/6 named staticlib/test.json7
-rw-r--r--test cases/rust/7 private crate collision/installed_files.txt3
-rw-r--r--test cases/rust/7 private crate collision/test.json7
-rw-r--r--test cases/vala/11 generated vapi/installed_files.txt9
-rw-r--r--test cases/vala/11 generated vapi/test.json13
-rw-r--r--test cases/vala/6 static library/installed_files.txt1
-rw-r--r--test cases/vala/6 static library/test.json5
-rw-r--r--test cases/vala/7 shared library/installed_files.txt10
-rw-r--r--test cases/vala/7 shared library/test.json14
-rw-r--r--test cases/vala/8 generated sources/installed_files.txt3
-rw-r--r--test cases/vala/8 generated sources/test.json7
-rw-r--r--test cases/vala/9 gir/installed_files.txt3
-rw-r--r--test cases/vala/9 gir/test.json7
-rw-r--r--test cases/windows/1 basic/installed_files.txt2
-rw-r--r--test cases/windows/1 basic/test.json6
-rw-r--r--test cases/windows/11 exe implib/installed_files.txt8
-rw-r--r--test cases/windows/11 exe implib/test.json12
-rw-r--r--test cases/windows/7 dll versioning/installed_files.txt30
-rw-r--r--test cases/windows/7 dll versioning/test.json34
157 files changed, 1453 insertions, 1043 deletions
diff --git a/docs/markdown/Contributing.md b/docs/markdown/Contributing.md
index c5b8608..26f3512 100644
--- a/docs/markdown/Contributing.md
+++ b/docs/markdown/Contributing.md
@@ -163,28 +163,136 @@ Any tests that require more thorough analysis, such as checking that certain
compiler arguments can be found in the command line or that the generated
pkg-config files actually work should be done with a unit test.
-The following files in the test's source root are consulted, if they exist:
-
-* `installed_files.txt` lists the files which are expected to be installed.
-Various constructs containing `?` are used to indicate platform specific
-filename variations (e.g. `?so` represents the platform appropriate suffix for a
-shared library)
-
-* `setup_env.json` contains a dictionary which specifies additional
-environment variables to be set during the configure step of the test. `@ROOT@`
-is replaced with the absolute path of the source directory.
+Additionally:
* `crossfile.ini` and `nativefile.ini` are passed to the configure step with
`--cross-file` and `--native-file` options, respectively.
-Additionally:
-
* `mlog.cmd_ci_include()` can be called from anywhere inside meson to capture the
contents of an additional file into the CI log on failure.
Projects needed by unit tests are in the `test cases/unit`
subdirectory. They are not run as part of `./run_project_tests.py`.
+#### Configuring project tests
+
+The (optional) `test.json` file, in the root of a test case, is used
+for configuring the test. All of the following root entries in the `test.json`
+are independent of each other and can be combined as needed.
+
+Exanple `test.json`:
+
+```json
+{
+ "env": {
+ "VAR": "VAL"
+ },
+ "installed": [
+ { "type": "exe", "file": "usr/bin/testexe" },
+ { "type": "pdb", "file": "usr/bin/testexe" },
+ ],
+ "matrix": {
+ "options": {
+ "opt1": [
+ { "val": "abc" },
+ { "val": "qwert" },
+ { "val": "bad" }
+ ],
+ "opt2": [
+ { "val": null },
+ { "val": "true" },
+ { "val": "false" },
+ ]
+ },
+ "exclude": [
+ { "opt1": "qwert", "opt2": "false" },
+ { "opt1": "bad" }
+ ]
+ }
+}
+```
+
+##### env
+
+The `env` key contains a dictionary which specifies additional
+environment variables to be set during the configure step of the test. `@ROOT@`
+is replaced with the absolute path of the source directory.
+
+##### installed
+
+The `installed` dict contains a list of dicts, describing which files are expected
+to be installed. Each dict contains the following keys:
+
+- `file`
+- `type`
+- `platform` (optional)
+
+The `file` entry contains the relative path (from the install root) to the
+actually installed file.
+
+The `type` entry specifies how the `file` path should be interpreted based on the
+current platform. The following values are currently supported:
+
+| `type` | Description |
+| :-----------: | -------------------------------------------------------------------------------- |
+| `file` | No postprocessing, just use the provided path |
+| `exe` | For executables. On Windows the `.exe` suffix is added to the path in `file` |
+| `pdb` | For Windows PDB files. PDB entries are ignored on non Windows platforms |
+| `implib` | For Windows import libraries. These entries are ignored on non Windows platforms |
+| `implibempty` | Like `implib`, but no symbols are exported in the library |
+| `expr` | `file` is an expression. This type should be avoided and removed if possible |
+
+Except for the `file` and `expr` types, all paths should be provided *without* a suffix.
+
+If the `platform` key is present, the installed file entry is only considered if
+the platform matches. The following values for `platform` are currently supported:
+
+| `platform` | Description |
+| :--------: | -------------------------------------------------------------------- |
+| `msvc` | Matches when a msvc like compiler is used (`msvc`, `clang-cl`, etc.) |
+| `gcc` | Not `msvc` |
+| `cygwin` | Matches when the platform is cygwin |
+| `!cygwin` | Not `cygwin` |
+
+##### matrix
+
+The `matrix` section can be used to define a test matrix to run project tests
+with different meson options.
+
+In the `options` dict, all possible options and their values are specified. Each
+key in the `options` dict is a meson option. It stores a list of all potential
+values in a dict format, which allows to skip specific values based on the current
+environment.
+
+Each value must contain the `val` key for the value of the option. `null` can be
+used for adding matrix entries without the current option.
+
+Additionally, the `skip_on_env` key can be used to specify a list of environment
+variables. If at least one environment variable in `skip_on_env` is present, all
+matrix entries containing this value are skipped.
+
+Similarly, the `compilers` key can be used to define a set of compilers required
+for this value.
+
+
+Specific option combinations can be excluded with the `exclude` section. It should
+be noted that `exclude` does not require exact matches. Instead, any matrix entry
+containing all option value combinations in `exclude` will be excluded. Thus
+an empty dict (`{}`) to will match **all** elements in the test matrix.
+
+The above example will produce the following matrix entries:
+- `opt1=abc`
+- `opt1=abc opt2=true`
+- `opt1=abc opt2=false`
+- `opt1=qwert`
+- `opt1=qwert opt2=true`
+
+##### do_not_set_opts
+
+Currently supported values are:
+- `prefix`
+- `libdir`
+
### Skipping integration tests
Meson uses several continuous integration testing systems that have slightly
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 0a8ca45..89fd86a 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1263,6 +1263,8 @@ You probably should put it in link_with instead.''')
if dl != linker.language:
stdlib_args += all_compilers[dl].language_stdlib_only_link_flags()
added_languages.add(dl)
+ # Type of var 'linker' is Compiler.
+ # Pretty hard to fix because the return value is passed everywhere
return linker, stdlib_args
m = 'Could not get a dynamic linker for build target {!r}'
@@ -1290,9 +1292,9 @@ You probably should put it in link_with instead.''')
2. If the target contains only objects, process_compilers guesses and
picks the first compiler that smells right.
'''
- linker, _ = self.get_clink_dynamic_linker_and_stdlibs()
+ compiler, _ = self.get_clink_dynamic_linker_and_stdlibs()
# Mixing many languages with MSVC is not supported yet so ignore stdlibs.
- if linker and linker.get_id() in {'msvc', 'clang-cl', 'intel-cl', 'llvm', 'dmd', 'nvcc'}:
+ if compiler and compiler.get_linker_id() in {'link', 'lld-link', 'xilink', 'optlink'}:
return True
return False
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 46bbea0..5e60294 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -338,6 +338,8 @@ def detect_cpu_family(compilers: CompilersDict) -> str:
trial = 'x86_64'
elif trial in {'sun4u', 'sun4v'}:
trial = 'sparc64'
+ elif trial in {'mipsel', 'mips64el'}:
+ trial = trial.rstrip('el')
# On Linux (and maybe others) there can be any mixture of 32/64 bit code in
# the kernel, Python, system, 32-bit chroot on 64-bit host, etc. The only
@@ -369,6 +371,7 @@ def detect_cpu(compilers: CompilersDict):
trial = platform.processor().lower()
else:
trial = platform.machine().lower()
+
if trial in ('amd64', 'x64', 'i86pc'):
trial = 'x86_64'
if trial == 'x86_64':
@@ -384,6 +387,9 @@ def detect_cpu(compilers: CompilersDict):
elif trial == 'e2k':
# Make more precise CPU detection for Elbrus platform.
trial = platform.processor().lower()
+ elif trial.startswith('mips'):
+ trial = trial.rstrip('el')
+
# Add more quirks here as bugs are reported. Keep in sync with
# detect_cpu_family() above.
return trial
@@ -1129,7 +1135,7 @@ class Environment:
cpp_compiler = self.detect_cpp_compiler(for_machine)
cls = CudaCompiler
self.coredata.add_lang_args(cls.language, cls, for_machine, self)
- linker = CudaLinker(compiler, for_machine, 'nvlink', CudaCompiler.LINKER_PREFIX, [], version=CudaLinker.parse_version())
+ linker = CudaLinker(compiler, for_machine, CudaCompiler.LINKER_PREFIX, [], version=CudaLinker.parse_version())
return cls(ccache + compiler, version, for_machine, is_cross, exe_wrap, host_compiler=cpp_compiler, info=info, linker=linker)
raise EnvironmentException('Could not find suitable CUDA compiler: "' + ' '.join(compilers) + '"')
diff --git a/run_project_tests.py b/run_project_tests.py
index 1194abf..86db599 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -24,7 +24,6 @@ import sys
import signal
import shlex
from io import StringIO
-from ast import literal_eval
from enum import Enum
import tempfile
from pathlib import Path, PurePath
@@ -34,7 +33,7 @@ from mesonbuild import compilers
from mesonbuild import mesonlib
from mesonbuild import mlog
from mesonbuild import mtest
-from mesonbuild.mesonlib import MachineChoice, stringlistify, Popen_safe
+from mesonbuild.mesonlib import MachineChoice, Popen_safe
from mesonbuild.coredata import backendlist
import argparse
import json
@@ -90,6 +89,53 @@ class TestResult:
def fail(self, msg):
self.msg = msg
+class InstalledFile:
+ def __init__(self, raw: T.Dict[str, str]):
+ self.path = raw['file']
+ self.typ = raw['type']
+ self.platform = raw.get('platform', None)
+
+ def get_path(self, compiler: str, env: environment.Environment) -> T.Optional[Path]:
+ p = Path(self.path)
+ canonical_compiler = compiler
+ if (compiler in ['clang-cl', 'intel-cl']) or (env.machines.host.is_windows() and compiler == 'pgi'):
+ canonical_compiler = 'msvc'
+
+ # Abort if the platform does not match
+ matches = {
+ 'msvc': canonical_compiler == 'msvc',
+ 'gcc': canonical_compiler != 'msvc',
+ 'cygwin': env.machines.host.is_cygwin(),
+ '!cygwin': not env.machines.host.is_cygwin(),
+ }.get(self.platform or '', True)
+ if not matches:
+ return None
+
+ # Handle the different types
+ if self.typ == 'file':
+ return p
+ elif self.typ == 'exe':
+ if env.machines.host.is_windows() or env.machines.host.is_cygwin():
+ return p.with_suffix('.exe')
+ elif self.typ == 'pdb':
+ return p.with_suffix('.pdb') if canonical_compiler == 'msvc' else None
+ elif self.typ == 'implib' or self.typ == 'implibempty':
+ if env.machines.host.is_windows() and canonical_compiler == 'msvc':
+ # only MSVC doesn't generate empty implibs
+ if self.typ == 'implibempty' and compiler == 'msvc':
+ return None
+ return p.parent / (re.sub(r'^lib', '', p.name) + '.lib')
+ elif env.machines.host.is_windows() or env.machines.host.is_cygwin():
+ return p.with_suffix('.dll.a')
+ else:
+ return None
+ elif self.typ == 'expr':
+ return Path(platform_fix_name(p.as_posix(), canonical_compiler, env))
+ else:
+ raise RuntimeError('Invalid installed file type {}'.format(self.typ))
+
+ return p
+
@functools.total_ordering
class TestDef:
def __init__(self, path: Path, name: T.Optional[str], args: T.List[str], skip: bool = False):
@@ -97,6 +143,9 @@ class TestDef:
self.name = name
self.args = args
self.skip = skip
+ self.env = os.environ.copy()
+ self.installed_files = [] # type: T.List[InstalledFile]
+ self.do_not_set_opts = [] # type: T.List[str]
def __repr__(self) -> str:
return '<{}: {:<48} [{}: {}] -- {}>'.format(type(self).__name__, str(self.path), self.name, self.args, self.skip)
@@ -106,10 +155,12 @@ class TestDef:
return '{} ({})'.format(self.path.as_posix(), self.name)
return self.path.as_posix()
- def __lt__(self, other: T.Any) -> T.Union[bool, type(NotImplemented)]:
+ def __lt__(self, other: T.Any) -> bool:
if isinstance(other, TestDef):
# None is not sortable, so replace it with an empty string
- return (self.path, self.name or '') < (other.path, other.name or '')
+ s_id = int(self.path.name.split(' ')[0])
+ o_id = int(other.path.name.split(' ')[0])
+ return (s_id, self.path, self.name or '') < (o_id, other.path, other.name or '')
return NotImplemented
class AutoDeletedDir:
@@ -156,17 +207,8 @@ def setup_commands(optbackend):
compile_commands, clean_commands, test_commands, install_commands, \
uninstall_commands = get_backend_commands(backend, do_debug)
-def get_relative_files_list_from_dir(fromdir: Path) -> T.List[Path]:
- return [file.relative_to(fromdir) for file in fromdir.rglob('*') if file.is_file()]
-
-def platform_fix_name(fname: str, compiler, env) -> str:
- # canonicalize compiler
- if (compiler in {'clang-cl', 'intel-cl'} or
- (env.machines.host.is_windows() and compiler == 'pgi')):
- canonical_compiler = 'msvc'
- else:
- canonical_compiler = compiler
-
+# TODO try to eliminate or at least reduce this function
+def platform_fix_name(fname: str, canonical_compiler: str, env: environment.EnvironmentException) -> str:
if '?lib' in fname:
if env.machines.host.is_windows() and canonical_compiler == 'msvc':
fname = re.sub(r'lib/\?lib(.*)\.', r'bin/\1.', fname)
@@ -183,31 +225,6 @@ def platform_fix_name(fname: str, compiler, env) -> str:
else:
fname = re.sub(r'\?lib', 'lib', fname)
- if fname.endswith('?exe'):
- fname = fname[:-4]
- if env.machines.host.is_windows() or env.machines.host.is_cygwin():
- return fname + '.exe'
-
- if fname.startswith('?msvc:'):
- fname = fname[6:]
- if canonical_compiler != 'msvc':
- return None
-
- if fname.startswith('?gcc:'):
- fname = fname[5:]
- if canonical_compiler == 'msvc':
- return None
-
- if fname.startswith('?cygwin:'):
- fname = fname[8:]
- if not env.machines.host.is_cygwin():
- return None
-
- if fname.startswith('?!cygwin:'):
- fname = fname[9:]
- if env.machines.host.is_cygwin():
- return None
-
if fname.endswith('?so'):
if env.machines.host.is_windows() and canonical_compiler == 'msvc':
fname = re.sub(r'lib/([^/]*)\?so$', r'bin/\1.dll', fname)
@@ -227,49 +244,28 @@ def platform_fix_name(fname: str, compiler, env) -> str:
else:
return fname[:-3] + '.so'
- if fname.endswith('?implib') or fname.endswith('?implibempty'):
- if env.machines.host.is_windows() and canonical_compiler == 'msvc':
- # only MSVC doesn't generate empty implibs
- if fname.endswith('?implibempty') and compiler == 'msvc':
- return None
- return re.sub(r'/(?:lib|)([^/]*?)\?implib(?:empty|)$', r'/\1.lib', fname)
- elif env.machines.host.is_windows() or env.machines.host.is_cygwin():
- return re.sub(r'\?implib(?:empty|)$', r'.dll.a', fname)
- else:
- return None
-
return fname
-def validate_install(srcdir: str, installdir: Path, compiler, env) -> str:
- # List of installed files
- info_file = Path(srcdir) / 'installed_files.txt'
- installdir = Path(installdir)
- expected = {} # type: T.Dict[Path, bool]
+def validate_install(test: TestDef, installdir: Path, compiler: str, env: environment.Environment) -> str:
+ expected_raw = [x.get_path(compiler, env) for x in test.installed_files]
+ expected = {Path(x): False for x in expected_raw if x}
+ found = [x.relative_to(installdir) for x in installdir.rglob('*') if x.is_file() or x.is_symlink()]
ret_msg = ''
- # Generate list of expected files
- if info_file.is_file():
- with info_file.open() as f:
- for line in f:
- line = platform_fix_name(line.strip(), compiler, env)
- if line:
- expected[Path(line)] = False
- # Check if expected files were found
- for fname in expected:
- file_path = installdir / fname
- if file_path.is_file() or file_path.is_symlink():
- expected[fname] = True
- for (fname, found) in expected.items():
- if not found:
- ret_msg += 'Expected file {} missing.\n'.format(fname)
- # Check if there are any unexpected files
- found = get_relative_files_list_from_dir(installdir)
+ # Mark all found files as found and detect unexpected files
for fname in found:
if fname not in expected:
ret_msg += 'Extra file {} found.\n'.format(fname)
+ continue
+ expected[fname] = True
+ # Check if expected files were found
+ for p, f in expected.items():
+ if not f:
+ ret_msg += 'Expected file {} missing.\n'.format(p)
+ # List dir content on error
if ret_msg != '':
ret_msg += '\nInstall dir contents:\n'
for i in found:
- ret_msg += ' - {}'.format(i)
+ ret_msg += ' - {}\n'.format(i)
return ret_msg
def log_text_file(logfile, testdir, stdo, stde):
@@ -361,83 +357,45 @@ def run_test_inprocess(testdir):
os.chdir(old_cwd)
return max(returncode_test, returncode_benchmark), mystdout.getvalue(), mystderr.getvalue(), test_log
-def parse_test_args(testdir):
- args = []
- try:
- with open(os.path.join(testdir, 'test_args.txt'), 'r') as f:
- content = f.read()
- try:
- args = literal_eval(content)
- except Exception:
- raise Exception('Malformed test_args file.')
- args = stringlistify(args)
- except FileNotFoundError:
- pass
- return args
-
# Build directory name must be the same so Ccache works over
# consecutive invocations.
-def create_deterministic_builddir(src_dir, name):
+def create_deterministic_builddir(test: TestDef) -> str:
import hashlib
- if name:
- src_dir += name
+ src_dir = test.path.as_posix()
+ if test.name:
+ src_dir += test.name
rel_dirname = 'b ' + hashlib.sha256(src_dir.encode(errors='ignore')).hexdigest()[0:10]
os.mkdir(rel_dirname)
abs_pathname = os.path.join(os.getcwd(), rel_dirname)
return abs_pathname
-def run_test(skipped, testdir, name, extra_args, compiler, backend, flags, commands, should_fail):
- if skipped:
+def run_test(test: TestDef, extra_args, compiler, backend, flags, commands, should_fail):
+ if test.skip:
return None
- with AutoDeletedDir(create_deterministic_builddir(testdir, name)) as build_dir:
+ with AutoDeletedDir(create_deterministic_builddir(test)) as build_dir:
with AutoDeletedDir(tempfile.mkdtemp(prefix='i ', dir=os.getcwd())) as install_dir:
try:
- return _run_test(testdir, build_dir, install_dir, extra_args, compiler, backend, flags, commands, should_fail)
+ return _run_test(test, build_dir, install_dir, extra_args, compiler, backend, flags, commands, should_fail)
finally:
mlog.shutdown() # Close the log file because otherwise Windows wets itself.
-def pass_prefix_to_test(dirname):
- if '39 prefix absolute' in dirname:
- return False
- return True
-
-def pass_libdir_to_test(dirname):
- if '8 install' in dirname:
- return False
- if '38 libdir must be inside prefix' in dirname:
- return False
- if '195 install_mode' in dirname:
- return False
- return True
-
-def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backend, flags, commands, should_fail):
+def _run_test(test: TestDef, test_build_dir: str, install_dir: str, extra_args, compiler, backend, flags, commands, should_fail):
compile_commands, clean_commands, install_commands, uninstall_commands = commands
- test_args = parse_test_args(testdir)
gen_start = time.time()
- setup_env = None
# Configure in-process
- if pass_prefix_to_test(testdir):
- gen_args = ['--prefix', 'x:/usr'] if mesonlib.is_windows() else ['--prefix', '/usr']
- else:
- gen_args = []
- if pass_libdir_to_test(testdir):
+ gen_args = [] # type: T.List[str]
+ if 'prefix' not in test.do_not_set_opts:
+ gen_args += ['--prefix', 'x:/usr'] if mesonlib.is_windows() else ['--prefix', '/usr']
+ if 'libdir' not in test.do_not_set_opts:
gen_args += ['--libdir', 'lib']
- gen_args += [testdir, test_build_dir] + flags + test_args + extra_args
- nativefile = os.path.join(testdir, 'nativefile.ini')
- if os.path.exists(nativefile):
- gen_args.extend(['--native-file', nativefile])
- crossfile = os.path.join(testdir, 'crossfile.ini')
- if os.path.exists(crossfile):
- gen_args.extend(['--cross-file', crossfile])
- setup_env_file = os.path.join(testdir, 'setup_env.json')
- if os.path.exists(setup_env_file):
- setup_env = os.environ.copy()
- with open(setup_env_file, 'r') as fp:
- data = json.load(fp)
- for key, val in data.items():
- val = val.replace('@ROOT@', os.path.abspath(testdir))
- setup_env[key] = val
- (returncode, stdo, stde) = run_configure(gen_args, env=setup_env)
+ gen_args += [test.path.as_posix(), test_build_dir] + flags + extra_args
+ nativefile = test.path / 'nativefile.ini'
+ crossfile = test.path / 'crossfile.ini'
+ if nativefile.exists():
+ gen_args.extend(['--native-file', nativefile.as_posix()])
+ if crossfile.exists():
+ gen_args.extend(['--cross-file', crossfile.as_posix()])
+ (returncode, stdo, stde) = run_configure(gen_args, env=test.env)
try:
logfile = Path(test_build_dir, 'meson-logs', 'meson-log.txt')
mesonlog = logfile.open(errors='ignore', encoding='utf-8').read()
@@ -462,7 +420,7 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen
# Touch the meson.build file to force a regenerate so we can test that
# regeneration works before a build is run.
ensure_backend_detects_changes(backend)
- os.utime(os.path.join(testdir, 'meson.build'))
+ os.utime(str(test.path / 'meson.build'))
# Build with subprocess
dir_args = get_backend_args_for_dir(backend, test_build_dir)
build_start = time.time()
@@ -479,7 +437,7 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen
# Touch the meson.build file to force a regenerate so we can test that
# regeneration works after a build is complete.
ensure_backend_detects_changes(backend)
- os.utime(os.path.join(testdir, 'meson.build'))
+ os.utime(str(test.path / 'meson.build'))
test_start = time.time()
# Test in-process
(returncode, tstdo, tstde, test_log) = run_test_inprocess(test_build_dir)
@@ -515,27 +473,54 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen
testresult.add_step(BuildStep.install, '', '')
if not install_commands:
return testresult
- install_msg = validate_install(testdir, install_dir, compiler, builddata.environment)
+ install_msg = validate_install(test, Path(install_dir), compiler, builddata.environment)
if install_msg:
- testresult.fail(install_msg)
+ testresult.fail('\n' + install_msg)
return testresult
return testresult
-def gather_tests(testdir: Path) -> T.Iterator[TestDef]:
- tests = [t.name for t in testdir.glob('*') if t.is_dir()]
+def gather_tests(testdir: Path) -> T.List[TestDef]:
+ tests = [t.name for t in testdir.iterdir() if t.is_dir()]
tests = [t for t in tests if not t.startswith('.')] # Filter non-tests files (dot files, etc)
- tests = [TestDef(testdir / t, None, []) for t in tests]
- all_tests = []
- for t in tests:
- matrix_file = t.path / 'test_matrix.json'
- if not matrix_file.is_file():
+ test_defs = [TestDef(testdir / t, None, []) for t in tests]
+ all_tests = [] # type: T.List[TestDef]
+ for t in test_defs:
+ test_def_file = t.path / 'test.json'
+ if not test_def_file.is_file():
+ all_tests += [t]
+ continue
+
+ test_def = json.loads(test_def_file.read_text())
+
+ # Handle additional environment variables
+ env = {} # type: T.Dict[str, str]
+ if 'env' in test_def:
+ assert isinstance(test_def['env'], dict)
+ env = test_def['env']
+ for key, val in env.items():
+ val = val.replace('@ROOT@', t.path.resolve().as_posix())
+ env[key] = val
+
+ # Handle installed files
+ installed = [] # type: T.List[InstalledFile]
+ if 'installed' in test_def:
+ installed = [InstalledFile(x) for x in test_def['installed']]
+
+ # Handle the do_not_set_opts list
+ do_not_set_opts = test_def.get('do_not_set_opts', []) # type: T.List[str]
+
+ # Skip the matrix code and just update the existing test
+ if 'matrix' not in test_def:
+ t.env.update(env)
+ t.installed_files = installed
+ t.do_not_set_opts = do_not_set_opts
all_tests += [t]
continue
- # Build multiple tests from matrix definition
+ # 'matrix; entry is present, so build multiple tests from matrix definition
opt_list = [] # type: T.List[T.List[T.Tuple[str, bool]]]
- matrix = json.loads(matrix_file.read_text())
+ matrix = test_def['matrix']
assert "options" in matrix
for key, val in matrix["options"].items():
assert isinstance(val, list)
@@ -552,8 +537,8 @@ def gather_tests(testdir: Path) -> T.Iterator[TestDef]:
# Skip the matrix entry if environment variable is present
if 'skip_on_env' in i:
- for env in i['skip_on_env']:
- if env in os.environ:
+ for skip_env_var in i['skip_on_env']:
+ if skip_env_var in os.environ:
skip = True
# Only run the test if all compiler ID's match
@@ -596,7 +581,11 @@ def gather_tests(testdir: Path) -> T.Iterator[TestDef]:
name = ' '.join([x[0] for x in i if x[0] is not None])
opts = ['-D' + x[0] for x in i if x[0] is not None]
skip = any([x[1] for x in i])
- all_tests += [TestDef(t.path, name, opts, skip)]
+ test = TestDef(t.path, name, opts, skip)
+ test.env.update(env)
+ test.installed_files = installed
+ test.do_not_set_opts = do_not_set_opts
+ all_tests += [test]
return sorted(all_tests)
@@ -880,7 +869,8 @@ def _run_tests(all_tests: T.List[T.Tuple[str, T.List[TestDef], bool]],
suite_args = ['--fatal-meson-warnings']
should_fail = name.split('warning-')[1]
- result = executor.submit(run_test, skipped or t.skip, t.path.as_posix(), t.name, extra_args + suite_args + t.args,
+ t.skip = skipped or t.skip
+ result = executor.submit(run_test, t, extra_args + suite_args + t.args,
system_compiler, backend, backend_flags, commands, should_fail)
futures.append((testname, t, result))
for (testname, t, result) in futures:
@@ -1033,11 +1023,11 @@ def detect_system_compiler(options):
for lang in sorted(compilers.all_languages):
try:
comp = env.compiler_from_language(lang, MachineChoice.HOST)
- details = '{} {} [{}]'.format(' '.join(comp.get_exelist()), comp.get_version_string(), comp.get_id())
+ details = '{:<10} {} {}'.format('[' + comp.get_id() + ']', ' '.join(comp.get_exelist()), comp.get_version_string())
compiler_id_map[lang] = comp.get_id()
except mesonlib.MesonException:
comp = None
- details = 'not found'
+ details = '[not found]'
print('%-7s: %s' % (lang, details))
# note C compiler for later use by platform_fix_name()
diff --git a/test cases/cmake/16 threads/test.json b/test cases/cmake/16 threads/test.json
new file mode 100644
index 0000000..db788b1
--- /dev/null
+++ b/test cases/cmake/16 threads/test.json
@@ -0,0 +1,11 @@
+{
+ "matrix": {
+ "options": {
+ "use_pthread": [
+ { "val": "ON" },
+ { "val": "OFF" },
+ { "val": "NOT_SET" }
+ ]
+ }
+ }
+}
diff --git a/test cases/cmake/16 threads/test_matrix.json b/test cases/cmake/16 threads/test_matrix.json
deleted file mode 100644
index 1c2c545..0000000
--- a/test cases/cmake/16 threads/test_matrix.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "options": {
- "use_pthread": [
- { "val": "ON" },
- { "val": "OFF" },
- { "val": "NOT_SET" }
- ]
- }
-}
diff --git a/test cases/cmake/2 advanced/installed_files.txt b/test cases/cmake/2 advanced/installed_files.txt
deleted file mode 100644
index 4965cd1..0000000
--- a/test cases/cmake/2 advanced/installed_files.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-usr/?lib/libcm_cmModLib?so
-?cygwin:usr/lib/libcm_cmModLib?implib
-?!cygwin:usr/bin/libcm_cmModLib?implib
-usr/bin/cm_testEXE?exe
diff --git a/test cases/cmake/2 advanced/test.json b/test cases/cmake/2 advanced/test.json
new file mode 100644
index 0000000..11aad94
--- /dev/null
+++ b/test cases/cmake/2 advanced/test.json
@@ -0,0 +1,8 @@
+{
+ "installed": [
+ {"type": "expr", "file": "usr/?lib/libcm_cmModLib?so"},
+ {"type": "implib", "platform": "cygwin", "file": "usr/lib/libcm_cmModLib"},
+ {"type": "implib", "platform": "!cygwin", "file": "usr/bin/libcm_cmModLib"},
+ {"type": "exe", "file": "usr/bin/cm_testEXE"}
+ ]
+}
diff --git a/test cases/cmake/3 advanced no dep/installed_files.txt b/test cases/cmake/3 advanced no dep/installed_files.txt
deleted file mode 100644
index 453c6c0..0000000
--- a/test cases/cmake/3 advanced no dep/installed_files.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-usr/?lib/libcm_cmModLib?so
-?cygwin:usr/lib/libcm_cmModLib?implib
-?!cygwin:usr/bin/libcm_cmModLib?implib
-?msvc:usr/bin/cm_cmModLib.pdb
-?msvc:usr/bin/cm_testEXE.pdb
-usr/bin/cm_testEXE?exe \ No newline at end of file
diff --git a/test cases/cmake/3 advanced no dep/test.json b/test cases/cmake/3 advanced no dep/test.json
new file mode 100644
index 0000000..3b8b12d
--- /dev/null
+++ b/test cases/cmake/3 advanced no dep/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ {"type": "expr", "file": "usr/?lib/libcm_cmModLib?so"},
+ {"type": "implib", "platform": "cygwin", "file": "usr/lib/libcm_cmModLib"},
+ {"type": "implib", "platform": "!cygwin", "file": "usr/bin/libcm_cmModLib"},
+ {"type": "pdb", "file": "usr/bin/cm_cmModLib"},
+ {"type": "pdb", "file": "usr/bin/cm_testEXE"},
+ {"type": "exe", "file": "usr/bin/cm_testEXE"}
+ ]
+}
diff --git a/test cases/common/10 man install/installed_files.txt b/test cases/common/10 man install/installed_files.txt
deleted file mode 100644
index 5aad8ea..0000000
--- a/test cases/common/10 man install/installed_files.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-usr/share/man/man1/foo.1
-usr/share/man/man2/bar.2
-usr/share/man/man1/vanishing.1
-usr/share/man/man2/vanishing.2
-usr/share/man/man1/baz.1
diff --git a/test cases/common/10 man install/test.json b/test cases/common/10 man install/test.json
new file mode 100644
index 0000000..cdcc81f
--- /dev/null
+++ b/test cases/common/10 man install/test.json
@@ -0,0 +1,9 @@
+{
+ "installed": [
+ { "type": "file", "file": "usr/share/man/man1/foo.1" },
+ { "type": "file", "file": "usr/share/man/man2/bar.2" },
+ { "type": "file", "file": "usr/share/man/man1/vanishing.1" },
+ { "type": "file", "file": "usr/share/man/man2/vanishing.2" },
+ { "type": "file", "file": "usr/share/man/man1/baz.1" }
+ ]
+}
diff --git a/test cases/common/105 testframework options/test.json b/test cases/common/105 testframework options/test.json
new file mode 100644
index 0000000..65bf3c0
--- /dev/null
+++ b/test cases/common/105 testframework options/test.json
@@ -0,0 +1,10 @@
+{
+ "matrix": {
+ "options": {
+ "testoption": [{ "val": "A string with spaces" }],
+ "other_one": [{ "val": "true" }],
+ "combo_opt": [{ "val": "one" }],
+ "werror": [{ "val": "true" }]
+ }
+ }
+}
diff --git a/test cases/common/105 testframework options/test_args.txt b/test cases/common/105 testframework options/test_args.txt
deleted file mode 100644
index a667e3a..0000000
--- a/test cases/common/105 testframework options/test_args.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# This file is not read by meson itself, but by the test framework.
-# It is not possible to pass arguments to meson from a file.
-['--werror', '-D', 'testoption=A string with spaces', '-D', 'other_one=true', \
- '-D', 'combo_opt=one']
diff --git a/test cases/common/113 custom target capture/installed_files.txt b/test cases/common/113 custom target capture/installed_files.txt
deleted file mode 100644
index d90a6b0..0000000
--- a/test cases/common/113 custom target capture/installed_files.txt
+++ /dev/null
@@ -1 +0,0 @@
-usr/subdir/data.dat
diff --git a/test cases/common/113 custom target capture/test.json b/test cases/common/113 custom target capture/test.json
new file mode 100644
index 0000000..ba66b02
--- /dev/null
+++ b/test cases/common/113 custom target capture/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/subdir/data.dat"}
+ ]
+}
diff --git a/test cases/common/12 data/installed_files.txt b/test cases/common/12 data/installed_files.txt
deleted file mode 100644
index 43bb0e5..0000000
--- a/test cases/common/12 data/installed_files.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-usr/share/progname/datafile.dat
-usr/share/progname/fileobject_datafile.dat
-usr/share/progname/vanishing.dat
-usr/share/progname/vanishing2.dat
-usr/share/data install test/renamed file.txt
-usr/share/data install test/somefile.txt
-usr/share/data install test/some/nested/path.txt
-usr/share/renamed/renamed 2.txt
-usr/share/renamed/renamed 3.txt
-etc/etcfile.dat
-usr/bin/runscript.sh
diff --git a/test cases/common/12 data/test.json b/test cases/common/12 data/test.json
new file mode 100644
index 0000000..f392e9a
--- /dev/null
+++ b/test cases/common/12 data/test.json
@@ -0,0 +1,15 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/progname/datafile.dat"},
+ {"type": "file", "file": "usr/share/progname/fileobject_datafile.dat"},
+ {"type": "file", "file": "usr/share/progname/vanishing.dat"},
+ {"type": "file", "file": "usr/share/progname/vanishing2.dat"},
+ {"type": "file", "file": "usr/share/data install test/renamed file.txt"},
+ {"type": "file", "file": "usr/share/data install test/somefile.txt"},
+ {"type": "file", "file": "usr/share/data install test/some/nested/path.txt"},
+ {"type": "file", "file": "usr/share/renamed/renamed 2.txt"},
+ {"type": "file", "file": "usr/share/renamed/renamed 3.txt"},
+ {"type": "file", "file": "etc/etcfile.dat"},
+ {"type": "file", "file": "usr/bin/runscript.sh"}
+ ]
+}
diff --git a/test cases/common/121 shared module/installed_files.txt b/test cases/common/121 shared module/installed_files.txt
deleted file mode 100644
index d46527c..0000000
--- a/test cases/common/121 shared module/installed_files.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/lib/modules/libnosyms?so
-usr/lib/modules/libnosyms?implibempty
-?msvc:usr/lib/modules/nosyms.pdb
diff --git a/test cases/common/121 shared module/test.json b/test cases/common/121 shared module/test.json
new file mode 100644
index 0000000..33bfeff
--- /dev/null
+++ b/test cases/common/121 shared module/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "expr", "file": "usr/lib/modules/libnosyms?so"},
+ {"type": "implibempty", "file": "usr/lib/modules/libnosyms"},
+ {"type": "pdb", "file": "usr/lib/modules/nosyms"}
+ ]
+}
diff --git a/test cases/common/125 object only target/installed_files.txt b/test cases/common/125 object only target/installed_files.txt
deleted file mode 100644
index 5e796b0..0000000
--- a/test cases/common/125 object only target/installed_files.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin/prog?exe
-?msvc:usr/bin/prog.pdb
diff --git a/test cases/common/125 object only target/test.json b/test cases/common/125 object only target/test.json
new file mode 100644
index 0000000..135300d
--- /dev/null
+++ b/test cases/common/125 object only target/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"}
+ ]
+}
diff --git a/test cases/common/127 custom target directory install/installed_files.txt b/test cases/common/127 custom target directory install/installed_files.txt
deleted file mode 100644
index bcf20e0..0000000
--- a/test cases/common/127 custom target directory install/installed_files.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/share/doc/testpkgname/html/a.html
-usr/share/doc/testpkgname/html/b.html
-usr/share/doc/testpkgname/html/c.html
diff --git a/test cases/common/127 custom target directory install/test.json b/test cases/common/127 custom target directory install/test.json
new file mode 100644
index 0000000..c7eebf5
--- /dev/null
+++ b/test cases/common/127 custom target directory install/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/doc/testpkgname/html/a.html"},
+ {"type": "file", "file": "usr/share/doc/testpkgname/html/b.html"},
+ {"type": "file", "file": "usr/share/doc/testpkgname/html/c.html"}
+ ]
+}
diff --git a/test cases/common/14 configure file/installed_files.txt b/test cases/common/14 configure file/installed_files.txt
deleted file mode 100644
index 542516e..0000000
--- a/test cases/common/14 configure file/installed_files.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-usr/share/appdir/config2.h
-usr/share/appdir/config2b.h
-usr/share/appdireh/config2-1.h
-usr/share/appdirok/config2-2.h
diff --git a/test cases/common/14 configure file/test.json b/test cases/common/14 configure file/test.json
new file mode 100644
index 0000000..92f7b18
--- /dev/null
+++ b/test cases/common/14 configure file/test.json
@@ -0,0 +1,8 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/appdir/config2.h"},
+ {"type": "file", "file": "usr/share/appdir/config2b.h"},
+ {"type": "file", "file": "usr/share/appdireh/config2-1.h"},
+ {"type": "file", "file": "usr/share/appdirok/config2-2.h"}
+ ]
+}
diff --git a/test cases/common/144 custom target multiple outputs/installed_files.txt b/test cases/common/144 custom target multiple outputs/installed_files.txt
deleted file mode 100644
index 21e1249..0000000
--- a/test cases/common/144 custom target multiple outputs/installed_files.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-usr/include/diff.h
-usr/include/first.h
-usr/bin/diff.sh
-usr/bin/second.sh
-opt/same.h
-opt/same.sh
diff --git a/test cases/common/144 custom target multiple outputs/test.json b/test cases/common/144 custom target multiple outputs/test.json
new file mode 100644
index 0000000..e59cb9f
--- /dev/null
+++ b/test cases/common/144 custom target multiple outputs/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/include/diff.h"},
+ {"type": "file", "file": "usr/include/first.h"},
+ {"type": "file", "file": "usr/bin/diff.sh"},
+ {"type": "file", "file": "usr/bin/second.sh"},
+ {"type": "file", "file": "opt/same.h"},
+ {"type": "file", "file": "opt/same.sh"}
+ ]
+}
diff --git a/test cases/common/145 special characters/installed_files.txt b/test cases/common/145 special characters/installed_files.txt
deleted file mode 100644
index f677881..0000000
--- a/test cases/common/145 special characters/installed_files.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/share/result
-usr/share/result2
diff --git a/test cases/common/145 special characters/test.json b/test cases/common/145 special characters/test.json
new file mode 100644
index 0000000..9709e5b
--- /dev/null
+++ b/test cases/common/145 special characters/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/result"},
+ {"type": "file", "file": "usr/share/result2"}
+ ]
+}
diff --git a/test cases/common/176 initial c_args/test.json b/test cases/common/176 initial c_args/test.json
new file mode 100644
index 0000000..f9b73a4
--- /dev/null
+++ b/test cases/common/176 initial c_args/test.json
@@ -0,0 +1,8 @@
+{
+ "matrix": {
+ "options": {
+ "c_args": [{ "val": "-funroll-loops" }],
+ "c_link_args": [{ "val": "-Dtest_harmless_but_useless_link_arg" }]
+ }
+ }
+}
diff --git a/test cases/common/176 initial c_args/test_args.txt b/test cases/common/176 initial c_args/test_args.txt
deleted file mode 100644
index 166e481..0000000
--- a/test cases/common/176 initial c_args/test_args.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# This file is not read by meson itself, but by the test framework.
-# It is not possible to pass arguments to meson from a file.
-['-Dc_args=-march=native', '-Dc_args=-funroll-loops',
- '-Dc_link_args=-Dtest_harmless_but_useless_link_arg']
diff --git a/test cases/common/195 install_mode/installed_files.txt b/test cases/common/195 install_mode/installed_files.txt
deleted file mode 100644
index 4bd2211..0000000
--- a/test cases/common/195 install_mode/installed_files.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-usr/bin/runscript.sh
-usr/bin/trivialprog?exe
-?msvc:usr/bin/trivialprog.pdb
-usr/include/config.h
-usr/include/rootdir.h
-usr/libtest/libstat.a
-usr/share/man/man1/foo.1
-usr/share/sub1/second.dat
-usr/share/sub2/stub
-usr/subdir/data.dat
diff --git a/test cases/common/195 install_mode/test.json b/test cases/common/195 install_mode/test.json
new file mode 100644
index 0000000..3614dbc
--- /dev/null
+++ b/test cases/common/195 install_mode/test.json
@@ -0,0 +1,15 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/runscript.sh"},
+ {"type": "exe", "file": "usr/bin/trivialprog"},
+ {"type": "pdb", "file": "usr/bin/trivialprog"},
+ {"type": "file", "file": "usr/include/config.h"},
+ {"type": "file", "file": "usr/include/rootdir.h"},
+ {"type": "file", "file": "usr/libtest/libstat.a"},
+ {"type": "file", "file": "usr/share/man/man1/foo.1"},
+ {"type": "file", "file": "usr/share/sub1/second.dat"},
+ {"type": "file", "file": "usr/share/sub2/stub"},
+ {"type": "file", "file": "usr/subdir/data.dat"}
+ ],
+ "do_not_set_opts": ["libdir"]
+}
diff --git a/test cases/common/206 install name_prefix name_suffix/installed_files.txt b/test cases/common/206 install name_prefix name_suffix/installed_files.txt
deleted file mode 100644
index be61611..0000000
--- a/test cases/common/206 install name_prefix name_suffix/installed_files.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-?msvc:usr/bin/baz.pdb
-?msvc:usr/bin/bowcorge.pdb
-?msvc:usr/bin/foo.pdb
-usr/?lib/bowcorge.stern
-usr/lib/?libbaz.cheese
-usr/lib/bar.a
-usr/lib/bowcorge?implib
-usr/lib/bowgrault.stern
-usr/lib/foo?implib
-usr/lib/foo?so
-usr/lib/libbaz?implib
-usr/lib/libqux.cheese
diff --git a/test cases/common/206 install name_prefix name_suffix/test.json b/test cases/common/206 install name_prefix name_suffix/test.json
new file mode 100644
index 0000000..63032bc
--- /dev/null
+++ b/test cases/common/206 install name_prefix name_suffix/test.json
@@ -0,0 +1,16 @@
+{
+ "installed": [
+ {"type": "pdb", "file": "usr/bin/baz"},
+ {"type": "pdb", "file": "usr/bin/bowcorge"},
+ {"type": "pdb", "file": "usr/bin/foo"},
+ {"type": "expr", "file": "usr/?lib/bowcorge.stern"},
+ {"type": "expr", "file": "usr/lib/?libbaz.cheese"},
+ {"type": "file", "file": "usr/lib/bar.a"},
+ {"type": "implib", "file": "usr/lib/bowcorge"},
+ {"type": "file", "file": "usr/lib/bowgrault.stern"},
+ {"type": "implib", "file": "usr/lib/foo"},
+ {"type": "expr", "file": "usr/lib/foo?so"},
+ {"type": "implib", "file": "usr/lib/libbaz"},
+ {"type": "file", "file": "usr/lib/libqux.cheese"}
+ ]
+}
diff --git a/test cases/common/207 kwarg entry/installed_files.txt b/test cases/common/207 kwarg entry/installed_files.txt
deleted file mode 100644
index 5e796b0..0000000
--- a/test cases/common/207 kwarg entry/installed_files.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin/prog?exe
-?msvc:usr/bin/prog.pdb
diff --git a/test cases/common/207 kwarg entry/test.json b/test cases/common/207 kwarg entry/test.json
new file mode 100644
index 0000000..135300d
--- /dev/null
+++ b/test cases/common/207 kwarg entry/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"}
+ ]
+}
diff --git a/test cases/common/208 custom target build by default/installed_files.txt b/test cases/common/208 custom target build by default/installed_files.txt
deleted file mode 100644
index e69de29..0000000
--- a/test cases/common/208 custom target build by default/installed_files.txt
+++ /dev/null
diff --git a/test cases/common/208 custom target build by default/test.json b/test cases/common/208 custom target build by default/test.json
new file mode 100644
index 0000000..df8bcb9
--- /dev/null
+++ b/test cases/common/208 custom target build by default/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+
+ ]
+}
diff --git a/test cases/common/211 cmake module/installed_files.txt b/test cases/common/211 cmake module/installed_files.txt
deleted file mode 100644
index f8b11f0..0000000
--- a/test cases/common/211 cmake module/installed_files.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/lib/cmake/cmakeModule/cmakeModuleConfig.cmake
-usr/lib/cmake/cmakeModule/cmakeModuleConfigVersion.cmake \ No newline at end of file
diff --git a/test cases/common/211 cmake module/test.json b/test cases/common/211 cmake module/test.json
new file mode 100644
index 0000000..2a5625a
--- /dev/null
+++ b/test cases/common/211 cmake module/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/cmake/cmakeModule/cmakeModuleConfig.cmake"},
+ {"type": "file", "file": "usr/lib/cmake/cmakeModule/cmakeModuleConfigVersion.cmake"}
+ ]
+}
diff --git a/test cases/common/212 native file path override/installed_files.txt b/test cases/common/212 native file path override/installed_files.txt
deleted file mode 100644
index 0044d40..0000000
--- a/test cases/common/212 native file path override/installed_files.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/custom_bindir/main?exe
-?msvc:usr/custom_bindir/main.pdb
diff --git a/test cases/common/212 native file path override/test.json b/test cases/common/212 native file path override/test.json
new file mode 100644
index 0000000..7954c8e
--- /dev/null
+++ b/test cases/common/212 native file path override/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/custom_bindir/main"},
+ {"type": "pdb", "file": "usr/custom_bindir/main"}
+ ]
+}
diff --git a/test cases/common/25 library versions/installed_files.txt b/test cases/common/25 library versions/installed_files.txt
deleted file mode 100644
index 938e063..0000000
--- a/test cases/common/25 library versions/installed_files.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/lib/prefixsomelib.suffix
-usr/lib/prefixsomelib?implib
-?msvc:usr/lib/prefixsomelib.pdb
diff --git a/test cases/common/25 library versions/test.json b/test cases/common/25 library versions/test.json
new file mode 100644
index 0000000..64b7ab0
--- /dev/null
+++ b/test cases/common/25 library versions/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/prefixsomelib.suffix"},
+ {"type": "implib", "file": "usr/lib/prefixsomelib"},
+ {"type": "pdb", "file": "usr/lib/prefixsomelib"}
+ ]
+}
diff --git a/test cases/common/42 library chain/installed_files.txt b/test cases/common/42 library chain/installed_files.txt
deleted file mode 100644
index 5e796b0..0000000
--- a/test cases/common/42 library chain/installed_files.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin/prog?exe
-?msvc:usr/bin/prog.pdb
diff --git a/test cases/common/42 library chain/test.json b/test cases/common/42 library chain/test.json
new file mode 100644
index 0000000..135300d
--- /dev/null
+++ b/test cases/common/42 library chain/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"}
+ ]
+}
diff --git a/test cases/common/45 subproject/installed_files.txt b/test cases/common/45 subproject/installed_files.txt
deleted file mode 100644
index dba3202..0000000
--- a/test cases/common/45 subproject/installed_files.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/bin/user?exe
-?msvc:usr/bin/user.pdb
-usr/share/sublib/sublib.depmf
diff --git a/test cases/common/45 subproject/test.json b/test cases/common/45 subproject/test.json
new file mode 100644
index 0000000..a56106f
--- /dev/null
+++ b/test cases/common/45 subproject/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/user"},
+ {"type": "pdb", "file": "usr/bin/user"},
+ {"type": "file", "file": "usr/share/sublib/sublib.depmf"}
+ ]
+}
diff --git a/test cases/common/47 pkgconfig-gen/installed_files.txt b/test cases/common/47 pkgconfig-gen/installed_files.txt
deleted file mode 100644
index 9e1a40a..0000000
--- a/test cases/common/47 pkgconfig-gen/installed_files.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-usr/include/simple.h
-usr/lib/pkgconfig/simple.pc
-usr/lib/pkgconfig/libfoo.pc
-usr/lib/pkgconfig/libhello.pc
-usr/lib/pkgconfig/libhello_nolib.pc \ No newline at end of file
diff --git a/test cases/common/47 pkgconfig-gen/test.json b/test cases/common/47 pkgconfig-gen/test.json
new file mode 100644
index 0000000..1c6a452
--- /dev/null
+++ b/test cases/common/47 pkgconfig-gen/test.json
@@ -0,0 +1,9 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/include/simple.h"},
+ {"type": "file", "file": "usr/lib/pkgconfig/simple.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/libfoo.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/libhello.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/libhello_nolib.pc"}
+ ]
+}
diff --git a/test cases/common/48 custom install dirs/installed_files.txt b/test cases/common/48 custom install dirs/installed_files.txt
deleted file mode 100644
index 4e17c2d..0000000
--- a/test cases/common/48 custom install dirs/installed_files.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-usr/dib/dab/dub/prog?exe
-?msvc:usr/dib/dab/dub/prog.pdb
-usr/dib/dab/dub2/prog2?exe
-?msvc:usr/dib/dab/dub2/prog2.pdb
-usr/some/dir/sample.h
-usr/some/dir2/sample.h
-usr/woman/prog.1
-usr/woman2/prog.1
-usr/meow/datafile.cat
-usr/meow2/datafile.cat
-usr/woof/subdir/datafile.dog
-usr/woof2/subdir/datafile.dog
diff --git a/test cases/common/48 custom install dirs/test.json b/test cases/common/48 custom install dirs/test.json
new file mode 100644
index 0000000..ac82fdb
--- /dev/null
+++ b/test cases/common/48 custom install dirs/test.json
@@ -0,0 +1,16 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/dib/dab/dub/prog"},
+ {"type": "pdb", "file": "usr/dib/dab/dub/prog"},
+ {"type": "exe", "file": "usr/dib/dab/dub2/prog2"},
+ {"type": "pdb", "file": "usr/dib/dab/dub2/prog2"},
+ {"type": "file", "file": "usr/some/dir/sample.h"},
+ {"type": "file", "file": "usr/some/dir2/sample.h"},
+ {"type": "file", "file": "usr/woman/prog.1"},
+ {"type": "file", "file": "usr/woman2/prog.1"},
+ {"type": "file", "file": "usr/meow/datafile.cat"},
+ {"type": "file", "file": "usr/meow2/datafile.cat"},
+ {"type": "file", "file": "usr/woof/subdir/datafile.dog"},
+ {"type": "file", "file": "usr/woof2/subdir/datafile.dog"}
+ ]
+}
diff --git a/test cases/common/52 custom target/installed_files.txt b/test cases/common/52 custom target/installed_files.txt
deleted file mode 100644
index d90a6b0..0000000
--- a/test cases/common/52 custom target/installed_files.txt
+++ /dev/null
@@ -1 +0,0 @@
-usr/subdir/data.dat
diff --git a/test cases/common/52 custom target/meson.build b/test cases/common/52 custom target/meson.build
index 9c7443c..5c7cfae 100644
--- a/test cases/common/52 custom target/meson.build
+++ b/test cases/common/52 custom target/meson.build
@@ -9,7 +9,7 @@ endif
# Code will not be rebuilt if it changes.
comp = '@0@/@1@'.format(meson.current_source_dir(), 'my_compiler.py')
# Test that files() in command: works. The compiler just discards it.
-useless = files('installed_files.txt')
+useless = files('test.json')
mytarget = custom_target('bindat',
output : 'data.dat',
diff --git a/test cases/common/52 custom target/test.json b/test cases/common/52 custom target/test.json
new file mode 100644
index 0000000..ba66b02
--- /dev/null
+++ b/test cases/common/52 custom target/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/subdir/data.dat"}
+ ]
+}
diff --git a/test cases/common/53 custom target chain/installed_files.txt b/test cases/common/53 custom target chain/installed_files.txt
deleted file mode 100644
index 7feb072..0000000
--- a/test cases/common/53 custom target chain/installed_files.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/subdir/data2.dat
-usr/subdir/data3.dat
diff --git a/test cases/common/53 custom target chain/test.json b/test cases/common/53 custom target chain/test.json
new file mode 100644
index 0000000..d6b0fa9
--- /dev/null
+++ b/test cases/common/53 custom target chain/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/subdir/data2.dat"},
+ {"type": "file", "file": "usr/subdir/data3.dat"}
+ ]
+}
diff --git a/test cases/common/56 install script/installed_files.txt b/test cases/common/56 install script/installed_files.txt
deleted file mode 100644
index 28f9ed0..0000000
--- a/test cases/common/56 install script/installed_files.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-usr/bin/prog?exe
-?msvc:usr/bin/prog.pdb
-usr/diiba/daaba/file.dat
-usr/this/should/also-work.dat
-usr/this/does/something-different.dat.in
diff --git a/test cases/common/56 install script/test.json b/test cases/common/56 install script/test.json
new file mode 100644
index 0000000..d17625f
--- /dev/null
+++ b/test cases/common/56 install script/test.json
@@ -0,0 +1,9 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/diiba/daaba/file.dat"},
+ {"type": "file", "file": "usr/this/should/also-work.dat"},
+ {"type": "file", "file": "usr/this/does/something-different.dat.in"}
+ ]
+}
diff --git a/test cases/common/6 linkshared/installed_files.txt b/test cases/common/6 linkshared/installed_files.txt
deleted file mode 100644
index 5e796b0..0000000
--- a/test cases/common/6 linkshared/installed_files.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin/prog?exe
-?msvc:usr/bin/prog.pdb
diff --git a/test cases/common/6 linkshared/test.json b/test cases/common/6 linkshared/test.json
new file mode 100644
index 0000000..067bca7
--- /dev/null
+++ b/test cases/common/6 linkshared/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ { "type": "exe", "file": "usr/bin/prog" },
+ { "type": "pdb", "file": "usr/bin/prog" }
+ ]
+}
diff --git a/test cases/common/62 install subdir/installed_files.txt b/test cases/common/62 install subdir/installed_files.txt
deleted file mode 100644
index ffcaa69..0000000
--- a/test cases/common/62 install subdir/installed_files.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-usr/share/dircheck/fifth.dat
-usr/share/dircheck/seventh.dat
-usr/share/dircheck/ninth.dat
-usr/share/eighth.dat
-usr/share/fourth.dat
-usr/share/sixth.dat
-usr/share/sub1/data1.dat
-usr/share/sub1/second.dat
-usr/share/sub1/third.dat
-usr/share/sub1/sub2/data2.dat
-usr/share/sub2/one.dat
-usr/share/sub2/dircheck/excluded-three.dat
diff --git a/test cases/common/62 install subdir/test.json b/test cases/common/62 install subdir/test.json
new file mode 100644
index 0000000..88c6f4b
--- /dev/null
+++ b/test cases/common/62 install subdir/test.json
@@ -0,0 +1,16 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/dircheck/fifth.dat"},
+ {"type": "file", "file": "usr/share/dircheck/seventh.dat"},
+ {"type": "file", "file": "usr/share/dircheck/ninth.dat"},
+ {"type": "file", "file": "usr/share/eighth.dat"},
+ {"type": "file", "file": "usr/share/fourth.dat"},
+ {"type": "file", "file": "usr/share/sixth.dat"},
+ {"type": "file", "file": "usr/share/sub1/data1.dat"},
+ {"type": "file", "file": "usr/share/sub1/second.dat"},
+ {"type": "file", "file": "usr/share/sub1/third.dat"},
+ {"type": "file", "file": "usr/share/sub1/sub2/data2.dat"},
+ {"type": "file", "file": "usr/share/sub2/one.dat"},
+ {"type": "file", "file": "usr/share/sub2/dircheck/excluded-three.dat"}
+ ]
+}
diff --git a/test cases/common/63 foreach/installed_files.txt b/test cases/common/63 foreach/installed_files.txt
deleted file mode 100644
index 3376925..0000000
--- a/test cases/common/63 foreach/installed_files.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-usr/bin/prog1?exe
-?msvc:usr/bin/prog1.pdb
-usr/bin/prog2?exe
-?msvc:usr/bin/prog2.pdb
-usr/bin/prog3?exe
-?msvc:usr/bin/prog3.pdb
diff --git a/test cases/common/63 foreach/test.json b/test cases/common/63 foreach/test.json
new file mode 100644
index 0000000..2fc952d
--- /dev/null
+++ b/test cases/common/63 foreach/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog1"},
+ {"type": "pdb", "file": "usr/bin/prog1"},
+ {"type": "exe", "file": "usr/bin/prog2"},
+ {"type": "pdb", "file": "usr/bin/prog2"},
+ {"type": "exe", "file": "usr/bin/prog3"},
+ {"type": "pdb", "file": "usr/bin/prog3"}
+ ]
+}
diff --git a/test cases/common/8 install/installed_files.txt b/test cases/common/8 install/installed_files.txt
deleted file mode 100644
index d3122a7..0000000
--- a/test cases/common/8 install/installed_files.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/bin/prog?exe
-?msvc:usr/bin/prog.pdb
-usr/libtest/libstat.a
diff --git a/test cases/common/8 install/test.json b/test cases/common/8 install/test.json
new file mode 100644
index 0000000..d2b1c63
--- /dev/null
+++ b/test cases/common/8 install/test.json
@@ -0,0 +1,8 @@
+{
+ "installed": [
+ { "type": "exe", "file": "usr/bin/prog" },
+ { "type": "pdb", "file": "usr/bin/prog" },
+ { "type": "file", "file": "usr/libtest/libstat.a" }
+ ],
+ "do_not_set_opts": ["libdir"]
+}
diff --git a/test cases/common/9 header install/installed_files.txt b/test cases/common/9 header install/installed_files.txt
deleted file mode 100644
index 8af6c1f..0000000
--- a/test cases/common/9 header install/installed_files.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-usr/include/rootdir.h
-usr/include/subdir/subdir.h
-usr/include/vanished.h
-usr/include/fileheader.h
diff --git a/test cases/common/9 header install/test.json b/test cases/common/9 header install/test.json
new file mode 100644
index 0000000..eb12cd0
--- /dev/null
+++ b/test cases/common/9 header install/test.json
@@ -0,0 +1,8 @@
+{
+ "installed": [
+ { "type": "file", "file": "usr/include/rootdir.h" },
+ { "type": "file", "file": "usr/include/subdir/subdir.h" },
+ { "type": "file", "file": "usr/include/vanished.h" },
+ { "type": "file", "file": "usr/include/fileheader.h" }
+ ]
+}
diff --git a/test cases/csharp/1 basic/installed_files.txt b/test cases/csharp/1 basic/installed_files.txt
deleted file mode 100644
index 5022d28..0000000
--- a/test cases/csharp/1 basic/installed_files.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin/prog.exe
-?msvc:usr/bin/prog.pdb
diff --git a/test cases/csharp/1 basic/test.json b/test cases/csharp/1 basic/test.json
new file mode 100644
index 0000000..650a6e2
--- /dev/null
+++ b/test cases/csharp/1 basic/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog.exe"},
+ {"type": "pdb", "file": "usr/bin/prog"}
+ ]
+}
diff --git a/test cases/csharp/2 library/installed_files.txt b/test cases/csharp/2 library/installed_files.txt
deleted file mode 100644
index 73e77a2..0000000
--- a/test cases/csharp/2 library/installed_files.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-usr/bin/prog.exe
-?msvc:usr/bin/prog.pdb
-?msvc:usr/bin/helper.dll
-?msvc:usr/bin/helper.pdb
-?gcc:usr/lib/helper.dll
diff --git a/test cases/csharp/2 library/test.json b/test cases/csharp/2 library/test.json
new file mode 100644
index 0000000..0523f45
--- /dev/null
+++ b/test cases/csharp/2 library/test.json
@@ -0,0 +1,9 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog.exe"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/helper.dll"},
+ {"type": "pdb", "file": "usr/bin/helper"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/helper.dll"}
+ ]
+}
diff --git a/test cases/csharp/4 external dep/installed_files.txt b/test cases/csharp/4 external dep/installed_files.txt
deleted file mode 100644
index f64c68c..0000000
--- a/test cases/csharp/4 external dep/installed_files.txt
+++ /dev/null
@@ -1 +0,0 @@
-usr/bin/prog.exe
diff --git a/test cases/csharp/4 external dep/test.json b/test cases/csharp/4 external dep/test.json
new file mode 100644
index 0000000..a94303f
--- /dev/null
+++ b/test cases/csharp/4 external dep/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog.exe"}
+ ]
+}
diff --git a/test cases/d/1 simple/installed_files.txt b/test cases/d/1 simple/installed_files.txt
deleted file mode 100644
index 9374c54..0000000
--- a/test cases/d/1 simple/installed_files.txt
+++ /dev/null
@@ -1 +0,0 @@
-usr/bin/dsimpleapp?exe
diff --git a/test cases/d/1 simple/test.json b/test cases/d/1 simple/test.json
new file mode 100644
index 0000000..7ec2783
--- /dev/null
+++ b/test cases/d/1 simple/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/dsimpleapp"}
+ ]
+}
diff --git a/test cases/d/2 static library/installed_files.txt b/test cases/d/2 static library/installed_files.txt
deleted file mode 100644
index 0f2bab4..0000000
--- a/test cases/d/2 static library/installed_files.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin/app_s?exe
-usr/lib/libstuff.a
diff --git a/test cases/d/2 static library/test.json b/test cases/d/2 static library/test.json
new file mode 100644
index 0000000..50d5cdf
--- /dev/null
+++ b/test cases/d/2 static library/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/app_s"},
+ {"type": "file", "file": "usr/lib/libstuff.a"}
+ ]
+}
diff --git a/test cases/d/3 shared library/installed_files.txt b/test cases/d/3 shared library/installed_files.txt
deleted file mode 100644
index 4e2c591..0000000
--- a/test cases/d/3 shared library/installed_files.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-usr/bin/app_d?exe
-?msvc:usr/bin/stuff.dll
-?msvc:usr/lib/stuff.lib
-?gcc:usr/lib/libstuff.so
-usr/lib/pkgconfig/test.pc
diff --git a/test cases/d/3 shared library/test.json b/test cases/d/3 shared library/test.json
new file mode 100644
index 0000000..66c546b
--- /dev/null
+++ b/test cases/d/3 shared library/test.json
@@ -0,0 +1,9 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/app_d"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/stuff.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/stuff.lib"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libstuff.so"},
+ {"type": "file", "file": "usr/lib/pkgconfig/test.pc"}
+ ]
+}
diff --git a/test cases/d/4 library versions/installed_files.txt b/test cases/d/4 library versions/installed_files.txt
deleted file mode 100644
index 2cf8d4b..0000000
--- a/test cases/d/4 library versions/installed_files.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-?gcc:usr/lib/libsome.so
-?gcc:usr/lib/libsome.so.0
-?gcc:usr/lib/libsome.so.1.2.3
-?gcc:usr/lib/libnoversion.so
-?gcc:usr/lib/libonlyversion.so
-?gcc:usr/lib/libonlyversion.so.1
-?gcc:usr/lib/libonlyversion.so.1.4.5
-?gcc:usr/lib/libonlysoversion.so
-?gcc:usr/lib/libonlysoversion.so.5
-?msvc:usr/bin/noversion.dll
-?msvc:usr/bin/onlysoversion-5.dll
-?msvc:usr/bin/onlyversion-1.dll
-?msvc:usr/bin/some-0.dll
-?msvc:usr/lib/noversion.lib
-?msvc:usr/lib/onlysoversion.lib
-?msvc:usr/lib/onlyversion.lib
-?msvc:usr/lib/some.lib
diff --git a/test cases/d/4 library versions/test.json b/test cases/d/4 library versions/test.json
new file mode 100644
index 0000000..2a3433e
--- /dev/null
+++ b/test cases/d/4 library versions/test.json
@@ -0,0 +1,21 @@
+{
+ "installed": [
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libsome.so"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libsome.so.0"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libsome.so.1.2.3"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libnoversion.so"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libonlyversion.so"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libonlyversion.so.1"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libonlyversion.so.1.4.5"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libonlysoversion.so"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libonlysoversion.so.5"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/noversion.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/onlysoversion-5.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/onlyversion-1.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/some-0.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/noversion.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/onlysoversion.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/onlyversion.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/some.lib"}
+ ]
+}
diff --git a/test cases/d/5 mixed/installed_files.txt b/test cases/d/5 mixed/installed_files.txt
deleted file mode 100644
index 46b7721..0000000
--- a/test cases/d/5 mixed/installed_files.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-usr/bin/appdc_d?exe
-usr/bin/appdc_s?exe
-usr/lib/libstuff.a
-?gcc:usr/lib/libstuff.so
-?msvc:usr/bin/stuff.dll
-?msvc:usr/bin/stuff.pdb
-?msvc:usr/lib/stuff.lib
diff --git a/test cases/d/5 mixed/test.json b/test cases/d/5 mixed/test.json
new file mode 100644
index 0000000..a63a19b
--- /dev/null
+++ b/test cases/d/5 mixed/test.json
@@ -0,0 +1,11 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/appdc_d"},
+ {"type": "exe", "file": "usr/bin/appdc_s"},
+ {"type": "file", "file": "usr/lib/libstuff.a"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libstuff.so"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/stuff.dll"},
+ {"type": "pdb", "file": "usr/bin/stuff"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/stuff.lib"}
+ ]
+}
diff --git a/test cases/d/6 unittest/installed_files.txt b/test cases/d/6 unittest/installed_files.txt
deleted file mode 100644
index e718389..0000000
--- a/test cases/d/6 unittest/installed_files.txt
+++ /dev/null
@@ -1 +0,0 @@
-usr/bin/dapp?exe
diff --git a/test cases/d/6 unittest/test.json b/test cases/d/6 unittest/test.json
new file mode 100644
index 0000000..433e4b0
--- /dev/null
+++ b/test cases/d/6 unittest/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/dapp"}
+ ]
+}
diff --git a/test cases/d/7 multilib/installed_files.txt b/test cases/d/7 multilib/installed_files.txt
deleted file mode 100644
index 473479f..0000000
--- a/test cases/d/7 multilib/installed_files.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-usr/bin/app_d?exe
-?gcc:usr/lib/libsay1.so
-?gcc:usr/lib/libsay1.so.0
-?gcc:usr/lib/libsay1.so.1.2.3
-?gcc:usr/lib/libsay2.so
-?gcc:usr/lib/libsay2.so.1
-?gcc:usr/lib/libsay2.so.1.2.4
-?msvc:usr/bin/say1-0.dll
-?msvc:usr/bin/say2-1.dll
-?msvc:usr/lib/say1.lib
-?msvc:usr/lib/say2.lib
diff --git a/test cases/d/7 multilib/test.json b/test cases/d/7 multilib/test.json
new file mode 100644
index 0000000..408c4f2
--- /dev/null
+++ b/test cases/d/7 multilib/test.json
@@ -0,0 +1,15 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/app_d"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libsay1.so"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libsay1.so.0"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libsay1.so.1.2.3"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libsay2.so"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libsay2.so.1"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libsay2.so.1.2.4"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/say1-0.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/say2-1.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/say1.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/say2.lib"}
+ ]
+}
diff --git a/test cases/failing/38 libdir must be inside prefix/test.json b/test cases/failing/38 libdir must be inside prefix/test.json
new file mode 100644
index 0000000..1cd893c
--- /dev/null
+++ b/test cases/failing/38 libdir must be inside prefix/test.json
@@ -0,0 +1,3 @@
+{
+ "do_not_set_opts": ["libdir"]
+}
diff --git a/test cases/failing/39 prefix absolute/test.json b/test cases/failing/39 prefix absolute/test.json
new file mode 100644
index 0000000..4e0f6cd
--- /dev/null
+++ b/test cases/failing/39 prefix absolute/test.json
@@ -0,0 +1,3 @@
+{
+ "do_not_set_opts": ["prefix"]
+}
diff --git a/test cases/failing/42 custom target outputs not matching install_dirs/installed_files.txt b/test cases/failing/42 custom target outputs not matching install_dirs/installed_files.txt
deleted file mode 100644
index 21e1249..0000000
--- a/test cases/failing/42 custom target outputs not matching install_dirs/installed_files.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-usr/include/diff.h
-usr/include/first.h
-usr/bin/diff.sh
-usr/bin/second.sh
-opt/same.h
-opt/same.sh
diff --git a/test cases/failing/42 custom target outputs not matching install_dirs/test.json b/test cases/failing/42 custom target outputs not matching install_dirs/test.json
new file mode 100644
index 0000000..e59cb9f
--- /dev/null
+++ b/test cases/failing/42 custom target outputs not matching install_dirs/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/include/diff.h"},
+ {"type": "file", "file": "usr/include/first.h"},
+ {"type": "file", "file": "usr/bin/diff.sh"},
+ {"type": "file", "file": "usr/bin/second.sh"},
+ {"type": "file", "file": "opt/same.h"},
+ {"type": "file", "file": "opt/same.sh"}
+ ]
+}
diff --git a/test cases/frameworks/1 boost/test.json b/test cases/frameworks/1 boost/test.json
new file mode 100644
index 0000000..f4412d2
--- /dev/null
+++ b/test cases/frameworks/1 boost/test.json
@@ -0,0 +1,21 @@
+{
+ "matrix": {
+ "options": {
+ "static": [
+ { "val": "true", "skip_on_env": [ "SKIP_STATIC_BOOST" ] },
+ { "val": "false" }
+ ],
+ "b_vscrt": [
+ { "val": null },
+ { "val": "md", "compilers": { "cpp": [ "msvc" ] } },
+ { "val": "mdd", "compilers": { "cpp": [ "msvc" ] } },
+ { "val": "mt", "compilers": { "cpp": [ "msvc" ] } },
+ { "val": "mtd", "compilers": { "cpp": [ "msvc" ] } }
+ ]
+ },
+ "exclude": [
+ { "static": "false", "b_vscrt": "mt" },
+ { "static": "false", "b_vscrt": "mtd" }
+ ]
+ }
+}
diff --git a/test cases/frameworks/1 boost/test_matrix.json b/test cases/frameworks/1 boost/test_matrix.json
deleted file mode 100644
index 730610e..0000000
--- a/test cases/frameworks/1 boost/test_matrix.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "options": {
- "static": [
- { "val": "true", "skip_on_env": [ "SKIP_STATIC_BOOST" ] },
- { "val": "false" }
- ],
- "b_vscrt": [
- { "val": null },
- { "val": "md", "compilers": { "cpp": [ "msvc" ] } },
- { "val": "mdd", "compilers": { "cpp": [ "msvc" ] } },
- { "val": "mt", "compilers": { "cpp": [ "msvc" ] } },
- { "val": "mtd", "compilers": { "cpp": [ "msvc" ] } }
- ]
- },
- "exclude": [
- { "static": "false", "b_vscrt": "mt" },
- { "static": "false", "b_vscrt": "mtd" }
- ]
-}
diff --git a/test cases/frameworks/10 gtk-doc/installed_files.txt b/test cases/frameworks/10 gtk-doc/installed_files.txt
deleted file mode 100644
index 952a724..0000000
--- a/test cases/frameworks/10 gtk-doc/installed_files.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-usr/include/foo-version.h
-usr/share/gtk-doc/html/foobar/BAR.html
-usr/share/gtk-doc/html/foobar/foobar.devhelp2
-usr/share/gtk-doc/html/foobar/foobar.html
-usr/share/gtk-doc/html/foobar/foobar-foo.html
-usr/share/gtk-doc/html/foobar/foobar-foo-version.html
-usr/share/gtk-doc/html/foobar/home.png
-usr/share/gtk-doc/html/foobar/index.html
-usr/share/gtk-doc/html/foobar/left.png
-usr/share/gtk-doc/html/foobar/left-insensitive.png
-usr/share/gtk-doc/html/foobar/right.png
-usr/share/gtk-doc/html/foobar/right-insensitive.png
-usr/share/gtk-doc/html/foobar/style.css
-usr/share/gtk-doc/html/foobar/up.png
-usr/share/gtk-doc/html/foobar/up-insensitive.png
-usr/share/gtk-doc/html/foobar2/BAR.html
-usr/share/gtk-doc/html/foobar2/foobar2.devhelp2
-usr/share/gtk-doc/html/foobar2/foobar.html
-usr/share/gtk-doc/html/foobar2/foobar2-foo.html
-usr/share/gtk-doc/html/foobar2/foobar2-foo-version.html
-usr/share/gtk-doc/html/foobar2/home.png
-usr/share/gtk-doc/html/foobar2/index.html
-usr/share/gtk-doc/html/foobar2/left.png
-usr/share/gtk-doc/html/foobar2/left-insensitive.png
-usr/share/gtk-doc/html/foobar2/right.png
-usr/share/gtk-doc/html/foobar2/right-insensitive.png
-usr/share/gtk-doc/html/foobar2/style.css
-usr/share/gtk-doc/html/foobar2/up.png
-usr/share/gtk-doc/html/foobar2/up-insensitive.png
-usr/share/gtk-doc/html/foobar-3.0/BAR.html
-usr/share/gtk-doc/html/foobar-3.0/foobar-3.0.devhelp2
-usr/share/gtk-doc/html/foobar-3.0/foobar.html
-usr/share/gtk-doc/html/foobar-3.0/foobar-foo.html
-usr/share/gtk-doc/html/foobar-3.0/foobar-foo-version.html
-usr/share/gtk-doc/html/foobar-3.0/home.png
-usr/share/gtk-doc/html/foobar-3.0/index.html
-usr/share/gtk-doc/html/foobar-3.0/left.png
-usr/share/gtk-doc/html/foobar-3.0/left-insensitive.png
-usr/share/gtk-doc/html/foobar-3.0/right.png
-usr/share/gtk-doc/html/foobar-3.0/right-insensitive.png
-usr/share/gtk-doc/html/foobar-3.0/style.css
-usr/share/gtk-doc/html/foobar-3.0/up.png
-usr/share/gtk-doc/html/foobar-3.0/up-insensitive.png
-usr/share/gtk-doc/html/foobar3/BAR.html
-usr/share/gtk-doc/html/foobar3/foobar2-3.0.devhelp2
-usr/share/gtk-doc/html/foobar3/foobar.html
-usr/share/gtk-doc/html/foobar3/foobar2-foo.html
-usr/share/gtk-doc/html/foobar3/foobar2-foo-version.html
-usr/share/gtk-doc/html/foobar3/home.png
-usr/share/gtk-doc/html/foobar3/index.html
-usr/share/gtk-doc/html/foobar3/left.png
-usr/share/gtk-doc/html/foobar3/left-insensitive.png
-usr/share/gtk-doc/html/foobar3/right.png
-usr/share/gtk-doc/html/foobar3/right-insensitive.png
-usr/share/gtk-doc/html/foobar3/style.css
-usr/share/gtk-doc/html/foobar3/up.png
-usr/share/gtk-doc/html/foobar3/up-insensitive.png
diff --git a/test cases/frameworks/10 gtk-doc/test.json b/test cases/frameworks/10 gtk-doc/test.json
new file mode 100644
index 0000000..c44126c
--- /dev/null
+++ b/test cases/frameworks/10 gtk-doc/test.json
@@ -0,0 +1,61 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/include/foo-version.h"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/BAR.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/foobar.devhelp2"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/foobar.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/foobar-foo.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/foobar-foo-version.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/home.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/index.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/left.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/left-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/right.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/right-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/style.css"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/up.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/up-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/BAR.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/foobar2.devhelp2"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/foobar.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/foobar2-foo.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/foobar2-foo-version.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/home.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/index.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/left.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/left-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/right.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/right-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/style.css"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/up.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar2/up-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/BAR.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/foobar-3.0.devhelp2"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/foobar.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/foobar-foo.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/foobar-foo-version.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/home.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/index.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/left.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/left-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/right.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/right-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/style.css"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/up.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar-3.0/up-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/BAR.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/foobar2-3.0.devhelp2"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/foobar.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/foobar2-foo.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/foobar2-foo-version.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/home.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/index.html"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/left.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/left-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/right.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/right-insensitive.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/style.css"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/up.png"},
+ {"type": "file", "file": "usr/share/gtk-doc/html/foobar3/up-insensitive.png"}
+ ]
+}
diff --git a/test cases/frameworks/11 gir subproject/installed_files.txt b/test cases/frameworks/11 gir subproject/installed_files.txt
deleted file mode 100644
index 6f11f54..0000000
--- a/test cases/frameworks/11 gir subproject/installed_files.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-usr/lib/girepository-1.0/Meson-1.0.typelib
-usr/lib/girepository-1.0/MesonSub-1.0.typelib
-usr/share/gir-1.0/Meson-1.0.gir
-usr/share/gir-1.0/MesonSub-1.0.gir
-usr/lib/?libgirsubproject.so
-?cygwin:usr/lib/libgirlib.dll.a
-usr/lib/?libgirlib.so
-?cygwin:usr/lib/libgirsubproject.dll.a
diff --git a/test cases/frameworks/11 gir subproject/test.json b/test cases/frameworks/11 gir subproject/test.json
new file mode 100644
index 0000000..e94152e
--- /dev/null
+++ b/test cases/frameworks/11 gir subproject/test.json
@@ -0,0 +1,12 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/girepository-1.0/Meson-1.0.typelib"},
+ {"type": "file", "file": "usr/lib/girepository-1.0/MesonSub-1.0.typelib"},
+ {"type": "file", "file": "usr/share/gir-1.0/Meson-1.0.gir"},
+ {"type": "file", "file": "usr/share/gir-1.0/MesonSub-1.0.gir"},
+ {"type": "expr", "file": "usr/lib/?libgirsubproject.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libgirlib.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libgirlib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libgirsubproject.dll.a"}
+ ]
+}
diff --git a/test cases/frameworks/12 multiple gir/installed_files.txt b/test cases/frameworks/12 multiple gir/installed_files.txt
deleted file mode 100644
index 3f9a8f2..0000000
--- a/test cases/frameworks/12 multiple gir/installed_files.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-usr/lib/girepository-1.0/Meson-1.0.typelib
-usr/lib/girepository-1.0/MesonSub-1.0.typelib
-usr/lib/?libgirlib.so
-?cygwin:usr/lib/libgirlib.dll.a
-usr/lib/?libgirsubproject.so
-?cygwin:usr/lib/libgirsubproject.dll.a
-usr/share/gir-1.0/Meson-1.0.gir
-usr/share/gir-1.0/MesonSub-1.0.gir
diff --git a/test cases/frameworks/12 multiple gir/test.json b/test cases/frameworks/12 multiple gir/test.json
new file mode 100644
index 0000000..4e3624c
--- /dev/null
+++ b/test cases/frameworks/12 multiple gir/test.json
@@ -0,0 +1,12 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/girepository-1.0/Meson-1.0.typelib"},
+ {"type": "file", "file": "usr/lib/girepository-1.0/MesonSub-1.0.typelib"},
+ {"type": "expr", "file": "usr/lib/?libgirlib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libgirlib.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libgirsubproject.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libgirsubproject.dll.a"},
+ {"type": "file", "file": "usr/share/gir-1.0/Meson-1.0.gir"},
+ {"type": "file", "file": "usr/share/gir-1.0/MesonSub-1.0.gir"}
+ ]
+}
diff --git a/test cases/frameworks/13 yelp/installed_files.txt b/test cases/frameworks/13 yelp/installed_files.txt
deleted file mode 100644
index 1f6522f..0000000
--- a/test cases/frameworks/13 yelp/installed_files.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-usr/share/help/C/meson/index.page
-usr/share/help/C/meson/media/test.txt
-usr/share/help/es/meson/index.page
-usr/share/help/es/meson/media/test.txt
-usr/share/help/de/meson/index.page
-usr/share/help/de/meson/media/test.txt
-usr/share/help/C/meson-symlink/index.page
-usr/share/help/C/meson-symlink/media/test.txt
-usr/share/help/es/meson-symlink/media/test.txt
-usr/share/help/es/meson-symlink/index.page
-usr/share/help/de/meson-symlink/index.page
-usr/share/help/de/meson-symlink/media/test.txt
-usr/share/help/C/meson-linguas/index.page
-usr/share/help/C/meson-linguas/media/test.txt
-usr/share/help/es/meson-linguas/media/test.txt
-usr/share/help/es/meson-linguas/index.page
-usr/share/help/de/meson-linguas/index.page
-usr/share/help/de/meson-linguas/media/test.txt
diff --git a/test cases/frameworks/13 yelp/test.json b/test cases/frameworks/13 yelp/test.json
new file mode 100644
index 0000000..070fb32
--- /dev/null
+++ b/test cases/frameworks/13 yelp/test.json
@@ -0,0 +1,22 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/help/C/meson/index.page"},
+ {"type": "file", "file": "usr/share/help/C/meson/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/es/meson/index.page"},
+ {"type": "file", "file": "usr/share/help/es/meson/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/de/meson/index.page"},
+ {"type": "file", "file": "usr/share/help/de/meson/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/C/meson-symlink/index.page"},
+ {"type": "file", "file": "usr/share/help/C/meson-symlink/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/es/meson-symlink/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/es/meson-symlink/index.page"},
+ {"type": "file", "file": "usr/share/help/de/meson-symlink/index.page"},
+ {"type": "file", "file": "usr/share/help/de/meson-symlink/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/C/meson-linguas/index.page"},
+ {"type": "file", "file": "usr/share/help/C/meson-linguas/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/es/meson-linguas/media/test.txt"},
+ {"type": "file", "file": "usr/share/help/es/meson-linguas/index.page"},
+ {"type": "file", "file": "usr/share/help/de/meson-linguas/index.page"},
+ {"type": "file", "file": "usr/share/help/de/meson-linguas/media/test.txt"}
+ ]
+}
diff --git a/test cases/frameworks/14 doxygen/installed_files.txt b/test cases/frameworks/14 doxygen/installed_files.txt
deleted file mode 100644
index e4f70e3..0000000
--- a/test cases/frameworks/14 doxygen/installed_files.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-usr/share/doc/spede/html/annotated.html
-usr/share/doc/spede/html/bc_s.png
-usr/share/doc/spede/html/bdwn.png
-usr/share/doc/spede/html/classComedy_1_1Comedian.html
-usr/share/doc/spede/html/classComedy_1_1Comedian.png
-usr/share/doc/spede/html/classComedy_1_1Comedian-members.html
-usr/share/doc/spede/html/classComedy_1_1Spede.html
-usr/share/doc/spede/html/classComedy_1_1Spede.png
-usr/share/doc/spede/html/classComedy_1_1Spede-members.html
-usr/share/doc/spede/html/classes.html
-usr/share/doc/spede/html/closed.png
-usr/share/doc/spede/html/comedian_8h_source.html
-usr/share/doc/spede/html/dir_7bdce917e28dfbd493cadd1d2e5c7d80.html
-usr/share/doc/spede/html/dir_44a4667d36a4476878de085754f6d2b9.html
-usr/share/doc/spede/html/dir_68b523c5b3a2dcea45d5ce70397fb722.html
-usr/share/doc/spede/html/dir_a7e6472d2301212032fd74682f8217f3.html
-usr/share/doc/spede/html/dir_ee191f21c02d247cc959e80c1a3acadf.html
-usr/share/doc/spede/html/doc.png
-usr/share/doc/spede/html/doxygen.css
-usr/share/doc/spede/html/doxygen.png
-usr/share/doc/spede/html/dynsections.js
-usr/share/doc/spede/html/files.html
-usr/share/doc/spede/html/folderclosed.png
-usr/share/doc/spede/html/folderopen.png
-usr/share/doc/spede/html/functions.html
-usr/share/doc/spede/html/functions_func.html
-usr/share/doc/spede/html/hierarchy.html
-usr/share/doc/spede/html/index.html
-usr/share/doc/spede/html/jquery.js
-usr/share/doc/spede/html/menu.js
-usr/share/doc/spede/html/menudata.js
-usr/share/doc/spede/html/namespaceComedy.html
-usr/share/doc/spede/html/namespacemembers.html
-usr/share/doc/spede/html/namespacemembers_func.html
-usr/share/doc/spede/html/namespaces.html
-usr/share/doc/spede/html/nav_f.png
-usr/share/doc/spede/html/nav_g.png
-usr/share/doc/spede/html/nav_h.png
-usr/share/doc/spede/html/open.png
-usr/share/doc/spede/html/search/all_0.html
-usr/share/doc/spede/html/search/all_0.js
-usr/share/doc/spede/html/search/all_1.html
-usr/share/doc/spede/html/search/all_1.js
-usr/share/doc/spede/html/search/all_2.html
-usr/share/doc/spede/html/search/all_2.js
-usr/share/doc/spede/html/search/all_3.html
-usr/share/doc/spede/html/search/all_3.js
-usr/share/doc/spede/html/search/classes_0.html
-usr/share/doc/spede/html/search/classes_0.js
-usr/share/doc/spede/html/search/classes_1.html
-usr/share/doc/spede/html/search/classes_1.js
-usr/share/doc/spede/html/search/close.png
-usr/share/doc/spede/html/search/files_0.html
-usr/share/doc/spede/html/search/files_0.js
-usr/share/doc/spede/html/search/functions_0.html
-usr/share/doc/spede/html/search/functions_0.js
-usr/share/doc/spede/html/search/functions_1.html
-usr/share/doc/spede/html/search/functions_1.js
-usr/share/doc/spede/html/search/functions_2.html
-usr/share/doc/spede/html/search/functions_2.js
-usr/share/doc/spede/html/search/mag_sel.png
-usr/share/doc/spede/html/search/namespaces_0.html
-usr/share/doc/spede/html/search/namespaces_0.js
-usr/share/doc/spede/html/search/nomatches.html
-usr/share/doc/spede/html/search/pages_0.html
-usr/share/doc/spede/html/search/pages_0.js
-usr/share/doc/spede/html/search/search.css
-usr/share/doc/spede/html/search/search.js
-usr/share/doc/spede/html/search/searchdata.js
-usr/share/doc/spede/html/search/search_l.png
-usr/share/doc/spede/html/search/search_m.png
-usr/share/doc/spede/html/search/search_r.png
-usr/share/doc/spede/html/spede_8cpp.html
-usr/share/doc/spede/html/spede_8h.html
-usr/share/doc/spede/html/spede_8h_source.html
-usr/share/doc/spede/html/splitbar.png
-usr/share/doc/spede/html/sync_off.png
-usr/share/doc/spede/html/sync_on.png
-usr/share/doc/spede/html/tabs.css
-usr/share/doc/spede/html/tab_a.png
-usr/share/doc/spede/html/tab_b.png
-usr/share/doc/spede/html/tab_h.png
-usr/share/doc/spede/html/tab_s.png
diff --git a/test cases/frameworks/14 doxygen/test.json b/test cases/frameworks/14 doxygen/test.json
new file mode 100644
index 0000000..85fdf73
--- /dev/null
+++ b/test cases/frameworks/14 doxygen/test.json
@@ -0,0 +1,87 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/doc/spede/html/annotated.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/bc_s.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/bdwn.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/classComedy_1_1Comedian.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/classComedy_1_1Comedian.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/classComedy_1_1Comedian-members.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/classComedy_1_1Spede.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/classComedy_1_1Spede.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/classComedy_1_1Spede-members.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/classes.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/closed.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/comedian_8h_source.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/dir_7bdce917e28dfbd493cadd1d2e5c7d80.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/dir_44a4667d36a4476878de085754f6d2b9.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/dir_68b523c5b3a2dcea45d5ce70397fb722.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/dir_a7e6472d2301212032fd74682f8217f3.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/dir_ee191f21c02d247cc959e80c1a3acadf.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/doc.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/doxygen.css"},
+ {"type": "file", "file": "usr/share/doc/spede/html/doxygen.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/dynsections.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/files.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/folderclosed.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/folderopen.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/functions.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/functions_func.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/hierarchy.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/index.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/jquery.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/menu.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/menudata.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/namespaceComedy.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/namespacemembers.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/namespacemembers_func.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/namespaces.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/nav_f.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/nav_g.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/nav_h.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/open.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/all_0.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/all_0.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/all_1.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/all_1.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/all_2.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/all_2.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/all_3.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/all_3.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/classes_0.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/classes_0.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/classes_1.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/classes_1.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/close.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/files_0.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/files_0.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/functions_0.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/functions_0.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/functions_1.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/functions_1.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/functions_2.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/functions_2.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/mag_sel.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/namespaces_0.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/namespaces_0.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/nomatches.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/pages_0.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/pages_0.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/search.css"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/search.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/searchdata.js"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/search_l.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/search_m.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/search/search_r.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/spede_8cpp.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/spede_8h.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/spede_8h_source.html"},
+ {"type": "file", "file": "usr/share/doc/spede/html/splitbar.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/sync_off.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/sync_on.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/tabs.css"},
+ {"type": "file", "file": "usr/share/doc/spede/html/tab_a.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/tab_b.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/tab_h.png"},
+ {"type": "file", "file": "usr/share/doc/spede/html/tab_s.png"}
+ ]
+}
diff --git a/test cases/frameworks/23 hotdoc/installed_files.txt b/test cases/frameworks/23 hotdoc/installed_files.txt
deleted file mode 100644
index 82597a2..0000000
--- a/test cases/frameworks/23 hotdoc/installed_files.txt
+++ /dev/null
@@ -1,314 +0,0 @@
-usr/share/doc/foobar/html/foo.html
-usr/share/doc/foobar/html/c-index.html
-usr/share/doc/foobar/html/index.html
-usr/share/doc/foobar/html/dumped.trie
-usr/share/doc/foobar/html/assets/theme.json
-usr/share/doc/foobar/html/assets/css/prism-tomorrow.css
-usr/share/doc/foobar/html/assets/css/bootstrap-toc.min.css
-usr/share/doc/foobar/html/assets/css/frontend.css
-usr/share/doc/foobar/html/assets/css/dumped.trie
-usr/share/doc/foobar/html/assets/css/jquery.mCustomScrollbar.min.css
-usr/share/doc/foobar/html/assets/css/custom_bootstrap.css
-usr/share/doc/foobar/html/assets/templates/navbar_links.html
-usr/share/doc/foobar/html/assets/templates/scripts.html
-usr/share/doc/foobar/html/assets/templates/stylesheets.html
-usr/share/doc/foobar/html/assets/templates/multi_return_value.html
-usr/share/doc/foobar/html/assets/templates/parameters.html
-usr/share/doc/foobar/html/assets/templates/base_page.html
-usr/share/doc/foobar/html/assets/templates/footer.html
-usr/share/doc/foobar/html/assets/templates/extra_head.html
-usr/share/doc/foobar/html/assets/templates/parameter_detail.html
-usr/share/doc/foobar/html/assets/templates/navbar_center.html
-usr/share/doc/foobar/html/assets/templates/enum_member.html
-usr/share/doc/foobar/html/assets/templates/member_list.html
-usr/share/doc/foobar/html/assets/templates/return_item.html
-usr/share/doc/foobar/html/assets/templates/subpages.html
-usr/share/doc/foobar/html/assets/templates/dumped.trie
-usr/share/doc/foobar/html/assets/templates/page_content.html
-usr/share/doc/foobar/html/assets/templates/navbar.html
-usr/share/doc/foobar/html/assets/templates/site_navigation.html
-usr/share/doc/foobar/html/assets/templates/field_detail.html
-usr/share/doc/foobar/html/assets/templates/brand-logo.html
-usr/share/doc/foobar/html/assets/js/prism_autoloader_path_override.js
-usr/share/doc/foobar/html/assets/js/jquery.js
-usr/share/doc/foobar/html/assets/js/scrollspy.js
-usr/share/doc/foobar/html/assets/js/isotope.pkgd.min.js
-usr/share/doc/foobar/html/assets/js/utils.js
-usr/share/doc/foobar/html/assets/js/typeahead.jquery.min.js
-usr/share/doc/foobar/html/assets/js/language_switching.js
-usr/share/doc/foobar/html/assets/js/tag_filtering.js
-usr/share/doc/foobar/html/assets/js/prism-autoloader.js
-usr/share/doc/foobar/html/assets/js/navbar_offset_scroller.js
-usr/share/doc/foobar/html/assets/js/lines_around_headings.js
-usr/share/doc/foobar/html/assets/js/trie_index.js
-usr/share/doc/foobar/html/assets/js/search.js
-usr/share/doc/foobar/html/assets/js/trie.js
-usr/share/doc/foobar/html/assets/js/bootstrap.js
-usr/share/doc/foobar/html/assets/js/navigation.js
-usr/share/doc/foobar/html/assets/js/bootstrap-toc.min.js
-usr/share/doc/foobar/html/assets/js/anchor.min.js
-usr/share/doc/foobar/html/assets/js/prism-core.js
-usr/share/doc/foobar/html/assets/js/sitemap.js
-usr/share/doc/foobar/html/assets/js/dumped.trie
-usr/share/doc/foobar/html/assets/js/mustache.min.js
-usr/share/doc/foobar/html/assets/js/compare-versions.js
-usr/share/doc/foobar/html/assets/js/jquery.touchSwipe.min.js
-usr/share/doc/foobar/html/assets/js/jquery.mCustomScrollbar.concat.min.js
-usr/share/doc/foobar/html/assets/js/search/members
-usr/share/doc/foobar/html/assets/js/search/Hello
-usr/share/doc/foobar/html/assets/js/search/hello
-usr/share/doc/foobar/html/assets/js/search/type
-usr/share/doc/foobar/html/assets/js/search/FooIndecision
-usr/share/doc/foobar/html/assets/js/search/fooindecision
-usr/share/doc/foobar/html/assets/js/search/Members
-usr/share/doc/foobar/html/assets/js/search/dumped.trie
-usr/share/doc/foobar/html/assets/js/search/indecision
-usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/index.html-hello-world.fragment
-usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/dumped.trie
-usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/foo.html-FooIndecision.fragment
-usr/share/doc/foobar/html/assets/js/search/Subpages
-usr/share/doc/foobar/html/assets/js/search/foo
-usr/share/doc/foobar/html/assets/js/search/API
-usr/share/doc/foobar/html/assets/js/search/Reference
-usr/share/doc/foobar/html/assets/js/search/api
-usr/share/doc/foobar/html/assets/js/search/reference
-usr/share/doc/foobar/html/assets/js/search/subpages
-usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/index.html-subpages.fragment
-usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/c-index.html-subpages.fragment
-usr/share/doc/foobar/html/assets/prism_components/prism-inform7.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-pascal.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-bro.js
-usr/share/doc/foobar/html/assets/prism_components/prism-nim.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-gherkin.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-stylus.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-ocaml.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-powershell.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-smalltalk.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-verilog.js
-usr/share/doc/foobar/html/assets/prism_components/prism-puppet.js
-usr/share/doc/foobar/html/assets/prism_components/prism-aspnet.js
-usr/share/doc/foobar/html/assets/prism_components/prism-parigp.js
-usr/share/doc/foobar/html/assets/prism_components/prism-objectivec.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-processing.js
-usr/share/doc/foobar/html/assets/prism_components/prism-objectivec.js
-usr/share/doc/foobar/html/assets/prism_components/prism-jsx.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-nginx.js
-usr/share/doc/foobar/html/assets/prism_components/prism-powershell.js
-usr/share/doc/foobar/html/assets/prism_components/prism-php.js
-usr/share/doc/foobar/html/assets/prism_components/prism-smarty.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-roboconf.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-batch.js
-usr/share/doc/foobar/html/assets/prism_components/prism-vhdl.js
-usr/share/doc/foobar/html/assets/prism_components/prism-protobuf.js
-usr/share/doc/foobar/html/assets/prism_components/prism-textile.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-crystal.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-scss.js
-usr/share/doc/foobar/html/assets/prism_components/prism-bro.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-smarty.js
-usr/share/doc/foobar/html/assets/prism_components/prism-bison.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-tcl.js
-usr/share/doc/foobar/html/assets/prism_components/prism-pure.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-makefile.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-applescript.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-css-extras.js
-usr/share/doc/foobar/html/assets/prism_components/prism-stylus.js
-usr/share/doc/foobar/html/assets/prism_components/prism-q.js
-usr/share/doc/foobar/html/assets/prism_components/prism-dart.js
-usr/share/doc/foobar/html/assets/prism_components/prism-oz.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-haskell.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-clike.js
-usr/share/doc/foobar/html/assets/prism_components/prism-kotlin.js
-usr/share/doc/foobar/html/assets/prism_components/prism-http.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-bash.js
-usr/share/doc/foobar/html/assets/prism_components/prism-apl.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-docker.js
-usr/share/doc/foobar/html/assets/prism_components/prism-sass.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-basic.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-nasm.js
-usr/share/doc/foobar/html/assets/prism_components/prism-kotlin.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-abap.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-perl.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-rust.js
-usr/share/doc/foobar/html/assets/prism_components/prism-c.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-scala.js
-usr/share/doc/foobar/html/assets/prism_components/prism-glsl.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-lua.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-coffeescript.js
-usr/share/doc/foobar/html/assets/prism_components/prism-jade.js
-usr/share/doc/foobar/html/assets/prism_components/prism-keyman.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-crystal.js
-usr/share/doc/foobar/html/assets/prism_components/prism-rest.js
-usr/share/doc/foobar/html/assets/prism_components/prism-json.js
-usr/share/doc/foobar/html/assets/prism_components/prism-roboconf.js
-usr/share/doc/foobar/html/assets/prism_components/prism-twig.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-dart.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-vim.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-handlebars.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-cpp.js
-usr/share/doc/foobar/html/assets/prism_components/prism-fsharp.js
-usr/share/doc/foobar/html/assets/prism_components/prism-sas.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-brainfuck.js
-usr/share/doc/foobar/html/assets/prism_components/prism-haxe.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-julia.js
-usr/share/doc/foobar/html/assets/prism_components/prism-jade.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-python.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-nim.js
-usr/share/doc/foobar/html/assets/prism_components/prism-typescript.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-csharp.js
-usr/share/doc/foobar/html/assets/prism_components/prism-brainfuck.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-asciidoc.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-groovy.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-applescript.js
-usr/share/doc/foobar/html/assets/prism_components/prism-elixir.js
-usr/share/doc/foobar/html/assets/prism_components/prism-diff.js
-usr/share/doc/foobar/html/assets/prism_components/prism-scheme.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-parser.js
-usr/share/doc/foobar/html/assets/prism_components/prism-qore.js
-usr/share/doc/foobar/html/assets/prism_components/prism-yaml.js
-usr/share/doc/foobar/html/assets/prism_components/prism-j.js
-usr/share/doc/foobar/html/assets/prism_components/prism-mel.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-css-extras.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-erlang.js
-usr/share/doc/foobar/html/assets/prism_components/prism-icon.js
-usr/share/doc/foobar/html/assets/prism_components/prism-actionscript.js
-usr/share/doc/foobar/html/assets/prism_components/prism-cpp.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-makefile.js
-usr/share/doc/foobar/html/assets/prism_components/prism-q.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-nsis.js
-usr/share/doc/foobar/html/assets/prism_components/prism-mizar.js
-usr/share/doc/foobar/html/assets/prism_components/prism-wiki.js
-usr/share/doc/foobar/html/assets/prism_components/prism-csharp.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-julia.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-coffeescript.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-sql.js
-usr/share/doc/foobar/html/assets/prism_components/prism-php-extras.js
-usr/share/doc/foobar/html/assets/prism_components/prism-basic.js
-usr/share/doc/foobar/html/assets/prism_components/prism-swift.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-haxe.js
-usr/share/doc/foobar/html/assets/prism_components/prism-apacheconf.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-javascript.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-markup.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-keyman.js
-usr/share/doc/foobar/html/assets/prism_components/prism-sql.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-php-extras.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-scheme.js
-usr/share/doc/foobar/html/assets/prism_components/prism-python.js
-usr/share/doc/foobar/html/assets/prism_components/prism-autoit.js
-usr/share/doc/foobar/html/assets/prism_components/prism-gherkin.js
-usr/share/doc/foobar/html/assets/prism_components/prism-java.js
-usr/share/doc/foobar/html/assets/prism_components/prism-parigp.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-autohotkey.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-ruby.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-nginx.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-core.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-fortran.js
-usr/share/doc/foobar/html/assets/prism_components/prism-nasm.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-ini.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-protobuf.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-jsx.js
-usr/share/doc/foobar/html/assets/prism_components/prism-markdown.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-nix.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-nsis.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-oz.js
-usr/share/doc/foobar/html/assets/prism_components/prism-less.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-abap.js
-usr/share/doc/foobar/html/assets/prism_components/prism-puppet.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-nix.js
-usr/share/doc/foobar/html/assets/prism_components/prism-pascal.js
-usr/share/doc/foobar/html/assets/prism_components/prism-latex.js
-usr/share/doc/foobar/html/assets/prism_components/prism-verilog.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-aspnet.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-go.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-glsl.js
-usr/share/doc/foobar/html/assets/prism_components/prism-inform7.js
-usr/share/doc/foobar/html/assets/prism_components/prism-yaml.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-matlab.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-lua.js
-usr/share/doc/foobar/html/assets/prism_components/prism-mizar.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-c.js
-usr/share/doc/foobar/html/assets/prism_components/prism-fsharp.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-haml.js
-usr/share/doc/foobar/html/assets/prism_components/prism-rust.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-icon.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-fortran.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-qore.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-batch.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-eiffel.js
-usr/share/doc/foobar/html/assets/prism_components/prism-vim.js
-usr/share/doc/foobar/html/assets/prism_components/prism-j.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-eiffel.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-elixir.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-erlang.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-matlab.js
-usr/share/doc/foobar/html/assets/prism_components/prism-tcl.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-ruby.js
-usr/share/doc/foobar/html/assets/prism_components/prism-d.js
-usr/share/doc/foobar/html/assets/prism_components/prism-swift.js
-usr/share/doc/foobar/html/assets/prism_components/prism-wiki.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-lolcode.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-latex.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-prolog.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-php.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-scss.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-vhdl.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-lolcode.js
-usr/share/doc/foobar/html/assets/prism_components/prism-prolog.js
-usr/share/doc/foobar/html/assets/prism_components/prism-apacheconf.js
-usr/share/doc/foobar/html/assets/prism_components/prism-core.js
-usr/share/doc/foobar/html/assets/prism_components/prism-diff.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-json.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-ini.js
-usr/share/doc/foobar/html/assets/prism_components/dumped.trie
-usr/share/doc/foobar/html/assets/prism_components/prism-r.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-markup.js
-usr/share/doc/foobar/html/assets/prism_components/prism-apl.js
-usr/share/doc/foobar/html/assets/prism_components/prism-markdown.js
-usr/share/doc/foobar/html/assets/prism_components/prism-asciidoc.js
-usr/share/doc/foobar/html/assets/prism_components/prism-ocaml.js
-usr/share/doc/foobar/html/assets/prism_components/prism-javascript.js
-usr/share/doc/foobar/html/assets/prism_components/prism-autohotkey.js
-usr/share/doc/foobar/html/assets/prism_components/prism-less.js
-usr/share/doc/foobar/html/assets/prism_components/prism-pure.js
-usr/share/doc/foobar/html/assets/prism_components/prism-groovy.js
-usr/share/doc/foobar/html/assets/prism_components/prism-bison.js
-usr/share/doc/foobar/html/assets/prism_components/prism-sass.js
-usr/share/doc/foobar/html/assets/prism_components/prism-css.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-haml.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-handlebars.js
-usr/share/doc/foobar/html/assets/prism_components/prism-textile.js
-usr/share/doc/foobar/html/assets/prism_components/prism-parser.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-docker.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-monkey.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-http.js
-usr/share/doc/foobar/html/assets/prism_components/prism-git.js
-usr/share/doc/foobar/html/assets/prism_components/prism-sas.js
-usr/share/doc/foobar/html/assets/prism_components/prism-go.js
-usr/share/doc/foobar/html/assets/prism_components/prism-mel.js
-usr/share/doc/foobar/html/assets/prism_components/prism-rest.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-clike.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-d.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-haskell.js
-usr/share/doc/foobar/html/assets/prism_components/prism-git.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-java.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-rip.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-perl.js
-usr/share/doc/foobar/html/assets/prism_components/prism-typescript.js
-usr/share/doc/foobar/html/assets/prism_components/prism-actionscript.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-autoit.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-rip.js
-usr/share/doc/foobar/html/assets/prism_components/prism-twig.js
-usr/share/doc/foobar/html/assets/prism_components/prism-monkey.js
-usr/share/doc/foobar/html/assets/prism_components/prism-processing.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-scala.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-smalltalk.js
-usr/share/doc/foobar/html/assets/prism_components/prism-bash.min.js
-usr/share/doc/foobar/html/assets/prism_components/prism-r.js
-usr/share/doc/foobar/html/assets/prism_components/prism-css.js
-usr/share/doc/foobar/html/assets/fonts/glyphicons-halflings-regular.woff
-usr/share/doc/foobar/html/assets/fonts/glyphicons-halflings-regular.woff2
-usr/share/doc/foobar/html/assets/fonts/glyphicons-halflings-regular.svg
-usr/share/doc/foobar/html/assets/fonts/glyphicons-halflings-regular.ttf
-usr/share/doc/foobar/html/assets/fonts/glyphicons-halflings-regular.eot
-usr/share/doc/foobar/html/assets/fonts/dumped.trie
-usr/share/doc/foobar/html/assets/images/home.svg
-usr/share/doc/foobar/html/assets/images/dumped.trie
diff --git a/test cases/frameworks/23 hotdoc/test.json b/test cases/frameworks/23 hotdoc/test.json
new file mode 100644
index 0000000..e2d4992
--- /dev/null
+++ b/test cases/frameworks/23 hotdoc/test.json
@@ -0,0 +1,318 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/share/doc/foobar/html/foo.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/c-index.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/index.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/dumped.trie"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/theme.json"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/css/prism-tomorrow.css"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/css/bootstrap-toc.min.css"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/css/frontend.css"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/css/dumped.trie"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/css/jquery.mCustomScrollbar.min.css"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/css/custom_bootstrap.css"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/navbar_links.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/scripts.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/stylesheets.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/multi_return_value.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/parameters.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/base_page.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/footer.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/extra_head.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/parameter_detail.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/navbar_center.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/enum_member.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/member_list.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/return_item.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/subpages.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/dumped.trie"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/page_content.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/navbar.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/site_navigation.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/field_detail.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/templates/brand-logo.html"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/prism_autoloader_path_override.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/jquery.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/scrollspy.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/isotope.pkgd.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/utils.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/typeahead.jquery.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/language_switching.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/tag_filtering.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/prism-autoloader.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/navbar_offset_scroller.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/lines_around_headings.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/trie_index.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/trie.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/bootstrap.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/navigation.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/bootstrap-toc.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/anchor.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/prism-core.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/sitemap.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/dumped.trie"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/mustache.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/compare-versions.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/jquery.touchSwipe.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/jquery.mCustomScrollbar.concat.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/members"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/Hello"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/hello"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/type"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/FooIndecision"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/fooindecision"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/Members"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/dumped.trie"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/indecision"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/index.html-hello-world.fragment"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/dumped.trie"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/foo.html-FooIndecision.fragment"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/Subpages"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/foo"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/API"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/Reference"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/api"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/reference"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/subpages"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/index.html-subpages.fragment"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/js/search/hotdoc_fragments/c-index.html-subpages.fragment"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-inform7.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-pascal.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-bro.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-nim.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-gherkin.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-stylus.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-ocaml.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-powershell.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-smalltalk.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-verilog.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-puppet.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-aspnet.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-parigp.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-objectivec.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-processing.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-objectivec.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-jsx.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-nginx.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-powershell.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-php.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-smarty.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-roboconf.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-batch.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-vhdl.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-protobuf.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-textile.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-crystal.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-scss.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-bro.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-smarty.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-bison.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-tcl.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-pure.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-makefile.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-applescript.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-css-extras.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-stylus.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-q.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-dart.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-oz.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-haskell.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-clike.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-kotlin.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-http.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-bash.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-apl.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-docker.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-sass.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-basic.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-nasm.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-kotlin.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-abap.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-perl.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-rust.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-c.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-scala.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-glsl.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-lua.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-coffeescript.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-jade.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-keyman.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-crystal.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-rest.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-json.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-roboconf.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-twig.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-dart.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-vim.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-handlebars.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-cpp.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-fsharp.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-sas.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-brainfuck.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-haxe.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-julia.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-jade.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-python.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-nim.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-typescript.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-csharp.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-brainfuck.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-asciidoc.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-groovy.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-applescript.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-elixir.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-diff.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-scheme.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-parser.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-qore.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-yaml.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-j.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-mel.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-css-extras.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-erlang.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-icon.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-actionscript.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-cpp.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-makefile.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-q.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-nsis.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-mizar.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-wiki.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-csharp.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-julia.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-coffeescript.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-sql.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-php-extras.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-basic.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-swift.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-haxe.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-apacheconf.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-javascript.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-markup.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-keyman.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-sql.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-php-extras.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-scheme.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-python.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-autoit.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-gherkin.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-java.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-parigp.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-autohotkey.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-ruby.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-nginx.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-core.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-fortran.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-nasm.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-ini.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-protobuf.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-jsx.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-markdown.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-nix.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-nsis.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-oz.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-less.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-abap.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-puppet.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-nix.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-pascal.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-latex.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-verilog.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-aspnet.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-go.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-glsl.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-inform7.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-yaml.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-matlab.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-lua.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-mizar.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-c.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-fsharp.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-haml.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-rust.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-icon.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-fortran.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-qore.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-batch.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-eiffel.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-vim.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-j.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-eiffel.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-elixir.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-erlang.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-matlab.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-tcl.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-ruby.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-d.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-swift.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-wiki.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-lolcode.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-latex.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-prolog.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-php.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-scss.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-vhdl.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-lolcode.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-prolog.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-apacheconf.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-core.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-diff.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-json.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-ini.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/dumped.trie"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-r.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-markup.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-apl.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-markdown.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-asciidoc.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-ocaml.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-javascript.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-autohotkey.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-less.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-pure.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-groovy.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-bison.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-sass.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-css.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-haml.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-handlebars.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-textile.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-parser.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-docker.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-monkey.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-http.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-git.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-sas.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-go.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-mel.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-rest.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-clike.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-d.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-haskell.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-git.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-java.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-rip.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-perl.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-typescript.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-actionscript.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-autoit.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-rip.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-twig.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-monkey.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-processing.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-scala.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-smalltalk.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-bash.min.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-r.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/prism_components/prism-css.js"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/fonts/glyphicons-halflings-regular.woff"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/fonts/glyphicons-halflings-regular.woff2"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/fonts/glyphicons-halflings-regular.svg"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/fonts/glyphicons-halflings-regular.ttf"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/fonts/glyphicons-halflings-regular.eot"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/fonts/dumped.trie"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/images/home.svg"},
+ {"type": "file", "file": "usr/share/doc/foobar/html/assets/images/dumped.trie"}
+ ]
+}
diff --git a/test cases/frameworks/6 gettext/installed_files.txt b/test cases/frameworks/6 gettext/installed_files.txt
deleted file mode 100644
index f32b282..0000000
--- a/test cases/frameworks/6 gettext/installed_files.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-usr/bin/intlprog?exe
-usr/share/locale/de/LC_MESSAGES/intltest.mo
-usr/share/locale/fi/LC_MESSAGES/intltest.mo
-usr/share/locale/ru/LC_MESSAGES/intltest.mo
-usr/share/applications/something.desktop
-usr/share/applications/test.desktop
-usr/share/applications/test.plugin
-usr/share/applications/test2.desktop
-usr/share/applications/test3.desktop
-usr/share/applications/test4.desktop
diff --git a/test cases/frameworks/6 gettext/test.json b/test cases/frameworks/6 gettext/test.json
new file mode 100644
index 0000000..1ed2dbf
--- /dev/null
+++ b/test cases/frameworks/6 gettext/test.json
@@ -0,0 +1,14 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/intlprog"},
+ {"type": "file", "file": "usr/share/locale/de/LC_MESSAGES/intltest.mo"},
+ {"type": "file", "file": "usr/share/locale/fi/LC_MESSAGES/intltest.mo"},
+ {"type": "file", "file": "usr/share/locale/ru/LC_MESSAGES/intltest.mo"},
+ {"type": "file", "file": "usr/share/applications/something.desktop"},
+ {"type": "file", "file": "usr/share/applications/test.desktop"},
+ {"type": "file", "file": "usr/share/applications/test.plugin"},
+ {"type": "file", "file": "usr/share/applications/test2.desktop"},
+ {"type": "file", "file": "usr/share/applications/test3.desktop"},
+ {"type": "file", "file": "usr/share/applications/test4.desktop"}
+ ]
+}
diff --git a/test cases/frameworks/7 gnome/installed_files.txt b/test cases/frameworks/7 gnome/installed_files.txt
deleted file mode 100644
index 9c1d496..0000000
--- a/test cases/frameworks/7 gnome/installed_files.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-usr/include/enums.h
-usr/include/enums2.h
-usr/include/enums3.h
-usr/include/enums5.h
-usr/include/marshaller.h
-usr/lib/?libgir_lib.so
-?cygwin:usr/lib/libgir_lib.dll.a
-usr/lib/?libgir_lib2.so
-?cygwin:usr/lib/libgir_lib2.dll.a
-usr/lib/?libdep1lib.so
-?cygwin:usr/lib/libdep1lib.dll.a
-usr/lib/?libdep2lib.so
-?cygwin:usr/lib/libdep2lib.dll.a
-usr/lib/girepository-1.0/Meson-1.0.typelib
-usr/lib/girepository-1.0/MesonDep1-1.0.typelib
-usr/lib/girepository-1.0/MesonDep2-1.0.typelib
-usr/share/gir-1.0/Meson-1.0.gir
-usr/share/gir-1.0/MesonDep1-1.0.gir
-usr/share/gir-1.0/MesonDep2-1.0.gir
-usr/share/glib-2.0/schemas/com.github.meson.gschema.xml
-usr/share/simple-resources.gresource
-usr/include/enums6.h
-usr/include/simple-resources.h
-usr/include/generated-gdbus.h
diff --git a/test cases/frameworks/7 gnome/test.json b/test cases/frameworks/7 gnome/test.json
new file mode 100644
index 0000000..e69c9f0
--- /dev/null
+++ b/test cases/frameworks/7 gnome/test.json
@@ -0,0 +1,28 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/include/enums.h"},
+ {"type": "file", "file": "usr/include/enums2.h"},
+ {"type": "file", "file": "usr/include/enums3.h"},
+ {"type": "file", "file": "usr/include/enums5.h"},
+ {"type": "file", "file": "usr/include/marshaller.h"},
+ {"type": "expr", "file": "usr/lib/?libgir_lib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libgir_lib.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libgir_lib2.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libgir_lib2.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libdep1lib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libdep1lib.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libdep2lib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libdep2lib.dll.a"},
+ {"type": "file", "file": "usr/lib/girepository-1.0/Meson-1.0.typelib"},
+ {"type": "file", "file": "usr/lib/girepository-1.0/MesonDep1-1.0.typelib"},
+ {"type": "file", "file": "usr/lib/girepository-1.0/MesonDep2-1.0.typelib"},
+ {"type": "file", "file": "usr/share/gir-1.0/Meson-1.0.gir"},
+ {"type": "file", "file": "usr/share/gir-1.0/MesonDep1-1.0.gir"},
+ {"type": "file", "file": "usr/share/gir-1.0/MesonDep2-1.0.gir"},
+ {"type": "file", "file": "usr/share/glib-2.0/schemas/com.github.meson.gschema.xml"},
+ {"type": "file", "file": "usr/share/simple-resources.gresource"},
+ {"type": "file", "file": "usr/include/enums6.h"},
+ {"type": "file", "file": "usr/include/simple-resources.h"},
+ {"type": "file", "file": "usr/include/generated-gdbus.h"}
+ ]
+}
diff --git a/test cases/java/1 basic/installed_files.txt b/test cases/java/1 basic/installed_files.txt
deleted file mode 100644
index 1c7cede..0000000
--- a/test cases/java/1 basic/installed_files.txt
+++ /dev/null
@@ -1 +0,0 @@
-usr/bin/myprog.jar
diff --git a/test cases/java/1 basic/test.json b/test cases/java/1 basic/test.json
new file mode 100644
index 0000000..b5b1539
--- /dev/null
+++ b/test cases/java/1 basic/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/myprog.jar"}
+ ]
+}
diff --git a/test cases/linuxlike/13 cmake dependency/setup_env.json b/test cases/linuxlike/13 cmake dependency/setup_env.json
deleted file mode 100644
index aa15374..0000000
--- a/test cases/linuxlike/13 cmake dependency/setup_env.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "CMAKE_PREFIX_PATH": "@ROOT@/cmake_pref_env"
-}
diff --git a/test cases/linuxlike/13 cmake dependency/test.json b/test cases/linuxlike/13 cmake dependency/test.json
new file mode 100644
index 0000000..565713e
--- /dev/null
+++ b/test cases/linuxlike/13 cmake dependency/test.json
@@ -0,0 +1,5 @@
+{
+ "env": {
+ "CMAKE_PREFIX_PATH": "@ROOT@/cmake_pref_env"
+ }
+}
diff --git a/test cases/linuxlike/7 library versions/installed_files.txt b/test cases/linuxlike/7 library versions/installed_files.txt
deleted file mode 100644
index 763a907..0000000
--- a/test cases/linuxlike/7 library versions/installed_files.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-usr/lib/libsome.so
-usr/lib/libsome.so.0
-usr/lib/libsome.so.1.2.3
-usr/lib/libnoversion.so
-usr/lib/libonlyversion.so
-usr/lib/libonlyversion.so.1
-usr/lib/libonlyversion.so.1.4.5
-usr/lib/libonlysoversion.so
-usr/lib/libonlysoversion.so.5
-usr/lib/libmodule.so
diff --git a/test cases/linuxlike/7 library versions/test.json b/test cases/linuxlike/7 library versions/test.json
new file mode 100644
index 0000000..0da9277
--- /dev/null
+++ b/test cases/linuxlike/7 library versions/test.json
@@ -0,0 +1,14 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/libsome.so"},
+ {"type": "file", "file": "usr/lib/libsome.so.0"},
+ {"type": "file", "file": "usr/lib/libsome.so.1.2.3"},
+ {"type": "file", "file": "usr/lib/libnoversion.so"},
+ {"type": "file", "file": "usr/lib/libonlyversion.so"},
+ {"type": "file", "file": "usr/lib/libonlyversion.so.1"},
+ {"type": "file", "file": "usr/lib/libonlyversion.so.1.4.5"},
+ {"type": "file", "file": "usr/lib/libonlysoversion.so"},
+ {"type": "file", "file": "usr/lib/libonlysoversion.so.5"},
+ {"type": "file", "file": "usr/lib/libmodule.so"}
+ ]
+}
diff --git a/test cases/linuxlike/8 subproject library install/installed_files.txt b/test cases/linuxlike/8 subproject library install/installed_files.txt
deleted file mode 100644
index 5c4a301..0000000
--- a/test cases/linuxlike/8 subproject library install/installed_files.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/lib/libsublib.so
-usr/lib/libsublib.so.5
-usr/lib/libsublib.so.2.1.0
diff --git a/test cases/linuxlike/8 subproject library install/test.json b/test cases/linuxlike/8 subproject library install/test.json
new file mode 100644
index 0000000..5a2bf04
--- /dev/null
+++ b/test cases/linuxlike/8 subproject library install/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/libsublib.so"},
+ {"type": "file", "file": "usr/lib/libsublib.so.5"},
+ {"type": "file", "file": "usr/lib/libsublib.so.2.1.0"}
+ ]
+}
diff --git a/test cases/osx/2 library versions/installed_files.txt b/test cases/osx/2 library versions/installed_files.txt
deleted file mode 100644
index f9c629b..0000000
--- a/test cases/osx/2 library versions/installed_files.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-usr/lib/libsome.dylib
-usr/lib/libsome.7.dylib
-usr/lib/libnoversion.dylib
-usr/lib/libonlyversion.dylib
-usr/lib/libonlyversion.1.dylib
-usr/lib/libonlysoversion.dylib
-usr/lib/libonlysoversion.5.dylib
-usr/lib/libmodule.dylib
diff --git a/test cases/osx/2 library versions/test.json b/test cases/osx/2 library versions/test.json
new file mode 100644
index 0000000..3234425
--- /dev/null
+++ b/test cases/osx/2 library versions/test.json
@@ -0,0 +1,12 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/libsome.dylib"},
+ {"type": "file", "file": "usr/lib/libsome.7.dylib"},
+ {"type": "file", "file": "usr/lib/libnoversion.dylib"},
+ {"type": "file", "file": "usr/lib/libonlyversion.dylib"},
+ {"type": "file", "file": "usr/lib/libonlyversion.1.dylib"},
+ {"type": "file", "file": "usr/lib/libonlysoversion.dylib"},
+ {"type": "file", "file": "usr/lib/libonlysoversion.5.dylib"},
+ {"type": "file", "file": "usr/lib/libmodule.dylib"}
+ ]
+}
diff --git a/test cases/osx/4 framework/installed_files.txt b/test cases/osx/4 framework/installed_files.txt
deleted file mode 100644
index 2c6bd93..0000000
--- a/test cases/osx/4 framework/installed_files.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin/prog
-usr/lib/libstat.a
diff --git a/test cases/osx/4 framework/test.json b/test cases/osx/4 framework/test.json
new file mode 100644
index 0000000..8def69a
--- /dev/null
+++ b/test cases/osx/4 framework/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libstat.a"}
+ ]
+}
diff --git a/test cases/osx/5 extra frameworks/installed_files.txt b/test cases/osx/5 extra frameworks/installed_files.txt
deleted file mode 100644
index 2c6bd93..0000000
--- a/test cases/osx/5 extra frameworks/installed_files.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin/prog
-usr/lib/libstat.a
diff --git a/test cases/osx/5 extra frameworks/test.json b/test cases/osx/5 extra frameworks/test.json
new file mode 100644
index 0000000..8def69a
--- /dev/null
+++ b/test cases/osx/5 extra frameworks/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libstat.a"}
+ ]
+}
diff --git a/test cases/rust/1 basic/installed_files.txt b/test cases/rust/1 basic/installed_files.txt
deleted file mode 100644
index 58aed81..0000000
--- a/test cases/rust/1 basic/installed_files.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-usr/bin/program?exe
-?msvc:usr/bin/program.pdb
-usr/bin/program2?exe
-?msvc:usr/bin/program2.pdb
diff --git a/test cases/rust/1 basic/test.json b/test cases/rust/1 basic/test.json
new file mode 100644
index 0000000..94c995b
--- /dev/null
+++ b/test cases/rust/1 basic/test.json
@@ -0,0 +1,8 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/program"},
+ {"type": "pdb", "file": "usr/bin/program"},
+ {"type": "exe", "file": "usr/bin/program2"},
+ {"type": "pdb", "file": "usr/bin/program2"}
+ ]
+}
diff --git a/test cases/rust/2 sharedlib/installed_files.txt b/test cases/rust/2 sharedlib/installed_files.txt
deleted file mode 100644
index fd1dbad..0000000
--- a/test cases/rust/2 sharedlib/installed_files.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-usr/bin/prog?exe
-?msvc:usr/bin/prog.pdb
-?gcc:usr/lib/libstuff.so
-?msvc:usr/bin/stuff.dll
-?msvc:usr/bin/stuff.pdb
-?msvc:usr/lib/stuff.dll.lib
diff --git a/test cases/rust/2 sharedlib/test.json b/test cases/rust/2 sharedlib/test.json
new file mode 100644
index 0000000..585fdeb
--- /dev/null
+++ b/test cases/rust/2 sharedlib/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libstuff.so"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/stuff.dll"},
+ {"type": "pdb", "file": "usr/bin/stuff"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/stuff.dll.lib"}
+ ]
+}
diff --git a/test cases/rust/3 staticlib/installed_files.txt b/test cases/rust/3 staticlib/installed_files.txt
deleted file mode 100644
index b8f09d7..0000000
--- a/test cases/rust/3 staticlib/installed_files.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/bin/prog?exe
-?msvc:usr/bin/prog.pdb
-usr/lib/libstuff.rlib
diff --git a/test cases/rust/3 staticlib/test.json b/test cases/rust/3 staticlib/test.json
new file mode 100644
index 0000000..ca29225
--- /dev/null
+++ b/test cases/rust/3 staticlib/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libstuff.rlib"}
+ ]
+}
diff --git a/test cases/rust/4 polyglot/installed_files.txt b/test cases/rust/4 polyglot/installed_files.txt
deleted file mode 100644
index 4a89107..0000000
--- a/test cases/rust/4 polyglot/installed_files.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-usr/bin/prog?exe
-?msvc:usr/bin/prog.pdb
-?gcc:usr/lib/libstuff.so
-?msvc:usr/bin/stuff.dll
-?msvc:usr/lib/stuff.dll.lib
-?msvc:usr/bin/stuff.pdb
-
diff --git a/test cases/rust/4 polyglot/test.json b/test cases/rust/4 polyglot/test.json
new file mode 100644
index 0000000..a8837a1
--- /dev/null
+++ b/test cases/rust/4 polyglot/test.json
@@ -0,0 +1,10 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libstuff.so"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/stuff.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/stuff.dll.lib"},
+ {"type": "pdb", "file": "usr/bin/stuff"}
+ ]
+}
diff --git a/test cases/rust/5 polyglot static/installed_files.txt b/test cases/rust/5 polyglot static/installed_files.txt
deleted file mode 100644
index b7d8f78..0000000
--- a/test cases/rust/5 polyglot static/installed_files.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/bin/prog?exe
-?msvc:usr/bin/prog.pdb
-usr/lib/libstuff.a
diff --git a/test cases/rust/5 polyglot static/test.json b/test cases/rust/5 polyglot static/test.json
new file mode 100644
index 0000000..1d4eff4
--- /dev/null
+++ b/test cases/rust/5 polyglot static/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libstuff.a"}
+ ]
+}
diff --git a/test cases/rust/6 named staticlib/installed_files.txt b/test cases/rust/6 named staticlib/installed_files.txt
deleted file mode 100644
index e118618..0000000
--- a/test cases/rust/6 named staticlib/installed_files.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/bin/prog?exe
-?msvc:usr/bin/prog.pdb
-usr/lib/libnamed_stuff.rlib
diff --git a/test cases/rust/6 named staticlib/test.json b/test cases/rust/6 named staticlib/test.json
new file mode 100644
index 0000000..3ac3e0b
--- /dev/null
+++ b/test cases/rust/6 named staticlib/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/libnamed_stuff.rlib"}
+ ]
+}
diff --git a/test cases/rust/7 private crate collision/installed_files.txt b/test cases/rust/7 private crate collision/installed_files.txt
deleted file mode 100644
index 07a4a16..0000000
--- a/test cases/rust/7 private crate collision/installed_files.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/bin/prog?exe
-?msvc:usr/bin/prog.pdb
-usr/lib/librand.rlib
diff --git a/test cases/rust/7 private crate collision/test.json b/test cases/rust/7 private crate collision/test.json
new file mode 100644
index 0000000..e35f6ff
--- /dev/null
+++ b/test cases/rust/7 private crate collision/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/prog"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/lib/librand.rlib"}
+ ]
+}
diff --git a/test cases/vala/11 generated vapi/installed_files.txt b/test cases/vala/11 generated vapi/installed_files.txt
deleted file mode 100644
index ca41d65..0000000
--- a/test cases/vala/11 generated vapi/installed_files.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-usr/bin/vapigen-test?exe
-usr/lib/?libfoo.so
-?cygwin:usr/lib/libfoo.dll.a
-usr/lib/?libbar.so
-?cygwin:usr/lib/libbar.dll.a
-usr/share/vala/vapi/foo-1.0.vapi
-usr/share/vala/vapi/foo-1.0.deps
-usr/share/vala/vapi/bar-1.0.vapi
-usr/share/vala/vapi/bar-1.0.deps
diff --git a/test cases/vala/11 generated vapi/test.json b/test cases/vala/11 generated vapi/test.json
new file mode 100644
index 0000000..1a742aa
--- /dev/null
+++ b/test cases/vala/11 generated vapi/test.json
@@ -0,0 +1,13 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/vapigen-test"},
+ {"type": "expr", "file": "usr/lib/?libfoo.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libfoo.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libbar.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libbar.dll.a"},
+ {"type": "file", "file": "usr/share/vala/vapi/foo-1.0.vapi"},
+ {"type": "file", "file": "usr/share/vala/vapi/foo-1.0.deps"},
+ {"type": "file", "file": "usr/share/vala/vapi/bar-1.0.vapi"},
+ {"type": "file", "file": "usr/share/vala/vapi/bar-1.0.deps"}
+ ]
+}
diff --git a/test cases/vala/6 static library/installed_files.txt b/test cases/vala/6 static library/installed_files.txt
deleted file mode 100644
index f464bc0..0000000
--- a/test cases/vala/6 static library/installed_files.txt
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/libextractedlib.a
diff --git a/test cases/vala/6 static library/test.json b/test cases/vala/6 static library/test.json
new file mode 100644
index 0000000..d85ef6d
--- /dev/null
+++ b/test cases/vala/6 static library/test.json
@@ -0,0 +1,5 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/lib/libextractedlib.a"}
+ ]
+}
diff --git a/test cases/vala/7 shared library/installed_files.txt b/test cases/vala/7 shared library/installed_files.txt
deleted file mode 100644
index 83cbb63..0000000
--- a/test cases/vala/7 shared library/installed_files.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-usr/lib/?libinstalled_vala_lib.so
-?cygwin:usr/lib/libinstalled_vala_lib.dll.a
-usr/lib/?libinstalled_vala_all.so
-?cygwin:usr/lib/libinstalled_vala_all.dll.a
-usr/include/installed_vala_all.h
-usr/include/valah/installed_vala_all_nolib.h
-usr/include/installed_vala_onlyh.h
-usr/share/vala/vapi/installed_vala_all.vapi
-usr/share/vala-1.0/vapi/installed_vala_all_nolib.vapi
-usr/share/vala/vapi/installed_vala_onlyvapi.vapi
diff --git a/test cases/vala/7 shared library/test.json b/test cases/vala/7 shared library/test.json
new file mode 100644
index 0000000..eee3c3d
--- /dev/null
+++ b/test cases/vala/7 shared library/test.json
@@ -0,0 +1,14 @@
+{
+ "installed": [
+ {"type": "expr", "file": "usr/lib/?libinstalled_vala_lib.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libinstalled_vala_lib.dll.a"},
+ {"type": "expr", "file": "usr/lib/?libinstalled_vala_all.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libinstalled_vala_all.dll.a"},
+ {"type": "file", "file": "usr/include/installed_vala_all.h"},
+ {"type": "file", "file": "usr/include/valah/installed_vala_all_nolib.h"},
+ {"type": "file", "file": "usr/include/installed_vala_onlyh.h"},
+ {"type": "file", "file": "usr/share/vala/vapi/installed_vala_all.vapi"},
+ {"type": "file", "file": "usr/share/vala-1.0/vapi/installed_vala_all_nolib.vapi"},
+ {"type": "file", "file": "usr/share/vala/vapi/installed_vala_onlyvapi.vapi"}
+ ]
+}
diff --git a/test cases/vala/8 generated sources/installed_files.txt b/test cases/vala/8 generated sources/installed_files.txt
deleted file mode 100644
index ae0f65f..0000000
--- a/test cases/vala/8 generated sources/installed_files.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/bin/generatedtestparent?exe
-usr/bin/generatedtest?exe
-usr/bin/onlygentest?exe
diff --git a/test cases/vala/8 generated sources/test.json b/test cases/vala/8 generated sources/test.json
new file mode 100644
index 0000000..d99a6ce
--- /dev/null
+++ b/test cases/vala/8 generated sources/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "exe", "file": "usr/bin/generatedtestparent"},
+ {"type": "exe", "file": "usr/bin/generatedtest"},
+ {"type": "exe", "file": "usr/bin/onlygentest"}
+ ]
+}
diff --git a/test cases/vala/9 gir/installed_files.txt b/test cases/vala/9 gir/installed_files.txt
deleted file mode 100644
index 890b47a..0000000
--- a/test cases/vala/9 gir/installed_files.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-?gcc:usr/lib/?libfoo.so
-?cygwin:usr/lib/libfoo.dll.a
-usr/share/gir-1.0/Foo-1.0.gir
diff --git a/test cases/vala/9 gir/test.json b/test cases/vala/9 gir/test.json
new file mode 100644
index 0000000..add1d71
--- /dev/null
+++ b/test cases/vala/9 gir/test.json
@@ -0,0 +1,7 @@
+{
+ "installed": [
+ {"type": "expr", "platform": "gcc", "file": "usr/lib/?libfoo.so"},
+ {"type": "file", "platform": "cygwin", "file": "usr/lib/libfoo.dll.a"},
+ {"type": "file", "file": "usr/share/gir-1.0/Foo-1.0.gir"}
+ ]
+}
diff --git a/test cases/windows/1 basic/installed_files.txt b/test cases/windows/1 basic/installed_files.txt
deleted file mode 100644
index 5022d28..0000000
--- a/test cases/windows/1 basic/installed_files.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin/prog.exe
-?msvc:usr/bin/prog.pdb
diff --git a/test cases/windows/1 basic/test.json b/test cases/windows/1 basic/test.json
new file mode 100644
index 0000000..650a6e2
--- /dev/null
+++ b/test cases/windows/1 basic/test.json
@@ -0,0 +1,6 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog.exe"},
+ {"type": "pdb", "file": "usr/bin/prog"}
+ ]
+}
diff --git a/test cases/windows/11 exe implib/installed_files.txt b/test cases/windows/11 exe implib/installed_files.txt
deleted file mode 100644
index b1e805c..0000000
--- a/test cases/windows/11 exe implib/installed_files.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-usr/bin/prog.exe
-?msvc:usr/bin/prog.pdb
-usr/bin/prog2.exe
-?msvc:usr/bin/prog2.pdb
-?gcc:usr/lib/libprog.exe.a
-?gcc:usr/lib/libburble.a
-?msvc:usr/lib/prog.exe.lib
-?msvc:usr/lib/burble.lib
diff --git a/test cases/windows/11 exe implib/test.json b/test cases/windows/11 exe implib/test.json
new file mode 100644
index 0000000..f719568
--- /dev/null
+++ b/test cases/windows/11 exe implib/test.json
@@ -0,0 +1,12 @@
+{
+ "installed": [
+ {"type": "file", "file": "usr/bin/prog.exe"},
+ {"type": "pdb", "file": "usr/bin/prog"},
+ {"type": "file", "file": "usr/bin/prog2.exe"},
+ {"type": "pdb", "file": "usr/bin/prog2"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libprog.exe.a"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libburble.a"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/prog.exe.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/burble.lib"}
+ ]
+}
diff --git a/test cases/windows/7 dll versioning/installed_files.txt b/test cases/windows/7 dll versioning/installed_files.txt
deleted file mode 100644
index f3a1e2d..0000000
--- a/test cases/windows/7 dll versioning/installed_files.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-?msvc:usr/bin/some-0.dll
-?msvc:usr/bin/some-0.pdb
-?msvc:usr/lib/some.lib
-?msvc:usr/bin/noversion.dll
-?msvc:usr/bin/noversion.pdb
-?msvc:usr/lib/noversion.lib
-?msvc:usr/bin/onlyversion-1.dll
-?msvc:usr/bin/onlyversion-1.pdb
-?msvc:usr/lib/onlyversion.lib
-?msvc:usr/bin/onlysoversion-5.dll
-?msvc:usr/bin/onlysoversion-5.pdb
-?msvc:usr/lib/onlysoversion.lib
-?msvc:usr/libexec/customdir.dll
-?msvc:usr/libexec/customdir.lib
-?msvc:usr/libexec/customdir.pdb
-?msvc:usr/lib/modules/module.dll
-?msvc:usr/lib/modules/module.lib
-?msvc:usr/lib/modules/module.pdb
-?gcc:usr/bin/?libsome-0.dll
-?gcc:usr/lib/libsome.dll.a
-?gcc:usr/bin/?libnoversion.dll
-?gcc:usr/lib/libnoversion.dll.a
-?gcc:usr/bin/?libonlyversion-1.dll
-?gcc:usr/lib/libonlyversion.dll.a
-?gcc:usr/bin/?libonlysoversion-5.dll
-?gcc:usr/lib/libonlysoversion.dll.a
-?gcc:usr/libexec/?libcustomdir.dll
-?gcc:usr/libexec/libcustomdir.dll.a
-?gcc:usr/lib/modules/?libmodule.dll
-?gcc:usr/lib/modules/libmodule.dll.a
diff --git a/test cases/windows/7 dll versioning/test.json b/test cases/windows/7 dll versioning/test.json
new file mode 100644
index 0000000..1402925
--- /dev/null
+++ b/test cases/windows/7 dll versioning/test.json
@@ -0,0 +1,34 @@
+{
+ "installed": [
+ {"type": "file", "platform": "msvc", "file": "usr/bin/some-0.dll"},
+ {"type": "pdb", "file": "usr/bin/some-0"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/some.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/noversion.dll"},
+ {"type": "pdb", "file": "usr/bin/noversion"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/noversion.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/onlyversion-1.dll"},
+ {"type": "pdb", "file": "usr/bin/onlyversion-1"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/onlyversion.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/bin/onlysoversion-5.dll"},
+ {"type": "pdb", "file": "usr/bin/onlysoversion-5"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/onlysoversion.lib"},
+ {"type": "file", "platform": "msvc", "file": "usr/libexec/customdir.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/libexec/customdir.lib"},
+ {"type": "pdb", "file": "usr/libexec/customdir"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/modules/module.dll"},
+ {"type": "file", "platform": "msvc", "file": "usr/lib/modules/module.lib"},
+ {"type": "pdb", "file": "usr/lib/modules/module"},
+ {"type": "expr", "platform": "gcc", "file": "usr/bin/?libsome-0.dll"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libsome.dll.a"},
+ {"type": "expr", "platform": "gcc", "file": "usr/bin/?libnoversion.dll"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libnoversion.dll.a"},
+ {"type": "expr", "platform": "gcc", "file": "usr/bin/?libonlyversion-1.dll"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libonlyversion.dll.a"},
+ {"type": "expr", "platform": "gcc", "file": "usr/bin/?libonlysoversion-5.dll"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/libonlysoversion.dll.a"},
+ {"type": "expr", "platform": "gcc", "file": "usr/libexec/?libcustomdir.dll"},
+ {"type": "file", "platform": "gcc", "file": "usr/libexec/libcustomdir.dll.a"},
+ {"type": "expr", "platform": "gcc", "file": "usr/lib/modules/?libmodule.dll"},
+ {"type": "file", "platform": "gcc", "file": "usr/lib/modules/libmodule.dll.a"}
+ ]
+}