The T2C ReqMarkup plugin uses Ctrl+R as a default keyboard shortcut to bring up the "Requirement properties" dialog. However, this shortcut is already assigned to "filerevert" command in KompoZer 0.7.7. You could use Alt+R instead or circumvent this problem by changing a shortcut for "filerevert". In the latter case you can do the following:
To install the T2C ReqMarkup plugin on KompoZer:
Sometimes it can be convenient not to link the requirements for properties and signals of gobject-based objects to the interfaces which behaviour they affect. (In fact the problem is that it is often difficult to determine which interfaces are affected by the requirements for a given property or a signal.)
For simplicity we can assign IDs for these requirements using almost the same rules as for the functions. Name of the property or signal should be used in the ID instead of the function name and dashes ('-') should be replaced with underscores ('_').
It is recommended to prefix the name of the property (or signal) with a name of the class this property (or signal) belongs to. This can help to avoid ID conflicts if there are properties or signals with the same names in different classes.
The name of the class should be written in lowercase with underscores separating the words.
If a fragment of the documentation contains a requirement for many interfaces, it can be difficult to specify all respective IDs in the list correctly. For instance, the following ID list could be used for one of the fragments of the description of printf():
"asprintf.13.02;fprintf.13.02;printf.13.02;snprintf.13.02;sprintf.13.02;vasprintf.13.02;vdprintf.13.02;vfprintf.13.02;vprintf.13.02;vsnprintf.13.02;vsprintf.13.02"Imagine you need to write such a list for each requirement trying not to forget to change the indexes appropriately. It can be a really hard time.
There is a way to handle this. We can create a so called "define"-block; (or "substitution block"): denote the whole list of functions (sprintf, fprintf, printf, snprintf, sprintf, vasprintf, vdprintf, vfprintf, vprintf, vsnprintf, vsprintf) with a single identifier, say, @print_funcs. (It begins with '@' to distinguish it from function names. This is not mandatory though.) Its definition should be placed in the html we are marking up and it looks like this:
<a class="define" name="@print_funcs" title="asprintf; sprintf; fprintf; printf; snprintf; vasprintf; vdprintf; vfprintf; vprintf; vsnprintf; vsprintf"></a>.
Now instead of that long list we can write just this: "@print_funcs.13.02".
If a "define"-block is placed in the html file manually, it is recommended that it is done at the beginning of the body of this html. However, ReqMarkup provides probably more convenient means to create, remove and modify such blocks (see the example in the tutorial). Using ReqMarkup to manage "define"-blocks has another advantage: creation, removal and modification of "define"-blocks can be undone / redone like almost any other editing operation.
The prefixes ("app", "ext" etc.) work properly with the subsitutions. That is, the followng "ID lists" are allowed:
"ext.@print_funcs.10"
"app.@print_funcs.15".
A substitution identifier should consist of letters, may contain digits, '_' and '@'. Other symbols are not allowed. The identifier is case sensitive.
The substitution ID may be an element of another ID list like any ordinary ID. Moreover, it is possible to use substitutions in a definition of another substitution.
Example: <a class="define" name="ALL_PRINT_FUNCS" title="f_PRINT_FUNCS; @_PRINT_FUNCS; s_PRINT_FUNCS"></a>,
f_PRINT_FUNCS, @_PRINT_FUNCS, s_PRINT_FUNCS are defined somewhere else in this html (no matter before or later).
Please make sure you do not create recursion here.
Sometimes it can be convenient not to use a "define"-block but rather specify the substitution directly. Let us consider the following list of IDs: "do_get_long.01;do_get_ulong.01;do_get_uint.01"
We could create a "define"-block named, say, "@VALUE_TYPE" which value is "long; ulong; uint" and then use "do_get_@VALUE_TYPE.01"
instead of the list of IDs. But it could be clearer if we used "do_get_[long; ulong; uint].01"
instead. Fortunately, unnamed substitutions like the one in the latter case are allowed by ReqMarkup and ReqTools. The list of values to be placed in the ID is specified in square brackets, the values being separated by semicolons. Spaces right before and after a semicolon are ignored.
The root of this directory structure is assumed to be specified in the T2C_SUITE_ROOT environment variable.
The subdirectories of src (denoted below as <s1> and <s2>) are just used to group the T2C files. Often there is only one subdirectory in src that contains all the T2C files.
T2C_SUITE_ROOT | +-- <main_suite_name>-t2c/ // the test suite | +-- <subsystem>-t2c/ // a "subsuite" containing tests for a given library (like glib, fontconfig, …) | +-- include/ // common include files for the tests for this subsystem +-- reqs/ // requirement catalog | | | +-- <group1>.xml | +-- <group2>.xml | +-- <group3>.xml | … … +-- src/ // T2C files | | | +-- <s1>/ // This directory contains a group of T2C files | | | | | +-- <group1>.t2c | | +-- <group2>.t2c | | | +-- <s2>/ | | | | … … +-- scenarios/ // TET scenarios | | | +-- func_scen | +-- tests/ // Generated C-files are placed here | | | +-- <group1>/ | | | | | +-- <group1>.c | | | +-- <group2>/ | | | | | +-- <group2>.c | … +-- testdata/ // Data used by the tests should be stored here | | | +-- testdata_src/ // Contains a makefile and source code | | // of the test data that needs to be built (modules, etc.) | +-- <group1>/ | | | | | … | +-- <group2>/ | | | | | … | … …
t2c <main_dir> <test_dir> [cfg_path]
The paths are relative to the directory specified in $T2C_SUITE_ROOT environment variable.
main_dir -
main directory for the test suites (<main_suite_name>-t2c directory in a structure shown in the note above). The subdirectories of <main_dir> contain the test "subsuites" for the particular subsystems to be tested.
It is often the same directory as specified in the T2C_SUITE_ROOT environment variable, so "." is often used as <main_dir>.
Main TET scenario file (tet_scen) resides in this directory. If this file does not exist when the code generator is invoked, it will be created. Otherwise an appropriate record will be added to the existing file.
tetexec.cfg should also reside in this directory. (This file is not generated automatically in this T2C vesion.)
test_dir -
path to the directory of a test suite to be generated.
Example: sample-01-t2c.
The C-code generator looks for the t2c files in the src subdir of this directory. The generated C files will be placed in the tests subdir, local scenario file(s) - in scenarios. For the above example these directories are the following (assume $T2C_SUITE_ROOT is samples/): sample-01-t2c/src, sample-01-t2c/tests, sample-01-t2c/scenarios.
cfg_path -
(optional) path to the configuration file of the generator. If this path is not specified, default configuration will be used.
$T2C_ROOT/t2c/bin/t2c . sample-01-t2c sample-01-t2c/sample-01.cfg
The parameters can be specified in a configuration file of the code generator as follows:
<NAME>=<value>COMPILER=lsbcc COMPILER_FLAGS=`pkg-config --cflags glib-2.0` -DCHECK_EXT_REQS LINKER_FLAGS=`pkg-config --libs glib-2.0` TET_SCEN_RECORD=no WAIT_TIME=180
The parameters can be listed in any order, one per line. The empty lines are ignored.
COMPILER - the compiler to be used to build the generated tests. The value of this parameter (as well as COMPILER_FLAGS and LINKER_FLAGS) goes to the common test makefile, common.mk.
COMPILER_FLAGS and LINKER_FLAGS - additional compiler and linker options required to build the tests. These flags will be copied to the makefiles of these tests.
The contents of "$T2C_SUITE_ROOT/cc_special_flags" (if this file exists) will also be loaded as the additional compiler flags in the generated makefiles. The file usually contains the version-specific compiler flags (e.g., -fno-stack-protector for gcc 4.1.0 and newer.). This file is often absent or is empty. You should only fill it when you really have to.
TET_SCEN_RECORD - if the value of this parameter is 'yes' (or 'YES'), the generator will add a proper record in the main TET scenario file (tet_scen) after the code of the test is created. This record may look like this:
:include:/sample-t2c/scenarios/func_scen
If this parameter has any other value (e.g. 'no'), no record is added in tet_scen.
WAIT_TIME - if positive, specifies how long (in seconds) any single test purpose is allowed to run. If this amount of time expires, the test purpose is terminated and its result code is set to "TIME EXPIRED" (numeric value: 65).
If this parameter has zero or negative value, there will be no restrictions on test purpose execution time.
Default value: 30.
It is highly recommended that a reasonable positive value is specified for WAIT_TIME. This ensures that the test suite execution will be finished even if some of the tests hang.
You should probably set WAIT_TIME to 0 to debug a standalone version of a test.
One often needs to use external data to check some of the requirements. For example, the test will probably have to load data from a file.
It is recommended to place the data necessary for the tests in the subdirectories of the testdata directory for the test suite. These subdirectories should have the same names as the corresponding t2c files. So the tests from a t2c file will look for their data in a separate directory.
To obtain the path to these data from the test code, one can use the T2C_GET_DATA_PATH(rel_path)
macro.
Suppose we need to get the path to the file myfile.txt from the test which source is in glib_key_parser.t2c. Let gkp-t2c to be the path to the test suite subdirectory (relative to $T2C_SUITE_ROOT), T2C_SUITE_ROOT = /tmp/test.
In this case T2C_GET_DATA_PATH("myfile.txt")
will return "/tmp/test/gkp-t2c/testdata/glib_key_parser/myfile.txt"
.
The returned pointer to the string should be freed when it is no longer needed.
Example (from samples/sample-02-t2c/include/AtkStreamableContent/AtkStreamableContent.h)
GError *error = NULL; char* full_filename = T2C_GET_DATA_PATH(file_names[i]); GIOChannel* channel = g_io_channel_new_file(full_filename, "r", &error); if(error != NULL) { … } free(full_filename); return channel;
Recall that the t2c-sources of the tests reside in samples/sample-02-t2c/src while the generated C sources will be placed in samples/sample-02-t2c/tests. Suppose we need to write some header files for these tests. The question is where we should place these headers. The common include directory is provided exactly for this purpose.
The 2nd example (sample-02-t2c) demonstrates how this directory can be used. $T2C_SUITE_ROOT/sample-02-t2c/include is automatically specified in -I compiler option in a make file created by the T2C code generator. So when we need to include the headers it contains, we just write :
#include <AtkStreamableContent/MyAtkStreamableContent.h> #include <useful_functions.h>
(See samples/sample-02-t2c/src/AtkStreamableContent/AtkStreamableContent.t2c.)
For each subsystem to be tested, T2C generates not only required C sources but also makefiles. Among these is common.mk that can be found in $T2C_SUITE_ROOT/<test_dir>/tests/<test_name>/. (This .mk-file contains common definitions for building the tests and it is included in the makefiles for each test. The latter makefiles contain targets to build the test for execution under TET ("all") and for standalone execution and debugging ("debug").
To build a standalone version of the test, you can do the following.
Make sure the 'T2C_SUITE_ROOT' environment variable is properly defined, T2C is built and C source for the .t2c-file of interest has already been generated.
cd $T2C_SUITE_ROOT/desktop-t2c/gmodule-t2c/tests/gmodule
Type "make clean" and then "make debug" in the command line. This will build the standalone version of the test.
During the build process the compiler will use the tet_api.h file we provide (it can be found in $T2C_ROOT/t2c/debug/include) instead of the one from TET. The object file for the test will be linked with dbgm.o and t2c_util_d.a from $T2C_ROOT/t2c/debug/lib instead of tcm.o and t2c_util.a. If you want, for example, to debug the test in an Eclipse project, you should specify this #include path and these linker input files in the build settings of the project.
Only a subset of TET API is supported in the debug components. Avoid using TET API directly from the t2c-file. Instead use special macros defined by T2C (REQ(), TRACE(), ABORT_TEST_PURPOSE() etc).
Now the test can be executed../<testname> [-v] [IC_number]
-v
If this option is specified, the test will be executed in a verbose mode.
Note that value of the TET variable named "VERBOSE" has no effect on the standalone test execution. TET settings have nothing to do with this, anyway.
IC_number
It is a number of the invocable component to execute. Each TET compliant test contains at least one invocable component (IC). (The number of the IC is specified as the 2nd field of the tet_testlist structure.) Each invocable component consists of one or more test purposes.
In the C source of the test each element of the tet_testlist array is a pair of the test purpose name and the IC number. See TET documentation for details.
If 'IC_number' is not specified, all invocable components will be executed.
Typically, there shall be only one test purpose for any invocable component generated by T2C. So IC number will be unique for each test purpose in the C file. You may change IC numbers in the tet_testlist array as you like. You can, for example, give several test purposes the same IC number, say, 999. Then execute
./<testname> 999
All these test purposes will be executed.
Do not change test purpose names listed in this array.
There is no TET journal for standalone test execution. All messages from the test go to stderr if the verbose mode is on or to nowhere if it is off. tet_printf() does nothing in both these cases, you should use TRACE() and TRACE0() instead.
Examples:./gmodule(Runs all the invocable components defined in this executable. Verbose mode is off.)
./FcCharSet -v 17
(Turns verbose mode on and runs all the test purposes in the invocable component number 17.)
To run the test under TET again, just rebuild this test:make clean make
Note that all the test purposes of a standalone test are executed in the same process to simplify debugging (some debuggers may not handle fork() calls properly by default).
WAIT_TIME configuration parameter has no effect on the standalone tests. They will not be interrupted, no matter how long they run. Otherwise they could be stopped in the middle of the debugging process (because their time had expired) which is probably not what you want.