├── .gitattributes
├── .github
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── discussion.md
│ ├── feature_request.md
│ └── question.md
├── PULL_REQUEST_TEMPLATE.md
├── assets
│ └── example_output.png
└── workflows
│ └── codeql-analysis.yml
├── .gitignore
├── CMakeLists.txt
├── LICENSE.md
├── README.md
├── build.sh
├── doc
└── asserts.md
└── eztest
├── eztest.h
└── runner.c
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Forces header files to be classified as C rathern than C++
2 | eztest/*.h linguist-language=C
3 |
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * Unwelcome sexual attention or advances
26 | * Trolling, insulting/derogatory comments, and personal or political attacks
27 | * Public or private harassment
28 | * Publishing others' private information, such as a physical or electronic
29 | address, without explicit permission
30 | * Other conduct which could reasonably be considered inappropriate in a
31 | professional setting
32 |
33 | ## Our Responsibilities
34 |
35 | Project maintainers are responsible for clarifying the standards of acceptable
36 | behavior and are expected to take appropriate and fair corrective action in
37 | response to any instances of unacceptable behavior.
38 |
39 | Project maintainers have the right and responsibility to remove, edit, or
40 | reject comments, commits, code, wiki edits, issues, and other contributions
41 | that are not aligned to this Code of Conduct, or to ban temporarily or
42 | permanently any contributor for other behaviors that they deem inappropriate,
43 | threatening, offensive, or harmful.
44 |
45 | ## Scope
46 |
47 | This Code of Conduct applies both within project spaces and in public spaces
48 | when an individual is representing the project or its community. Examples of
49 | representing a project or community include using an official project e-mail
50 | address, posting via an official social media account, or acting as an appointed
51 | representative at an online or offline event. Representation of a project may be
52 | further defined and clarified by project maintainers.
53 |
54 | ## Enforcement
55 |
56 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
57 | reported by contacting the project team using the Security Advisories section on Github. All
58 | complaints will be reviewed and investigated and will result in a response that
59 | is deemed necessary and appropriate to the circumstances. The project team is
60 | obligated to maintain confidentiality with regard to the reporter of an incident.
61 | Further details of specific enforcement policies may be posted separately.
62 |
63 | Project maintainers who do not follow or enforce the Code of Conduct in good
64 | faith may face temporary or permanent repercussions as determined by other
65 | members of the project's leadership.
66 |
67 | ## Attribution
68 |
69 | This Code of Conduct is based on the Contributor Covenant, version 1.4,
70 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
71 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to EzTest
2 | :balloon: Thank you for your interest in contributing to EzTest! :balloon:
3 |
4 | We welcome all contributions and hope you will do your best to follow the given guidelines in order to smooth the development process.
5 |
6 | ## How to contribute
7 |
8 | ### Report a bug | Suggest bug fix
9 |
10 | Please create an issue marked with the bug label. When writing the issue please attempt to follow the issue template for bugs.
11 |
12 | ##### Know of a fix?
13 |
14 | If you have a fix for the bug please create a pull requests. Make sure to fully describe the issue along with how your solution fixes the problem.
15 |
16 | ### New feature
17 |
18 | Suggest a new feature by creating an issue marked with the new feature label.
19 |
20 | ##### Developing a feature
21 |
22 | If you have developed a new feature please make sure you have followed the style guides by doing a self review.
23 | All new features should be developed in response to an issue. A common process would then be to create an issue marked with the
24 | new feature or enhancement label, develop the feature and then create a pull-request.
25 |
26 | ## Development guidelines
27 |
28 | #### Git commit messages
29 |
30 | Each git commit should be accompanied by a message giving a clear indication of what has been changed.
31 | If the commit is in response to an issue, make sure to reference the issue in the commit message.
32 |
33 |
34 | #### Code
35 |
36 | - Indentation and brackets follow [Allman style](https://en.wikipedia.org/wiki/Indentation_style#Allman_style)
37 | - Indentation should be 4 spaces
38 | - Code documentation should follow "JavaDoc style"
39 | Example:
40 | ```
41 | /**
42 | *
43 | * @param
44 | * @see
45 | * @return
46 | */
47 | ```
48 |
49 | #### Integration
50 |
51 | To smooth integration, it is recommended that you develop on a branch specific for your feature. Once you have completed the feature please create a pull-request to get the code reviewed and merged.
52 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: "[BUG]"
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Use parameter..
16 | 2. Call method..
17 | etc.
18 |
19 | **Expected behavior**
20 | A clear and concise description of what you expected to happen.
21 |
22 | **Screenshots**
23 | If applicable, add screenshots to help explain your problem.
24 |
25 | **Additional context**
26 | Add any other context about the problem here.
27 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/discussion.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Discussion
3 | about: 'Open a dialog into any project related subjects. '
4 | title: "[DISCUSSION]"
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: "[FEATURE REQUEST]"
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Question
3 | about: Questions & help
4 | title: "[QUESTION]"
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | # [TITLE]
11 | Add further details and code to help us better understand your question.
12 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
4 |
5 | Fixes # (issue)
6 |
7 | ## Type of change
8 |
9 | - [ ] Bug fix (non-breaking change which fixes an issue)
10 | - [ ] New feature (non-breaking change which adds functionality)
11 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
12 |
13 | # How Has This Been Tested?
14 |
15 | Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
16 |
17 | # Checklist:
18 |
19 | - [ ] I have performed a self-review of my own code
20 | - [ ] I have commented my code, particularly in hard-to-understand areas
21 | - [ ] My changes generate no new warnings
22 | - [ ] I have added tests that prove my fix is effective or that my feature works
23 |
--------------------------------------------------------------------------------
/.github/assets/example_output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/havardt/EzTest/9ebdcf3db330c8a6d2f3b1d06fae2ce5d42de773/.github/assets/example_output.png
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ master ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ master ]
20 | schedule:
21 | - cron: '19 17 * * 4'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'cpp' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support
38 |
39 | steps:
40 | - name: Checkout repository
41 | uses: actions/checkout@v3
42 |
43 | # Initializes the CodeQL tools for scanning.
44 | - name: Initialize CodeQL
45 | uses: github/codeql-action/init@v2
46 | with:
47 | languages: ${{ matrix.language }}
48 | # If you wish to specify custom queries, you can do so here or in a config file.
49 | # By default, queries listed here will override any specified in a config file.
50 | # Prefix the list here with "+" to use these queries and those in the config file.
51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
52 |
53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
54 | # If this step fails, then you should remove it and run the build manually (see below)
55 | - name: Autobuild
56 | uses: github/codeql-action/autobuild@v2
57 |
58 | # ℹ️ Command-line programs to run using the OS shell.
59 | # 📚 https://git.io/JvXDl
60 |
61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
62 | # and modify them (or add more) to build your code if your project
63 | # uses a compiled language
64 |
65 | #- run: |
66 | # make bootstrap
67 | # make release
68 |
69 | - name: Perform CodeQL Analysis
70 | uses: github/codeql-action/analyze@v2
71 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | *.obj
3 | *.exe
4 | *.out
5 | out/
6 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 2.8)
2 |
3 | project (eztest)
4 |
5 | set (CMAKE_C_STANDARD 11)
6 |
7 | set (eztest_VERSION_MAJOR 3)
8 | set (eztest_VERSION_MINOR 0)
9 | set (eztest_VERSION_PATCH 0)
10 |
11 | if (CMAKE_COMPILER_IS_GNUCC)
12 | set(CMAKE_C_FLAGS "-Wall")
13 | set(CMAKE_C_FLAGS_DEBUG "-g")
14 | set(CMAKE_C_FLAGS_RELEASE "-O3")
15 | endif()
16 |
17 | add_executable(eztest eztest/runner.c eztest/eztest.h)
18 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 havardt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
EzTest
2 |
3 |
4 |
5 | [](https://github.com/havardt/EzTest/releases)
6 | [](https://opensource.org/licenses/MIT)
7 |
8 |
9 |
10 | An easy to use unit testing framework written in, and created for, the C language.
11 |
12 |
13 |

14 |
15 |
16 |
17 |
18 | ## Table of contents
19 | * [Introduction](#introduction)
20 | * [Getting started](#getting-started)
21 | * [Asserts](#asserts)
22 | * [Runner](#runner)
23 | * [How to contribute](#contribute)
24 | * [License info](#license)
25 |
26 | ## Introduction
27 |
28 |
29 | ###### A simple test
30 |
31 | ```C
32 | TEST(Math, AddingTwoOnTwoShouldEqualFour)
33 | {
34 | const int expected = 4;
35 | const int actual = math_add(2, 2);
36 |
37 | ASSERT_ARE_EQUAL(expected, actual); // or ASSERT_EQ(expected, actual); using the shorthand.
38 | }
39 | ```
40 | The [asserts](#asserts) are created using the power of the C11 macro ```_Generic```. As seen in the above example, this means that the user doesn't have to provide any prefix or suffix to represent the data type.
41 |
42 | ###### A full test (Setup and Teardown)
43 | EzTest also provides the option of setup and teardown functions. The setup function is a function that runs before every test within a test suite. The teardown function has similar behaviour, but runs after the test. A test utilizing setup and teardown functions is defined by using the ```TEST_FULL(suite, name)``` macro. A setup and teardown function *must* also be defined for the test suite when using the full test macro. This is done with the ```SETUP(suite)``` and ```TEARDOWN(suite)``` macros.
44 |
45 | ```C
46 |
47 | SETUP(Math)
48 | {
49 | // Code to run before every test in the Math suite.
50 | }
51 |
52 | TEST_FULL(Math, AddingTwoOnTwoShouldEqualFour)
53 | {
54 | // Test code placed here.
55 | }
56 |
57 | TEARDOWN(Math)
58 | {
59 | // This code runs after every test in the Math suite.
60 | }
61 |
62 | ```
63 |
64 | See the next section for information on how to get started with EzTest.
65 |
66 | ## Getting started
67 | EzTest was created to make unit testing quick and easy in C. The fastest way to get started with EzTest is by using the [template](https://github.com/havardt/EzTest-Template). The template provides a default project layout for C projects using EzTest. After getting the template or creating your own project structure, you are ready to start.
68 |
69 | #### 1. Write tests using the test macros
70 | Before having access to the test macros you need to include the eztest header file: ```#include "eztest.h"```.
71 | There are two macros for creating tests: ```TEST(suite, test)``` and ```TEST_FULL(suite, test)```.
72 | The first is for simple unit tests while the second is for tests with a setup and teardown function. Both of these macros take the same arguments.
73 |
74 | ###### Argument 1: Suite
75 | This is the name of the test suite that the test will be associated with. The name must follow the rules for variable names in C and must be unique through out your tests. The suite name can be used to group multiple tests providing a better overview for the tester.
76 |
77 | ###### Argument 2: Test
78 | This is the name of the test. The name must follow the rules for variable names in C and must be unique within the test suite.
79 |
80 | Example usage of both ```TEST(suite, test)``` and ```TEST_FULL(suite, test)``` can be found in the [usage section](#usage).
81 |
82 |
83 | #### 2. Build/ Compile
84 |
85 | ###### Option I: CMake/Template
86 | The perhaps simplest way to build your tests is to use CMake. If you are using CMake and/or the template, then follow the build instructions given [here](https://github.com/havardt/EzTest-Template#hammer_and_wrench-build).
87 |
88 | ###### Option II: Manual build
89 | To build the EzTest runner, compile using a C11 compatible C compiler by providing the ```runner.c``` source file along with your test files.
90 | Example compile: ```$ gcc -o ezrunner runner.c ```
91 |
92 |
93 | #### 3. Run
94 | Run the executable to run your tests. The test runner can take multiple optional arguments to customize your test experience. Learn more about the test runner [here](#runner).
95 |
96 | ## Asserts
97 |
98 | | Macro | Shorthand | Description | Details |
99 | | --- | --- | --- | --- |
100 | | ``` ASSERT_IS_NULL ``` | | Tests whether the provided pointer is null. | [Documentation](doc/asserts.md#Assert-NULL) |
101 | | ``` ASSERT_IS_NOT_NULL ``` | | Tests whether the provided pointer is non-null. | [Documentation](doc/asserts.md#Assert-not-NULL) |
102 | | ``` ASSERT_IS_TRUE ``` | | Tests whether the condition is true. | [Documentation](doc/asserts.md#Assert-true) |
103 | | ``` ASSERT_IS_FALSE ``` | | Tests whether the condition is false. | [Documentation](doc/asserts.md#Assert-false) |
104 | | ``` ASSERT_ARE_SAME ``` | | Tests whether the two pointers refer to the same memory location. | [Documentation](doc/asserts.md#Assert-same) |
105 | | ``` ASSERT_ARE_NOT_SAME ``` | | Tests whether the two pointers refer to different memory locations. | [Documentation](doc/asserts.md#Assert-not-same) |
106 | | ``` ASSERT_IS_NAN ``` | | Tests whether the provided float is NaN. | [Documentation](doc/asserts.md#Assert-NaN) |
107 | | ``` ASSERT_ARE_EQUAL ``` | ``` ASSERT_EQ ``` | Tests whether the two values are equal. | [Documentation](doc/asserts.md#Assert-equal) |
108 | | ``` ASSERT_ARE_EQUAL_PRECISION ``` | ```ASSERT_EQ_PRECISION```| Tests whether two floating point numbers are equal using a user provided epsilon. | [Documentation](doc/asserts.md#Assert-equal-precision) |
109 | | ``` ASSERT_ARE_EQUAL_MEM ``` | ``` ASSERT_EQ_MEM ``` | Tests whether the two values are equal by comparing each byte at the given memory locations. | [Documentation](doc/asserts.md#Assert-equal-memory) |
110 | | ``` ASSERT_ARE_EQUAL_CMP ``` | ``` ASSERT_EQ_CMP ``` | Tests whether the two values are equal by using the passed comparator function. | [Documentation](doc/asserts.md#Assert-equal-cmp) |
111 | | ``` ASSERT_ARE_NOT_EQUAL ``` |``` ASSERT_NE ``` | Tests whether the two values are different. | [Documentation](doc/asserts.md#Assert-not-equal) |
112 | | ``` ASSERT_ARE_NOT_EQUAL_PRECISION ``` | ```ASSERT_NE_PRECISION``` | Tests whether two floating point numbers are different using a user provided epsilon. | [Documentation](doc/asserts.md#Assert-not-equal-precision) |
113 | | ``` ASSERT_ARE_NOT_EQUAL_MEM ``` | ```ASSERT_NE_MEM``` | Tests whether the two values are different by comparing each byte at the given memory locations. | [Documentation](doc/asserts.md#Assert-not-equal-mem) |
114 | | ``` ASSERT_ARE_NOT_EQUAL_CMP ``` | ``` ASSERT_NE_CMP ``` | Tests whether the two values are different by using the passed comparator function. | [Documentation](doc/asserts.md#Assert-not-equal-cmp) |
115 | | ``` ASSERT_GREATER ``` | ``` ASSERT_GT ``` | Tests whether the first value is greater than the second value. |
116 | | ``` ASSERT_GREATER_PRECISION ``` | ``` ASSERT_GT_PRECISION ``` | Tests whether the first floating point value is greater than the second floating point value using a user provided epsilon. |
117 | | ``` ASSERT_GREATER_MEM ``` | ```ASSERT_GT_MEM``` | Tests whether the first n bytes at the first memory location is greater than the n first bytes at the second memory location. |
118 | | ``` ASSERT_GREATER_CMP ``` | ``` ASSERT_GT_CMP ``` | Tests whether the first value is greater than the second value by using the passed comparator function. |
119 | | ``` ASSERT_GREATER_EQUAL ``` | ```ASSERT_GE``` | Tests whether the first value is greater than or equal to the second value. |
120 | | ``` ASSERT_GREATER_EQUAL_PRECISION ``` | ```ASSERT_GE_PRECISION``` | Tests whether the first floating point value is greater than or equal to the second floating point value using a user provided epsilon. |
121 | | ``` ASSERT_GREATER_EQUAL_MEM ``` | ```ASSERT_GE_MEM``` | Tests whether the first n bytes at the first memory location is greater than or equal to the n first bytes at the second memory location. |
122 | | ``` ASSERT_GREATER_EQUAL_CMP ``` | ``` ASSERT_GE_CMP ``` | Tests whether the first value is greater than or equal to the second value by using the passed comparator function. |
123 | | ``` ASSERT_LESS ``` | ``` ASSERT_LT ``` | Tests whether the first value is lesser than the second value. |
124 | | ``` ASSERT_LESS_PRECISION ``` | ``` ASSERT_LT_PRECISION ``` | Tests whether the first floating point value is lesser than the second floating point value using a user provided epsilon. |
125 | | ``` ASSERT_LESS_MEM ``` | ```ASSERT_LT_MEM``` | Tests whether the first n bytes at the first memory location is lesser than the n first bytes at the second memory location. |
126 | | ``` ASSERT_LESS_CMP ``` | ``` ASSERT_LT_CMP ``` | Tests whether the first value is lesser than the second value by using the passed comparator function. |
127 | | ``` ASSERT_LESS_EQUAL ``` | ``` ASSERT_LE ``` | Tests whether the first value is lesser than or equal to the second value. |
128 | | ``` ASSERT_LESS_EQUAL_PRECISION ``` | ``` ASSERT_LE_PRECISION ``` | Tests whether the first floating point value is lesser than or equal to the second floating point value using a user provided epsilon. |
129 | | ``` ASSERT_LESS_EQUAL_MEM ``` | ```ASSERT_LE_MEM``` | Tests whether the first n bytes at the first memory location is lesser than or equal to the n first bytes at the second memory location. |
130 | | ``` ASSERT_LESS_EQUAL_CMP ``` | ``` ASSERT_LE_CMP ``` | Tests whether the first value is lesser than or equal to the second value by using the passed comparator function. |
131 |
132 | ## Runner
133 | The runner is the program that executes the tests.
134 |
135 | #### Exit code
136 | The exit code is EXIT_SUCCESS (0) if all tests passed and EXIT_FAILURE (non-zero) if one or more tests failed.
137 |
138 | #### Options
139 | | Short | Long | Description |
140 | | --- | --- | --- |
141 | | -v | --version | Prints the version number. |
142 | | -h | --help | Prints help/ usage information. |
143 | | -c | --no-color | Don't use any color when printing. |
144 | | -t | --timer | Display execution time for each test. |
145 | | -q | --quiet | No output. |
146 | | -s | --skip | Skips all tests in the passed list of test suits. The argument for this option should be a comma separated list of case-sensitive test suit names that you want to skip. |
147 | | -f | --SIGSEGV | Segmentation fault is handled like other test failures. |
148 |
149 |
150 | ## Contribute
151 | We welcome all contributions, please see the [contribution guidelines](.github/CONTRIBUTING.md).
152 |
153 | ## License
154 |
155 | This project is licensed under the MIT License - see [LICENSE.md](LICENSE.md) for details.
156 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | ###############################################
4 | # Convenience script for building with CMake. #
5 | ###############################################
6 |
7 | # Make sure we are in the correct directory.
8 | cd $(dirname "$0")
9 |
10 | # Output diractory name / location
11 | OUTPUT="out"
12 |
13 | # Create output directory if it doesn't exist
14 | if [ ! -d $OUTPUT ]
15 | then
16 | mkdir $OUTPUT
17 | fi
18 |
19 | # Enter output directory
20 | cd $OUTPUT
21 |
22 | # CMake
23 | cmake ..
24 |
25 | # Stopping if CMake fails.
26 | if [ $? -ne 0 ]; then
27 | echo "CMake failed, stopping build."
28 | exit 1
29 | fi
30 |
31 | # Make
32 | make
33 |
34 | # Stopping if Make fails.
35 | if [ $? -ne 0 ]; then
36 | echo "Make failed, stopping build."
37 | exit 1
38 | fi
39 |
40 |
--------------------------------------------------------------------------------
/doc/asserts.md:
--------------------------------------------------------------------------------
1 | # EzTest documentation - asserts
2 | Each assert is a macro prefixed with ```ASSERT_```. Some of the macros also have a short-hand version. The short-hand
3 | version has the same underlying functionality.
4 |
5 | ---
6 |
7 | ### Assert NULL
8 | Tests whether the provided pointer is ```NULL```. This test uses ```NULL``` as defined by ```stddef.h```.
9 |
10 | ##### Declaration
11 | ```C
12 | ASSERT_IS_NULL(const void *value);
13 | ```
14 | ##### Parameters
15 | value The pointer to test for NULL.
16 |
17 | ---
18 |
19 | ### Assert not NULL
20 | Tests whether the provided pointer is non-```NULL```. This test uses ```NULL``` as defined by ```stddef.h```.
21 |
22 | ##### Declaration
23 | ```C
24 | ASSERT_IS_NOT_NULL(const void *value);
25 | ```
26 | ##### Parameters
27 | value The pointer to test for NULL.
28 |
29 | ---
30 |
31 | ### Assert true
32 | Tests whether the passed condition is ```true```. This test uses the boolean definitions in ```stdbool.h```.
33 |
34 | ##### Declaration
35 | ```C
36 | ASSERT_IS_TRUE(const bool condition);
37 | ```
38 | ##### Parameters
39 | condition The boolean condition to test.
40 |
41 | ---
42 |
43 | ### Assert false
44 | Tests whether the passed condition is ```false```. This test uses the boolean definitions in ```stdbool.h```.
45 |
46 | ##### Declaration
47 | ```C
48 | ASSERT_IS_FALSE(const bool condition);
49 | ```
50 | ##### Parameters
51 | condition The boolean condition to test.
52 |
53 | ---
54 |
55 | ### Assert same
56 | Tests whether the two pointers refer to the same memory location.
57 |
58 | ##### Declaration
59 | ```C
60 | ASSERT_ARE_SAME(const void *expected, const void *actual);
61 | ```
62 | ##### Parameters
63 | expected This is the value the tests expects.
64 |
65 | actual This is the value produced by the code under test.
66 |
67 | ---
68 |
69 | ### Assert not same
70 | Tests whether the two pointers refer to different memory locations.
71 |
72 | ##### Declaration
73 | ```C
74 | ASSERT_ARE_NOT_SAME(const void *unexpected, const void *actual);
75 | ```
76 | ##### Parameters
77 | unexpected This is the value that should not occur.
78 |
79 | actual This is the value produced by the code under test.
80 |
81 | ---
82 |
83 | ### Assert NaN
84 | Tests whether the passed value is NaN.
85 |
86 | ##### Declaration
87 | ```C
88 | ASSERT_IS_NAN(float value);
89 | ```
90 | ##### Parameters
91 | value The floating point value to check.
92 |
93 | ---
94 |
95 | ### Assert equal
96 | Tests whether the two values are equal.
97 |
98 | > The equality function for floating point numbers uses the epsilon macro from ```float.h``` in its equality test. It is therefore often better to use [ASSERT EQUAL PRECISION](#assert-equal-precision) when comparing floating point numbers (allowing application specific epsilon).
99 |
100 | ##### Declaration
101 | ```C
102 | ASSERT_ARE_EQUAL(T expected, T actual);
103 |
104 | ASSERT_EQ(T expected, T actual);
105 | ```
106 | ##### Parameters
107 | expected This is the value that should occur.
108 |
109 | actual This is the value produced by the code under test.
110 |
111 | ---
112 |
113 | ### Assert equal precision
114 | Tests whether two floating point numbers are equal using a user provided epsilon.
115 |
116 | ##### Declaration
117 | ```C
118 | ASSERT_ARE_EQUAL_PRECISION(long double expected, long double actual, long double epsilon);
119 |
120 | ASSERT_EQ_PRECISION(long double expected, long double actual, long double epsilon);
121 | ```
122 | ##### Parameters
123 | expected This is the value that is expected to be generated by the code under test.
124 |
125 | actual This is the value generated by the code under test.
126 |
127 | epsilon A floating point representing the precision required when testing for equality.
128 |
129 | ---
130 |
131 | ### Assert equal memory
132 | Tests whether the two values are equal by comparing each byte at the given memory locations.
133 |
134 | ##### Declaration
135 | ```C
136 | ASSERT_EQUAL_MEM(const void *expected, const void *actual, size_t size);
137 |
138 | ASSERT_EQ_MEM(const void *expected, const void *actual, size_t size);
139 | ```
140 | ##### Parameters
141 |
142 | expected A pointer to the expected value.
143 |
144 | actual A pointer to the actual value.
145 |
146 | size The size of the passed types.
147 |
148 | ---
149 |
150 | ### Assert equal cmp
151 | Tests whether the two values are equal by using the passed comparator function.
152 |
153 | ##### Declaration
154 | ```C
155 | ASSERT_ARE_EQUAL_CMP(const void *expected,
156 | const void *actual,
157 | int(*cmp_fn)(const void *ptr1, const void *ptr2));
158 |
159 | ASSERT_ARE_EQ_CMP(const void *expected,
160 | const void *actual,
161 | int(*cmp_fn)(const void *ptr1, const void *ptr2));
162 | ```
163 | ##### Parameters
164 |
165 | expected A pointer to the expected value.
166 |
167 | actual A pointer to the actual value.
168 |
169 | cmp_fn The comparator to use. This should return a negative value if the first parameter is less than the second parameter, 0 (zero) if the values are equal and a positive value if the first value is greater than the second value.
170 |
171 | ---
172 |
173 | ### Assert not equal
174 | Tests whether the two values are different.
175 |
176 | > The equality function for floating point numbers uses the epsilon macro from ```float.h``` in its equality test. It is therefore often better to use [ASSERT NOT EQUAL PRECISION](#assert-not-equal-precision) when comparing floating point numbers (allowing application specific epsilon).
177 |
178 | ##### Declaration
179 | ```C
180 | ASSERT_ARE_NOT_EQUAL(T unexpected, T actual);
181 |
182 | ASSERT_NE(T unexpected, T actual);
183 | ```
184 | ##### Parameters
185 |
186 | unexpected This is the value that should not occur.
187 |
188 | actual This is the value produced by the code under test.
189 |
190 | ---
191 |
192 | ### Assert not equal precision
193 | Tests whether two floating point numbers are different using a user provided epsilon.
194 |
195 | ##### Declaration
196 | ```C
197 | ASSERT_ARE_NOT_EQUAL_PRECISION(long double unexpected, long double actual, long double epsilon);
198 |
199 | ASSERT_NE_PRECISION(T unexpected, T actual);
200 | ```
201 | ##### Parameters
202 |
203 | unexpected This is the value that should not occur.
204 |
205 | actual This is the value produced by the code under test.
206 |
207 | epsilon A floating point representing the precision required when testing for equality.
208 |
209 | ---
210 |
211 | ### Assert not equal mem
212 | Tests whether the two values are different by comparing each byte at the given memory locations.
213 |
214 | ##### Declaration
215 | ```C
216 | ASSERT_NOT_EQUAL_MEM(const void *unexpected, const void *actual, size_t size);
217 |
218 | ASSERT_NE_MEM(const void *unexpected, const void *actual, size_t size);
219 | ```
220 | ##### Parameters
221 |
222 | unexpected A pointer to the unexpected value.
223 |
224 | actual A pointer to the actual value.
225 |
226 | size The size of the passed types.
227 |
228 | ---
229 | ### Assert not equal cmp
230 | Tests whether the two values are different by using the passed comparator function.
231 |
232 | ##### Declaration
233 | ```C
234 | ASSERT_NOT_EQUAL_CMP(const void *unexpected,
235 | const void *actual,
236 | int(*cmp_fn)(const void *ptr1, const void *ptr2));
237 |
238 | ASSERT_NE_CMP(const void *unexpected,
239 | const void *actual,
240 | int(*cmp_fn)(const void *ptr1, const void *ptr2));
241 | ```
242 | ##### Parameters
243 |
244 | unexpected The first value to compare. This is the value that should not occur.
245 |
246 | actual The second value to compare. This is the value that is generated by the code under test.
247 |
248 | cmp_fn The comparator to use. This should return a negative value if the first parameter is less than the second parameter, 0 (zero) if the values are equal and a positive value if the first value is greater than the second value.
249 |
250 | ---
--------------------------------------------------------------------------------
/eztest/eztest.h:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * @author havardt
4 | *
5 | * @license MIT
6 | *
7 | */
8 |
9 | #ifndef EZTEST_H
10 | #define EZTEST_H
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | struct unit_test
18 | {
19 | char *test_name;
20 | char *test_suite;
21 | void (*setup_fn)();
22 | void (*teardown_fn)();
23 | void (*run_fn)();
24 |
25 | /** Marks each unit test: used for test discovery. */
26 | uint64_t marker;
27 | };
28 |
29 | /** Represents the standard ok/ success result value for non-pointer return types. */
30 | #define EZTEST_RESULT_OK 0
31 |
32 | /** Represents the standard error/ fail result value for non-pointer return types. */
33 | #define EZTEST_RESULT_ERR (-1)
34 |
35 | #define EZTEST_MARKER 4242424242424242
36 |
37 | /** The max amount of bytes to print when printing value without type. */
38 | #define EZTEST_MAX_PRINTABLE_LEN 16
39 |
40 | #define EZTEST_BASE_TEST_NAME "eztest_base_test"
41 |
42 | #define EZTEST_RUN_FN_NAME(suite, name) run_##suite##_##name
43 |
44 | #define EZTEST_SETUP_FN_NAME(suite) setup_##suite
45 |
46 | #define EZTEST_TEARDOWN_FN_NAME(suite) teardown_##suite
47 |
48 | #define EZTEST_STRUCT_NAME(suite, name) struct_##suite##_##name
49 |
50 | /**
51 | * Initializes the setup function for the given suite.
52 | *
53 | * @param suite The name of the test suite that this setup function belongs.
54 | * @note Each suite should only have one (1) setup function.
55 | */
56 | #define SETUP(suite) static void EZTEST_SETUP_FN_NAME(suite)(void)
57 |
58 | /**
59 | * Initializes the teardown function for the given suite.
60 | *
61 | * @param suite The name of the test suite that this teardown function belongs.
62 | * @note Each suite should only have one (1) teardown function.
63 | */
64 | #define TEARDOWN(suite) static void EZTEST_TEARDOWN_FN_NAME(suite)(void)
65 |
66 | #define EZTEST_UNIT_TEST_STRUCT(suite, name)\
67 | static struct unit_test EZTEST_STRUCT_NAME(suite, name) __attribute__ ((used, section(".eztest"), aligned(1))) = {\
68 | .test_name=#name,\
69 | .test_suite=#suite,\
70 | .setup_fn = NULL,\
71 | .teardown_fn = NULL,\
72 | .run_fn = EZTEST_RUN_FN_NAME(suite, name),\
73 | .marker = EZTEST_MARKER\
74 | }
75 |
76 | #define EZTEST_FULL_UNIT_TEST_STRUCT(suite, name)\
77 | static struct unit_test EZTEST_STRUCT_NAME(suite, name) __attribute__ ((used, section(".eztest"), aligned(1))) = {\
78 | .test_name=#name,\
79 | .test_suite=#suite,\
80 | .setup_fn = EZTEST_SETUP_FN_NAME(suite),\
81 | .teardown_fn = EZTEST_TEARDOWN_FN_NAME(suite),\
82 | .run_fn = EZTEST_RUN_FN_NAME(suite, name),\
83 | .marker = EZTEST_MARKER\
84 | }
85 |
86 | /**
87 | * Initialize a new unit test.
88 | *
89 | * @param suite The name of the test suite that this test belongs.
90 | * @param name The name of the test.
91 | * @note Suite and test-names must follow C naming rules.
92 | * Suite and test-name combination must be unique for the project.
93 | */
94 | #define TEST(suite, name)\
95 | static void EZTEST_RUN_FN_NAME(suite, name)(void);\
96 | EZTEST_UNIT_TEST_STRUCT(suite, name);\
97 | static void EZTEST_RUN_FN_NAME(suite, name)(void)
98 |
99 | /**
100 | * Initializes a new unit test with setup and teardown functions.
101 | *
102 | * @param suite The name of the test suite that this test belongs.
103 | * @param name The name of the test.
104 | * @note Suite and test-names must follow C naming rules.
105 | * Suite and test-name combination must be unique for the project.
106 | */
107 | #define TEST_FULL(suite, name)\
108 | static void EZTEST_RUN_FN_NAME(suite, name)(void);\
109 | EZTEST_FULL_UNIT_TEST_STRUCT(suite, name);\
110 | static void EZTEST_RUN_FN_NAME(suite, name)(void)
111 |
112 | void assert_is_null(const void *value, char *file, int line);
113 | #define ASSERT_IS_NULL(value) assert_is_null(value, __FILE__, __LINE__);
114 |
115 | void assert_is_not_null(const void *value, char *file, int line);
116 | #define ASSERT_IS_NOT_NULL(value) assert_is_not_null(value, __FILE__, __LINE__);
117 |
118 | void assert_is_true(bool condition, char *file, int line);
119 | #define ASSERT_IS_TRUE(condition) assert_is_true(condition, __FILE__, __LINE__);
120 |
121 | void assert_is_false(bool condition, char *file, int line);
122 | #define ASSERT_IS_FALSE(condition) assert_is_false(condition, __FILE__, __LINE__);
123 |
124 | void assert_are_same(const void *expected, const void *actual, char *file, int line);
125 | #define ASSERT_ARE_SAME(expected, actual) assert_are_same(expected, actual, __FILE__, __LINE__);
126 |
127 | void assert_are_not_same(const void *unexpected, const void *actual, char *file, int line);
128 | #define ASSERT_ARE_NOT_SAME(unexpected, actual) assert_are_not_same(unexpected, actual, __FILE__, __LINE__);
129 |
130 | #ifdef NAN
131 |
132 | void assert_is_nan(float value, char *file, int line);
133 | #define ASSERT_IS_NAN(value) assert_is_nan(value, __FILE__, __LINE__);
134 |
135 | #endif
136 |
137 | void assert_are_equal_ch (char expected, char actual, char *file, int line);
138 | void assert_are_equal_sch (signed char expected, signed char actual, char *file, int line);
139 | void assert_are_equal_uch (unsigned char expected, unsigned char actual, char *file, int line);
140 | void assert_are_equal_int (intmax_t expected, intmax_t actual, char *file, int line);
141 | void assert_are_equal_uint(uintmax_t expected, uintmax_t actual, char *file, int line);
142 | void assert_are_equal_dbl (long double expected, long double actual, char *file, int line);
143 | void assert_are_equal_str (const char * expected, const char * actual, char *file, int line);
144 | void assert_are_equal_wstr(const wchar_t * expected, const wchar_t * actual, char *file, int line);
145 | void assert_are_equal (const void * expected, const void * actual, char *file, int line);
146 | /**
147 | * Tests whether the two values are equal.
148 | *
149 | * @param expected The first value to compare. This is the value the tests expects.
150 | * @param actual The second value to compare. This is the value produced by the code under test.
151 | */
152 | #define ASSERT_ARE_EQUAL(expected, actual) _Generic((expected),\
153 | char : assert_are_equal_ch, \
154 | signed char : assert_are_equal_sch, \
155 | unsigned char : assert_are_equal_uch, \
156 | \
157 | short : assert_are_equal_int, \
158 | unsigned short : assert_are_equal_uint, \
159 | \
160 | int : assert_are_equal_int, \
161 | unsigned int : assert_are_equal_uint, \
162 | \
163 | long : assert_are_equal_int, \
164 | unsigned long : assert_are_equal_uint, \
165 | \
166 | long long : assert_are_equal_int, \
167 | unsigned long long : assert_are_equal_uint, \
168 | \
169 | float : assert_are_equal_dbl, \
170 | double : assert_are_equal_dbl, \
171 | long double : assert_are_equal_dbl, \
172 | \
173 | char * : assert_are_equal_str, \
174 | const char * : assert_are_equal_str, \
175 | \
176 | wchar_t * : assert_are_equal_wstr, \
177 | const wchar_t * : assert_are_equal_wstr, \
178 | \
179 | default : assert_are_equal)(expected, actual, __FILE__, __LINE__)
180 |
181 | /**
182 | * @see ASSERT_ARE_EQUAL(expected, actual);
183 | *
184 | * @remarks This is a short-hand for ASSERT_ARE_EQUAL.
185 | */
186 | #define ASSERT_EQ(expected, actual) ASSERT_ARE_EQUAL(expected, actual)
187 |
188 | void assert_are_not_equal_ch (char unexpected, char actual, char *file, int line);
189 | void assert_are_not_equal_sch (signed char unexpected, signed char actual, char *file, int line);
190 | void assert_are_not_equal_uch (unsigned char unexpected, unsigned char actual, char *file, int line);
191 | void assert_are_not_equal_int (intmax_t unexpected, intmax_t actual, char *file, int line);
192 | void assert_are_not_equal_uint(uintmax_t unexpected, uintmax_t actual, char *file, int line);
193 | void assert_are_not_equal_dbl (long double unexpected, long double actual, char *file, int line);
194 | void assert_are_not_equal_str (const char * unexpected, const char * actual, char *file, int line);
195 | void assert_are_not_equal_wstr(const wchar_t * unexpected, const wchar_t * actual, char *file, int line);
196 | void assert_are_not_equal (const void * unexpected, const void * actual, char *file, int line);
197 | /**
198 | * Tests for inequality.
199 | *
200 | * @param unexpected The first value to compare. This is the value that should not occur.
201 | * @param actual The second value to compare. This is the value produced by the code under test.
202 | * @note The equality function for floating point numbers uses the epsilon macro from float.h
203 | * in its equality test. It is therefore often better to use assert_are_equal_precision()
204 | * and provide the application specific epsilon.
205 | */
206 | #define ASSERT_ARE_NOT_EQUAL(unexpected, actual) _Generic((unexpected),\
207 | char : assert_are_not_equal_ch, \
208 | signed char : assert_are_not_equal_sch, \
209 | unsigned char : assert_are_not_equal_uch, \
210 | \
211 | short : assert_are_not_equal_int, \
212 | unsigned short : assert_are_not_equal_uint, \
213 | \
214 | int : assert_are_not_equal_int, \
215 | unsigned int : assert_are_not_equal_uint, \
216 | \
217 | long : assert_are_not_equal_int, \
218 | unsigned long : assert_are_not_equal_uint, \
219 | \
220 | long long : assert_are_not_equal_int, \
221 | unsigned long long : assert_are_not_equal_uint, \
222 | \
223 | float : assert_are_not_equal_dbl, \
224 | double : assert_are_not_equal_dbl, \
225 | long double : assert_are_not_equal_dbl, \
226 | \
227 | char * : assert_are_not_equal_str, \
228 | const char * : assert_are_not_equal_str, \
229 | \
230 | wchar_t * : assert_are_not_equal_wstr, \
231 | const wchar_t * : assert_are_not_equal_wstr, \
232 | \
233 | default : assert_are_not_equal)(unexpected, actual, __FILE__, __LINE__)
234 |
235 | /**
236 | * @see ASSERT_ARE_NOT_EQUAL(unexpected, actual);
237 | *
238 | * @remarks This is a short-hand for ASSERT_ARE_NOT_EQUAL.
239 | */
240 | #define ASSERT_NE(unexpected, actual) ASSERT_ARE_NOT_EQUAL(unexpected, actual)
241 |
242 | void assert_equal_mem(const void *expected, const void *actual, size_t size, char *file, int line);
243 | /**
244 | * Checks for equality by comparing each byte at the given memory locations.
245 | *
246 | * @param expected A pointer to the expected value.
247 | * @param actual A pointer to the actual value.
248 | * @param size The size of the passed types.
249 | */
250 | #define ASSERT_EQUAL_MEM(expected, actual, size)\
251 | assert_equal_mem(expected, actual, size, __FILE__, __LINE__)
252 |
253 | /**
254 | * @see ASSERT_EQUAL_MEM(expected, actual, size);
255 | *
256 | * @remarks This is a short-hand for ASSERT_EQUAL_MEM.
257 | */
258 | #define ASSERT_EQ_MEM(expected, actual, size) ASSERT_EQUAL_MEM(expected, actual, size)
259 |
260 | void assert_not_equal_mem(const void *unexpected, const void *actual, size_t size, char *file, int line);
261 | /**
262 | * Checks for inequality by comparing each byte at the given memory locations.
263 | *
264 | * @param unexpected A pointer to the unexpected value.
265 | * @param actual A pointer to the actual value.
266 | * @param size The size of the passed types.
267 | */
268 | #define ASSERT_NOT_EQUAL_MEM(unexpected, actual, size)\
269 | assert_not_equal_mem(unexpected, actual, size, __FILE__, __LINE__)
270 |
271 | /**
272 | * @see ASSERT_NOT_EQUAL_MEM(unexpected, actual, size);
273 | *
274 | * @remarks This is a short-hand for ASSERT_NOT_EQUAL_MEM.
275 | */
276 | #define ASSERT_NE_MEM(unexpected, actual, size) ASSERT_NOT_EQUAL_MEM(unexpected, actual, size)
277 |
278 | void assert_greater_mem(const void *greater, const void *lesser, size_t size, char *file, int line);
279 | /**
280 | * Tests whether the first value is greater than the second value by comparing
281 | * the bytes at the memory location.
282 | *
283 | * @param greater The first value to compare. This is the value the user
284 | * expects to be greater than the second value.
285 | *
286 | * @param lesser The second value to compare. This is the value the user
287 | * expects to be lesser than the first value.
288 | */
289 | #define ASSERT_GREATER_MEM(greater, lesser, size)\
290 | assert_greater_mem(greater, lesser, size, __FILE__, __LINE__)
291 |
292 | #define ASSERT_GT_MEM(greater, lesser, size)\
293 | assert_greater_mem(greater, lesser, size, __FILE__, __LINE__)
294 |
295 | void assert_greater_equal_mem(const void *ge, const void *le, size_t size, char *file, int line);
296 | /**
297 | * Tests whether the first value is greater than or equal to the second value
298 | * by comparing the bytes at the memory location.
299 | *
300 | * @param ge The first value to compare. This is the value the user
301 | * expects to be greater than or equal to the second value.
302 | *
303 | * @param le The second value to compare. This is the value the user
304 | * expects to be lesser than or equal to the first value.
305 | */
306 | #define ASSERT_GREATER_EQUAL_MEM(ge, le, size)\
307 | assert_greater_equal_mem(ge, le, size, __FILE__, __LINE__)
308 |
309 | #define ASSERT_GE_MEM(ge, le, size)\
310 | assert_greater_equal_mem(ge, le, size, __FILE__, __LINE__)
311 |
312 | void assert_less_mem(const void *lesser, const void *greater, size_t size, char *file, int line);
313 | /**
314 | * Tests whether the first value is less than the second value by comparing
315 | * the bytes at the memory location.
316 | *
317 | * @param lesser The first value to compare. This is the value the user
318 | * expects to be lesser than the second value.
319 | *
320 | * @param greater The second value to compare. This is the value the user
321 | * expects to be greater than the first value.
322 | */
323 | #define ASSERT_LESS_MEM(lesser, greater, size)\
324 | assert_less_mem(lesser, greater, size, __FILE__, __LINE__)
325 |
326 | #define ASSERT_LT_MEM(lesser, greater, size)\
327 | assert_less_mem(lesser, greater, size, __FILE__, __LINE__)
328 |
329 | void assert_less_equal_mem(const void *le, const void *ge, size_t size, char *file, int line);
330 | /**
331 | * Tests whether the first value is less than or equal to the second value
332 | * by comparing the bytes at the memory location.
333 | *
334 | * @param le The first value to compare. This is the value the user
335 | * expects to be lesser than or equal to the second value.
336 | *
337 | * @param ge The second value to compare. This is the value the user
338 | * expects to be greater than or equal to the first value.
339 | */
340 | #define ASSERT_LESS_EQUAL_MEM(le, ge, size)\
341 | assert_less_equal_mem(le, ge, size, __FILE__, __LINE__)
342 |
343 | #define ASSERT_LE_MEM(le, ge, size)\
344 | assert_less_equal_mem(le, ge, size, __FILE__, __LINE__)
345 |
346 |
347 | void assert_are_equal_cmp(const void *expected,
348 | const void *actual,
349 | int(*cmp_fn)(const void *ptr1, const void *ptr2),
350 | char *file,
351 | int line);
352 | /**
353 | * Tests whether the first value is equal to the second value
354 | * using the passed comparator.
355 | *
356 | * @param expected The first value to compare. This is the value the user
357 | * expects.
358 | *
359 | * @param actual The second value to compare. This is the value that is
360 | * generated by the code under test.
361 | *
362 | * @param cmp_fn The comparator to use. This should return a negative value
363 | * if the first parameter is less than the second parameter,
364 | * 0 (zero) if the values are equal and a positive value if
365 | * the first value is greater than the second value.
366 | */
367 | #define ASSERT_ARE_EQUAL_CMP(expected, actual, cmp_fn)\
368 | assert_are_equal_cmp(expected, actual, cmp_fn, __FILE__, __LINE__)
369 |
370 | /**
371 | * @see ASSERT_ARE_EQUAL_CMP(expected, actual, cmp_fn);
372 | *
373 | * @remarks This is a short-hand for ASSERT_ARE_EQUAL_CMP.
374 | */
375 | #define ASSERT_EQ_CMP(expected, actual, cmp_fn) ASSERT_ARE_EQUAL_CMP(expected, actual, cmp_fn)
376 |
377 | void assert_are_not_equal_cmp(const void *unexpected,
378 | const void *actual,
379 | int(*cmp_fn)(const void *ptr1, const void *ptr2),
380 | char *file,
381 | int line);
382 | /**
383 | * Tests whether the first value is different than the second value
384 | * using the passed comparator.
385 | *
386 | * @param unexpected The first value to compare. This is the value that
387 | * should not occur.
388 | *
389 | * @param actual The second value to compare. This is the value that is
390 | * generated by the code under test.
391 | *
392 | * @param cmp_fn The comparator to use. This should return a negative value
393 | * if the first parameter is less than the second parameter,
394 | * 0 (zero) if the values are equal and a positive value if
395 | * the first value is greater than the second value.*
396 | */
397 | #define ASSERT_ARE_NOT_EQUAL_CMP(unexpected, actual, cmp_fn)\
398 | assert_are_not_equal_cmp(unexpected, actual, cmp_fn, __FILE__, __LINE__)
399 |
400 | void assert_greater_cmp(const void *greater,
401 | const void *lesser,
402 | int(*cmp_fn)(const void *ptr1, const void *ptr2),
403 | char *file,
404 | int line);
405 | /**
406 | * Tests whether the first value is greater than the second value
407 | * using the passed comparator.
408 | *
409 | * @param greater The first value to compare. This is the value the user
410 | * expects to be greater than the second value.
411 | *
412 | * @param lesser The second value to compare. This is the value that is
413 | * expected to be lesser than the first value.
414 | *
415 | * @param cmp_fn The comparator to use. This should return a negative value
416 | * if the first parameter is less than the second parameter,
417 | * 0 (zero) if the values are equal and a positive value if
418 | * the first value is greater than the second value.
419 | */
420 | #define ASSERT_GREATER_CMP(greater, lesser, cmp_fn)\
421 | assert_greater_cmp(greater, lesser, cmp_fn, __FILE__, __LINE__)
422 |
423 | /**
424 | * @see ASSERT_GREATER_CMP(greater, lesser, cmp_fn);
425 | *
426 | * @remarks This is a short-hand for ASSERT_GREATER_CMP.
427 | */
428 | #define ASSERT_GT_CMP(greater, lesser, cmp_fn)\
429 | ASSERT_GREATER_CMP(greater, lesser, cmp_fn)
430 |
431 | void assert_less_cmp(const void *lesser,
432 | const void *greater,
433 | int(*cmp_fn)(const void *ptr1, const void *ptr2),
434 | char *file,
435 | int line);
436 | /**
437 | * Tests whether the first value is lesser than the second value
438 | * using the passed comparator.
439 | *
440 | * @param lesser The first value to compare. This is the value the user
441 | * expects to be lesser than the second value. This value
442 | * is placed as the first parameter of the custom comparator.
443 | *
444 | * @param greater The second value to compare. This is the value that is
445 | * expected to be greater than the first value. This value
446 | * is placed as the second parameter of the custom comparator.
447 | *
448 | * @param cmp_fn The comparator to use. This should return a negative value
449 | * if the first parameter is less than the second parameter,
450 | * 0 (zero) if the values are equal and a positive value if
451 | * the first value is greater than the second value.
452 | */
453 | #define ASSERT_LESS_CMP(lesser, greater, cmp_fn)\
454 | assert_less_cmp(lesser, greater, cmp_fn, __FILE__, __LINE__)
455 |
456 | /**
457 | * @see ASSERT_LESS_CMP(lesser, greater, cmp_fn);
458 | *
459 | * @remarks This is a short-hand for ASSERT_LESS_CMP.
460 | */
461 | #define ASSERT_LT_CMP(lesser, greater, cmp_fn)\
462 | ASSERT_LESS_CMP(lesser, greater, cmp_fn)
463 |
464 | void assert_less_equal_cmp(const void *le,
465 | const void *ge,
466 | int(*cmp_fn)(const void *ptr1, const void *ptr2),
467 | char *file,
468 | int line);
469 | /**
470 | * Tests whether the first value is lesser or equal to the second value
471 | * using the passed comparator.
472 | *
473 | * @param le The first value to compare. This is the value the user expects
474 | * to be lesser than or equal to the second value. This value is
475 | * placed as the first parameter of the custom comparator.
476 | *
477 | * @param ge The second value to compare. This is the value that is expected
478 | * to be greater than or equal to the first value. This value is
479 | * placed as the second parameter of the custom comparator.
480 | *
481 | * @param cmp_fn The comparator to use. This should return a negative value
482 | * if the first parameter is less than the second parameter,
483 | * 0 (zero) if the values are equal and a positive value if
484 | * the first value is greater than the second value.
485 | */
486 | #define ASSERT_LESS_EQUAL_CMP(le, ge, cmp_fn)\
487 | assert_less_equal_cmp(le, ge, cmp_fn, __FILE__, __LINE__)
488 |
489 | /**
490 | * @see ASSERT_LESS_EQUAL_CMP(le, ge, cmp_fn);
491 | *
492 | * @remarks This is a short-hand for ASSERT_LESS_EQUAL_CMP.
493 | */
494 | #define ASSERT_LE_CMP(le, ge, cmp_fn)\
495 | ASSERT_LESS_EQUAL_CMP(le, ge, cmp_fn)
496 |
497 | void assert_greater_equal_cmp(const void *ge,
498 | const void *le,
499 | int(*cmp_fn)(const void *ptr1, const void *ptr2),
500 | char *file,
501 | int line);
502 | /**
503 | * Tests whether the first value is greater than or equal to the second
504 | * value using the passed comparator.
505 | *
506 | * @param ge The first value to compare. This is the value the user
507 | * expects to be greater than or equal to the second value.
508 | *
509 | * @param le The second value to compare. This is the value that is
510 | * expected to be lesser than or equal to the first value.
511 | */
512 | #define ASSERT_GREATER_EQUAL_CMP(ge, le, cmp_fn)\
513 | assert_greater_equal_cmp(ge, le, cmp_fn, __FILE__, __LINE__)
514 |
515 | /**
516 | * @see ASSERT_GREATER_EQUAL_CMP(ge, le, cmp_fn);
517 | *
518 | * @remarks This is a short-hand for ASSERT_GREATER_EQUAL_CMP.
519 | */
520 | #define ASSERT_GE_CMP(ge, le, cmp_fn)\
521 | ASSERT_GREATER_EQUAL_CMP(ge, le, cmp_fn)
522 |
523 | /**
524 | * @see ASSERT_ARE_NOT_EQUAL_CMP(unexpected, actual, cmp_fn);
525 | *
526 | * @remarks This is a short-hand for ASSERT_ARE_NOT_EQUAL_CMP.
527 | */
528 | #define ASSERT_NE_CMP(unexpected, actual, cmp_fn) ASSERT_ARE_NOT_EQUAL_CMP(unexpected, actual, cmp_fn)
529 |
530 | void assert_are_equal_precision(long double expected, long double actual, long double epsilon, char *file, int line);
531 | /**
532 | * Tests for equality between two floating point numbers.
533 | *
534 | * @param expected The first value to compare. This is the value that is expected
535 | * to be generated by the code under test.
536 | *
537 | * @param actual The second value to compare. This is the value generated by the
538 | * code under test.
539 | *
540 | * @param epsilon A floating point representing the precision required when testing
541 | * for equality.
542 | */
543 | #define ASSERT_ARE_EQUAL_PRECISION(expected, actual, epsilon)\
544 | assert_are_equal_precision(expected, actual, epsilon, __FILE__, __LINE__)
545 |
546 | /**
547 | * @see ASSERT_ARE_EQUAL_PRECISION(expected, actual, epsilon);
548 | *
549 | * @remarks This is a short-hand for ASSERT_ARE_EQUAL_PRECISION.
550 | */
551 | #define ASSERT_EQ_PRECISION(expected, actual, epsilon) ASSERT_ARE_EQUAL_PRECISION(expected, actual, epsilon)
552 |
553 | void assert_are_not_equal_precision(long double unexpected,
554 | long double actual,
555 | long double epsilon,
556 | char * file,
557 | int line);
558 | /**
559 | * Tests for inequality between two floating point numbers.
560 | *
561 | * @param unexpected The first value to compare.
562 | *
563 | * @param actual The second value to compare. This is the value generated by the
564 | * code under test.
565 | *
566 | * @param epsilon A floating point representing the precision required when testing
567 | * for equality.
568 | */
569 | #define ASSERT_ARE_NOT_EQUAL_PRECISION(unexpected, actual, epsilon)\
570 | assert_are_not_equal_precision(unexpected, actual, epsilon, __FILE__, __LINE__)
571 |
572 | /**
573 | * @see ASSERT_ARE_NOT_EQUAL_PRECISION(unexpected, actual, epsilon);
574 | *
575 | * @remarks This is a short-hand for ASSERT_ARE_NOT_EQUAL_PRECISION.
576 | */
577 | #define ASSERT_NE_PRECISION(unexpected, actual, epsilon) ASSERT_ARE_NOT_EQUAL_PRECISION(unexpected, actual, epsilon)
578 |
579 | void assert_greater_ch (char greater, char lesser, char *file, int line);
580 | void assert_greater_sch (signed char greater, signed char lesser, char *file, int line);
581 | void assert_greater_uch (unsigned char greater, unsigned char lesser, char *file, int line);
582 | void assert_greater_int (intmax_t greater, intmax_t lesser, char *file, int line);
583 | void assert_greater_uint(uintmax_t greater, uintmax_t lesser, char *file, int line);
584 | void assert_greater_dbl (long double greater, long double lesser, char *file, int line);
585 | void assert_greater_str (const char * greater, const char * lesser, char *file, int line);
586 | void assert_greater_wstr(const wchar_t * greater, const wchar_t * lesser, char *file, int line);
587 | void assert_greater (const void * greater, const void * lesser, char *file, int line);
588 | /**
589 | * Tests whether the first value is greater than the second value.
590 | *
591 | * @param greater The first value to compare. This is the value the user
592 | * expects to be greater than the second value.
593 | *
594 | * @param lesser The second value to compare. This is the value the user
595 | * expects to be lesser than the first value.
596 | */
597 | #define ASSERT_GREATER(greater, lesser) _Generic((greater),\
598 | char : assert_greater_ch, \
599 | signed char : assert_greater_sch, \
600 | unsigned char : assert_greater_uch, \
601 | \
602 | short : assert_greater_int, \
603 | unsigned short : assert_greater_uint, \
604 | \
605 | int : assert_greater_int, \
606 | unsigned int : assert_greater_uint, \
607 | \
608 | long : assert_greater_int, \
609 | unsigned long : assert_greater_uint, \
610 | \
611 | long long : assert_greater_int, \
612 | unsigned long long : assert_greater_uint, \
613 | \
614 | float : assert_greater_dbl, \
615 | double : assert_greater_dbl, \
616 | long double : assert_greater_dbl, \
617 | \
618 | char * : assert_greater_str, \
619 | const char * : assert_greater_str, \
620 | \
621 | wchar_t * : assert_greater_wstr, \
622 | const wchar_t * : assert_greater_wstr, \
623 | \
624 | default : assert_greater)(greater, lesser, __FILE__, __LINE__)
625 |
626 | /**
627 | * @see ASSERT_GREATER(greater, less);
628 | *
629 | * @remarks This is just a short-hand for ASSERT_GREATER.
630 | */
631 | #define ASSERT_GT(greater, lesser) ASSERT_GREATER(greater, lesser)
632 |
633 | void assert_greater_precision(long double greater,
634 | long double lesser,
635 | long double epsilon,
636 | char * file,
637 | int line);
638 |
639 | /**
640 | * Tests whether the first value is greater than the second value.
641 | *
642 | * @param greater The first floating point value to compare. This is the value the user
643 | * expects to be greater than the second value.
644 | *
645 | * @param lesser The second floating point value to compare. This is the value the user
646 | * expects to be lesser than the first value.
647 | *
648 | * @param epsilon A floating point representing the precision required when testing
649 | * for equality.
650 | */
651 | #define ASSERT_GREATER_PRECISION(greater, less, epsilon)\
652 | assert_greater_precision(greater, less, epsilon, __FILE__, __LINE__)
653 |
654 | /**
655 | * @see ASSERT_GREATER_PRECISION(greater, less, epsilon);
656 | *
657 | * @remarks This is just a short-hand for ASSERT_GREATER_PRECISION.
658 | */
659 | #define ASSERT_GT_PRECISION(greater, less, epsilon)\
660 | assert_greater_precision(greater, less, epsilon, __FILE__, __LINE__)
661 |
662 | void assert_greater_equal_ch (char ge, char le, char *file, int line);
663 | void assert_greater_equal_sch (signed char ge, signed char le, char *file, int line);
664 | void assert_greater_equal_uch (unsigned char ge, unsigned char le, char *file, int line);
665 | void assert_greater_equal_int (intmax_t ge, intmax_t le, char *file, int line);
666 | void assert_greater_equal_uint(uintmax_t ge, uintmax_t le, char *file, int line);
667 | void assert_greater_equal_dbl (long double ge, long double le, char *file, int line);
668 | void assert_greater_equal_str (const char * ge, const char * le, char *file, int line);
669 | void assert_greater_equal_wstr(const wchar_t * ge, const wchar_t * le, char *file, int line);
670 | void assert_greater_equal (const void * ge, const void * le, char *file, int line);
671 | /**
672 | * Tests whether the first value is greater than or equal to the second value.
673 | *
674 | * @param greater The first value to compare. This is the value the user
675 | * expects to be greater than or equal to the second value.
676 | *
677 | * @param lesser The second value to compare. This is the value the user
678 | * expects to be lesser than or equal to the first value.
679 | */
680 | #define ASSERT_GREATER_EQUAL(ge, le) _Generic((ge),\
681 | char : assert_greater_equal_ch, \
682 | signed char : assert_greater_equal_sch, \
683 | unsigned char : assert_greater_equal_uch, \
684 | \
685 | short : assert_greater_equal_int, \
686 | unsigned short : assert_greater_equal_uint, \
687 | \
688 | int : assert_greater_equal_int, \
689 | unsigned int : assert_greater_equal_uint, \
690 | \
691 | long : assert_greater_equal_int, \
692 | unsigned long : assert_greater_equal_uint, \
693 | \
694 | long long : assert_greater_equal_int, \
695 | unsigned long long : assert_greater_equal_uint, \
696 | \
697 | float : assert_greater_equal_dbl, \
698 | double : assert_greater_equal_dbl, \
699 | long double : assert_greater_equal_dbl, \
700 | \
701 | char * : assert_greater_equal_str, \
702 | const char * : assert_greater_equal_str, \
703 | \
704 | wchar_t * : assert_greater_equal_wstr, \
705 | const wchar_t * : assert_greater_equal_wstr, \
706 | \
707 | default : assert_greater_equal)(ge, le, __FILE__, __LINE__)
708 |
709 | /**
710 | * @see ASSERT_GREATER_EQUAL(ge, le);
711 | *
712 | * @remarks This is just a short-hand for ASSERT_GREATER_EQUAL.
713 | */
714 | #define ASSERT_GE(ge, le) ASSERT_GREATER_EQUAL(ge, le)
715 |
716 | void assert_greater_equal_precision(long double ge,
717 | long double le,
718 | long double epsilon,
719 | char *file,
720 | int line);
721 |
722 | /**
723 | * Tests whether the first value is greater than or equal to the second value.
724 | *
725 | * @param ge The first floating point value to compare. This is the value the user
726 | * expects to be greater than or equal to the second value.
727 | *
728 | * @param le The second floating point value to compare. This is the value the user
729 | * expects to be lesser than or equal to the first value.
730 | *
731 | * @param epsilon A floating point representing the precision required when testing
732 | * for equality.
733 | */
734 | #define ASSERT_GREATER_EQUAL_PRECISION(ge, le, epsilon)\
735 | assert_greater_equal_precision(ge, le, epsilon, __FILE__, __LINE__)
736 |
737 | /**
738 | * @see ASSERT_GREATER_EQUAL_PRECISION(ge, le, epsilon);
739 | *
740 | * @remarks This is just a short-hand for ASSERT_GREATER_EQUAL_PRECISION.
741 | */
742 | #define ASSERT_GE_PRECISION(ge, le, epsilon)\
743 | assert_greater_equal_precision(ge, le, epsilon, __FILE__, __LINE__)
744 |
745 | void assert_less_ch (char lesser, char greater, char *file, int line);
746 | void assert_less_sch (signed char lesser, signed char greater, char *file, int line);
747 | void assert_less_uch (unsigned char lesser, unsigned char greater, char *file, int line);
748 | void assert_less_int (intmax_t lesser, intmax_t greater, char *file, int line);
749 | void assert_less_uint(uintmax_t lesser, uintmax_t greater, char *file, int line);
750 | void assert_less_dbl (long double lesser, long double greater, char *file, int line);
751 | void assert_less_str (const char *lesser, const char *greater, char *file, int line);
752 | void assert_less_wstr(const wchar_t *lesser, const wchar_t *greater, char *file, int line);
753 | void assert_less (const void *lesser, const void *greater, char *file, int line);
754 | /**
755 | * Tests whether the first value is lesser than the second value.
756 | *
757 | * @param lesser The first value to compare. This is the value the user
758 | * expects to be lesser than the second value.
759 | *
760 | * @param greater The second value to compare. This is the value the user
761 | * expects to be greater than the first value.
762 | */
763 | #define ASSERT_LESS(lesser, greater) _Generic((lesser),\
764 | char : assert_less_ch, \
765 | signed char : assert_less_sch, \
766 | unsigned char : assert_less_uch, \
767 | \
768 | short : assert_less_int, \
769 | unsigned short : assert_less_uint, \
770 | \
771 | int : assert_less_int, \
772 | unsigned int : assert_less_uint, \
773 | \
774 | long : assert_less_int, \
775 | unsigned long : assert_less_uint, \
776 | \
777 | long long : assert_less_int, \
778 | unsigned long long : assert_less_uint, \
779 | \
780 | float : assert_less_dbl, \
781 | double : assert_less_dbl, \
782 | long double : assert_less_dbl, \
783 | \
784 | char * : assert_less_str, \
785 | const char * : assert_less_str, \
786 | \
787 | wchar_t * : assert_less_wstr, \
788 | const wchar_t * : assert_less_wstr, \
789 | \
790 | default : assert_less)(lesser, greater, __FILE__, __LINE__)
791 |
792 | /**
793 | * @see ASSERT_LESS(lesser, greater);
794 | *
795 | * @remarks This is just a short-hand for ASSERT_LESS.
796 | */
797 | #define ASSERT_LT(lesser, greater) ASSERT_LESS(lesser, greater)
798 |
799 | void assert_less_precision(long double lesser,
800 | long double greater,
801 | long double epsilon,
802 | char *file,
803 | int line);
804 |
805 | /**
806 | * Tests whether the first value is lesser than the second value.
807 | *
808 | * @param lesser The first floating point value to compare. This is the value the user
809 | * expects to be lesser than the second value.
810 | *
811 | * @param greater The second floating point value to compare. This is the value the user
812 | * expects to be greater than the first value.
813 | *
814 | * @param epsilon A floating point representing the precision required when testing
815 | * for equality.
816 | */
817 | #define ASSERT_LESS_PRECISION(lesser, greater, epsilon)\
818 | assert_less_precision(lesser, greater, epsilon, __FILE__, __LINE__)
819 |
820 | /**
821 | * @see ASSERT_LESS_PRECISION(lesser, greater, epsilon);
822 | *
823 | * @remarks This is just a short-hand for ASSERT_LESS_PRECISION.
824 | */
825 | #define ASSERT_LT_PRECISION(lesser, greater, epsilon)\
826 | assert_less_precision(lesser, greater, epsilon, __FILE__, __LINE__)
827 |
828 | void assert_less_equal_ch (char le, char ge, char *file, int line);
829 | void assert_less_equal_sch (signed char le, signed char ge, char *file, int line);
830 | void assert_less_equal_uch (unsigned char le, unsigned char ge, char *file, int line);
831 | void assert_less_equal_int (intmax_t le, intmax_t ge, char *file, int line);
832 | void assert_less_equal_uint(uintmax_t le, uintmax_t ge, char *file, int line);
833 | void assert_less_equal_dbl (long double le, long double ge, char *file, int line);
834 | void assert_less_equal_str (const char *le, const char *ge, char *file, int line);
835 | void assert_less_equal_wstr(const wchar_t *le, const wchar_t *ge, char *file, int line);
836 | void assert_less_equal (const void *le, const void *ge, char *file, int line);
837 | /**
838 | * Tests whether the first value is lesser than or equal to the second value.
839 | *
840 | * @param le The first value to compare. This is the value the user
841 | * expects to be lesser than or equal to the second value.
842 | *
843 | * @param ge The second value to compare. This is the value the user
844 | * expects to be greater than or equal to the first value.
845 | */
846 | #define ASSERT_LESS_EQUAL(le, ge) _Generic((le),\
847 | char : assert_less_equal_ch, \
848 | signed char : assert_less_equal_sch, \
849 | unsigned char : assert_less_equal_uch, \
850 | \
851 | short : assert_less_equal_int, \
852 | unsigned short : assert_less_equal_uint, \
853 | \
854 | int : assert_less_equal_int, \
855 | unsigned int : assert_less_equal_uint, \
856 | \
857 | long : assert_less_equal_int, \
858 | unsigned long : assert_less_equal_uint, \
859 | \
860 | long long : assert_less_equal_int, \
861 | unsigned long long : assert_less_equal_uint, \
862 | \
863 | float : assert_less_equal_dbl, \
864 | double : assert_less_equal_dbl, \
865 | long double : assert_less_equal_dbl, \
866 | \
867 | char * : assert_less_equal_str, \
868 | const char * : assert_less_equal_str, \
869 | \
870 | wchar_t * : assert_less_equal_wstr, \
871 | const wchar_t * : assert_less_equal_wstr, \
872 | \
873 | default : assert_less_equal)(le, ge, __FILE__, __LINE__)
874 |
875 | /**
876 | * @see ASSERT_LESS_EQUAL(le, ge);
877 | *
878 | * @remarks This is just a short-hand for ASSERT_LESS_EQUAL.
879 | */
880 | #define ASSERT_LE(le, ge) ASSERT_LESS_EQUAL(le, ge)
881 |
882 | void assert_less_equal_precision(long double le,
883 | long double ge,
884 | long double epsilon,
885 | char *file,
886 | int line);
887 |
888 | /**
889 | * Tests whether the first value is lesser than or equal to the second value.
890 | *
891 | * @param le The first floating point value to compare. This is the value the user
892 | * expects to be lesser than or equal to the second value.
893 | *
894 | * @param ge The second floating point value to compare. This is the value the user
895 | * expects to be greater than or equal to the first value.
896 | *
897 | * @param epsilon A floating point representing the precision required when testing
898 | * for equality.
899 | */
900 | #define ASSERT_LESS_EQUAL_PRECISION(le, ge, epsilon)\
901 | assert_less_equal_precision(le, ge, epsilon, __FILE__, __LINE__)
902 |
903 | /**
904 | * @see ASSERT_LESS_EQUAL_PRECISION(le, ge, epsilon);
905 | *
906 | * @remarks This is just a short-hand for ASSERT_LESS_EQUAL_PRECISION.
907 | */
908 | #define ASSERT_LE_PRECISION(le, ge, epsilon)\
909 | assert_less_equal_precision(le, ge, epsilon, __FILE__, __LINE__)
910 |
911 | #ifdef TEST_RUNNER
912 |
913 | #include
914 | #include
915 | #include
916 | #include
917 | #include
918 | #include
919 | #include
920 | #include
921 | #include
922 | #include
923 |
924 | /**
925 | * This is the value returned when the runner encounters an error
926 | * and has to exit. The value is positive (rather than the conventional -1)
927 | * because the return value is the amount of failed tests. This is also why
928 | * the value is set so high.
929 | */
930 | #define EZTEST_EXIT_FAILURE 99999
931 |
932 | #define COLOR_RED "\033[0;31m"
933 | #define COLOR_YELLOW "\033[0;33m"
934 | #define COLOR_GREEN "\033[0;32m"
935 | #define COLOR_NONE "\033[0m"
936 |
937 | /** Represents the application options for EzTest. */
938 | struct options
939 | {
940 | /** When set to @code true @endcode only default color is used when printing. */
941 | bool no_color;
942 | /** When set to @code true @endcode the test execution time is displayed for each test */
943 | bool timer;
944 | /** When set to @code true @endcode EzTest will not print anything. */
945 | bool quiet;
946 | /** When set to @code true @endcode the skip list will be checked. */
947 | bool skip;
948 | /** Handles segfault. */
949 | bool sigsegv;
950 | };
951 |
952 | enum test_result
953 | {
954 | undefined,
955 | pass,
956 | fail,
957 | skip
958 | };
959 |
960 | /** Used to separate items in the skip list. */
961 | static const char *separator = ",";
962 |
963 | /** A list of test suit names to skip separated by @see separator.*/
964 | static char *skip_list = NULL;
965 |
966 | static const size_t ASSERT_BUFFER_SIZE = 512;
967 |
968 | /**
969 | * Holds the output of asserts for the current test.
970 | *
971 | * @remarks It should be "cleared" between each test.
972 | */
973 | static char *assert_buffer = NULL;
974 |
975 | /**
976 | * The current length of the assert buffer.
977 | *
978 | * @remarks This exists to remove some strlen calls.
979 | */
980 | static int assert_buffer_len = 0;
981 |
982 | static int pass_count = 0;
983 | static int fail_count = 0;
984 | static int skip_count = 0;
985 |
986 | /** The current test. */
987 | static struct unit_test *current = NULL;
988 |
989 | /** Application options */
990 | static struct options *options = NULL;
991 |
992 | /** The result of the current/ latest test. */
993 | static enum test_result result = undefined;
994 |
995 | /** Create base/ reference test. */
996 | TEST(eztest_base_suite, eztest_base_test){}
997 |
998 | //region printers
999 |
1000 | /**
1001 | * Extracts the file name from the given path.
1002 | * Note that the file name includes the file extension.
1003 | *
1004 | * @param path The path of which to extract the file name.
1005 | * @return A char pointer to the first char in the file name.
1006 | */
1007 | static const char *extract_file_name(char *path)
1008 | {
1009 | char *tmp = strrchr(path, '/');
1010 | if(tmp == NULL)
1011 | {
1012 | return path;
1013 | }
1014 | path = tmp;
1015 | return ++path;
1016 | }
1017 |
1018 | /**
1019 | * Get the requested color if and only if the application options allow it.
1020 | *
1021 | * @param color The color to request (not NULL).
1022 | * @return If 'no-color' has been set in the application options then
1023 | * @code COLOR_NONE @endcode is returned; otherwise the requested
1024 | * color is returned.
1025 | */
1026 | static const char *color(const char *color)
1027 | {
1028 | assert(color != NULL);
1029 |
1030 | if(options->no_color)
1031 | {
1032 | return COLOR_NONE;
1033 | }
1034 | return color;
1035 | }
1036 |
1037 | static void register_file_marker(char *file, const int line)
1038 | {
1039 | assert_buffer_len += snprintf(
1040 | assert_buffer + assert_buffer_len,
1041 | ASSERT_BUFFER_SIZE - assert_buffer_len,
1042 | "\n%s└──%s See file %s line %d %s", COLOR_NONE, color(COLOR_YELLOW), extract_file_name(file), line, COLOR_NONE);
1043 | }
1044 |
1045 | /** Prints an overall report of the test results. */
1046 | static void print_report(void)
1047 | {
1048 | if(options->quiet) return;
1049 |
1050 | printf("-----------------------------------\n"
1051 | "| "
1052 | "%sPASSED" COLOR_NONE " | "
1053 | "%sSKIPPED" COLOR_NONE " | "
1054 | "%sFAILED" COLOR_NONE " |\n"
1055 | "-----------------------------------\n"
1056 | "| "
1057 | " %s%-7d" COLOR_NONE " | "
1058 | " %s%-8d" COLOR_NONE " | "
1059 | " %s%-7d" COLOR_NONE " |\n"
1060 | "-----------------------------------\n\n",
1061 | color(COLOR_GREEN) ,
1062 | color(COLOR_YELLOW),
1063 | color(COLOR_RED) ,
1064 | color(COLOR_GREEN) , pass_count,
1065 | color(COLOR_YELLOW), skip_count,
1066 | color(COLOR_RED) , fail_count);
1067 | }
1068 |
1069 | /**
1070 | * Prints the test result output if and only if the quiet option has not been set.
1071 | *
1072 | * @param test The unit test to print result for.
1073 | * @param time The test execution time in ms.
1074 | * @param resstr The string representing the result (Eg. PASS, FAIL etc)
1075 | * @param c The requested color of the output result string.
1076 | */
1077 | static void print_result(const struct unit_test *test,
1078 | const unsigned int time,
1079 | const char *restrict resstr,
1080 | const char *restrict c)
1081 | {
1082 | if(options->quiet) return;
1083 |
1084 | printf("|%s %s %s] %s : %s " COLOR_NONE,
1085 | // Print result with the given color.
1086 | color(c), resstr, COLOR_NONE,
1087 | // Print test suite and name
1088 | test->test_suite, test->test_name);
1089 |
1090 | if(options->timer)
1091 | {
1092 | printf("(%dms)\n", time);
1093 | }
1094 | else
1095 | {
1096 | printf("\n");
1097 | }
1098 |
1099 | if(assert_buffer_len > 0)
1100 | {
1101 | puts(assert_buffer);
1102 | }
1103 | printf("\n");
1104 | fflush(stdout);
1105 | }
1106 |
1107 | static void print_failed(const struct unit_test *test, const unsigned int time)
1108 | {
1109 | print_result(test, time, "FAILED", COLOR_RED);
1110 | }
1111 |
1112 | static void print_passed(const struct unit_test *test, const unsigned int time)
1113 | {
1114 | print_result(test, time, "PASSED", COLOR_GREEN);
1115 | }
1116 |
1117 | static void print_skipped(const struct unit_test *test, const unsigned int time)
1118 | {
1119 | print_result(test, time, "SKIPPED", COLOR_YELLOW);
1120 | }
1121 |
1122 | /**
1123 | * Store the n first bytes at the memory location pointed to by the given pointer in hex.
1124 | *
1125 | * @param buffer Location of which the bytes will be written to.
1126 | * @param ptr Pointer to the memory location of which to start.
1127 | * @param n The amount of bytes to print.
1128 | */
1129 | static void register_bytes(char *buffer, const void *ptr, size_t n)
1130 | {
1131 | const unsigned char *bytes = (const unsigned char *)ptr;
1132 | for (; n > 0; --n, ++bytes)
1133 | {
1134 | snprintf(buffer + strlen(buffer), 128 - strlen(buffer), "%x", *bytes);
1135 | }
1136 | }
1137 |
1138 | /**
1139 | * Registers the current test as a failure and prints the given failure message.
1140 | *
1141 | * @param msg The failure message to print.
1142 | * @param ... Message arguments.
1143 | */
1144 | static void register_fail(char *file, const int line, const char *msg, ...)
1145 | {
1146 | result = fail;
1147 |
1148 | if(options->quiet)
1149 | {
1150 | return;
1151 | }
1152 |
1153 | assert_buffer_len += snprintf(assert_buffer + assert_buffer_len, ASSERT_BUFFER_SIZE - assert_buffer_len, "%s├── %s", COLOR_NONE, color(COLOR_YELLOW));
1154 | va_list va;
1155 | va_start(va, msg);
1156 | assert_buffer_len += vsnprintf(assert_buffer + assert_buffer_len, ASSERT_BUFFER_SIZE - assert_buffer_len, msg, va);
1157 | va_end(va);
1158 | register_file_marker(file, line);
1159 | }
1160 |
1161 | //endregion printers
1162 |
1163 | //region asserts
1164 |
1165 | void assert_is_null(const void *value, char *file, const int line)
1166 | {
1167 | if (value != NULL)
1168 | {
1169 | register_fail(file, line, "Assert is null failed: value is not null.");
1170 | }
1171 | }
1172 |
1173 | void assert_is_not_null(const void *value, char *file, const int line)
1174 | {
1175 | if (value == NULL)
1176 | {
1177 | register_fail(file, line, "Assert is not null failed: value is null.");
1178 | }
1179 | }
1180 |
1181 | void assert_is_true(const bool condition, char *file, const int line)
1182 | {
1183 | if(condition != true)
1184 | {
1185 | register_fail(file, line, "Assert is true failed.");
1186 | }
1187 | }
1188 |
1189 | void assert_is_false(const bool condition, char *file, const int line)
1190 | {
1191 | if(condition != false)
1192 | {
1193 | register_fail(file, line, "Assert is false failed.");
1194 | }
1195 | }
1196 |
1197 | void assert_are_same(const void *expected, const void *actual, char *file, const int line)
1198 | {
1199 | if(expected != actual)
1200 | {
1201 | register_fail(file, line, "Assert are same failed: different memory location.");
1202 | }
1203 | }
1204 |
1205 | void assert_are_not_same(const void *unexpected, const void *actual, char *file, const int line)
1206 | {
1207 | if(unexpected == actual)
1208 | {
1209 | register_fail(file, line, "Assert are not same failed: same memory location.");
1210 | }
1211 | }
1212 |
1213 | #ifdef NAN
1214 |
1215 | void assert_is_nan(const float value, char *file, const int line)
1216 | {
1217 | if(!isnan(value))
1218 | {
1219 | register_fail(file, line, "Assert is NaN failed.");
1220 | }
1221 | }
1222 |
1223 | #endif
1224 |
1225 | void mem_test_failed(const void *ptr1, const void *ptr2, const size_t size, char *file,
1226 | const int line, const char *msg1, const char *msg2)
1227 | {
1228 | result = fail;
1229 |
1230 | if(options->quiet)
1231 | {
1232 | return;
1233 | }
1234 |
1235 | char buf[128];
1236 | buf[0] = '\0';
1237 |
1238 | snprintf(buf, 128, "%s '0x", msg1);
1239 | register_bytes(buf, ptr1, (size > EZTEST_MAX_PRINTABLE_LEN ? EZTEST_MAX_PRINTABLE_LEN : size));
1240 | snprintf(buf + strlen(buf), 128 - strlen(buf), "%s'%s '0x", (size > EZTEST_MAX_PRINTABLE_LEN ? "..." : ""), msg2);
1241 | register_bytes(buf, ptr2, (size > EZTEST_MAX_PRINTABLE_LEN ? EZTEST_MAX_PRINTABLE_LEN : size));
1242 | snprintf(buf + strlen(buf), 128 - strlen(buf), "%s", (size > EZTEST_MAX_PRINTABLE_LEN ? "...'." : "'."));
1243 |
1244 | register_fail(file, line, buf);
1245 | }
1246 |
1247 | void assert_equal_mem(const void *expected, const void *actual, const size_t size, char *file, const int line)
1248 | {
1249 | if((expected == NULL && actual != NULL) ||
1250 | (expected != NULL && actual == NULL) ||
1251 | (expected != NULL && memcmp(expected, actual, size) != 0))
1252 | {
1253 | mem_test_failed(expected, actual, size, file, line, "Assert are equal failed: expected", ", but got");
1254 | }
1255 | }
1256 |
1257 | void assert_not_equal_mem(const void *unexpected, const void *actual, const size_t size, char *file, const int line)
1258 | {
1259 | if((unexpected == NULL && actual == NULL) ||
1260 | (unexpected != NULL && actual != NULL && memcmp(unexpected, actual, size) == 0))
1261 | {
1262 | mem_test_failed(unexpected, actual, size, file, line, "Assert not equal failed:", "is equal to");
1263 | }
1264 | }
1265 |
1266 |
1267 |
1268 | void assert_greater_mem(const void *greater, const void *lesser, const size_t size, char *file, const int line)
1269 | {
1270 | if((greater == NULL && lesser != NULL) ||
1271 | (greater == NULL && lesser == NULL) ||
1272 | (greater != NULL && lesser != NULL && memcmp(greater, lesser, size) < 1))
1273 | {
1274 | mem_test_failed(greater, lesser, size, file, line, "Assert greater failed:", "is lesser than or equal to");
1275 | }
1276 | }
1277 |
1278 | void assert_greater_equal_mem(const void *ge, const void *le, const size_t size, char *file, const int line)
1279 | {
1280 | if((ge == NULL && le != NULL) ||
1281 | (ge != NULL && le != NULL && memcmp(ge, le, size) < 0))
1282 | {
1283 | mem_test_failed(ge, le, size, file, line, "Assert greater equal failed:", "is lesser than");
1284 | }
1285 | }
1286 |
1287 | void assert_less_mem(const void *lesser, const void *greater, const size_t size, char *file, const int line)
1288 | {
1289 | if((lesser != NULL && greater == NULL) ||
1290 | (lesser == NULL && greater == NULL) ||
1291 | (lesser != NULL && greater != NULL && memcmp(lesser, greater, size) >= 0))
1292 | {
1293 | mem_test_failed(lesser, greater, size, file, line, "Assert lesser failed:", "is greater than or equal to");
1294 | }
1295 | }
1296 |
1297 | void assert_less_equal_mem(const void *le, const void *ge, const size_t size, char *file, const int line)
1298 | {
1299 | if((le != NULL && ge == NULL) ||
1300 | (le != NULL && ge != NULL && memcmp(le, ge, size) > 0))
1301 | {
1302 | mem_test_failed(le, ge, size, file, line, "Assert less or equal failed:", "is greater than");
1303 | }
1304 | }
1305 |
1306 | void assert_are_equal_cmp(const void *expected,
1307 | const void *actual,
1308 | int(*cmp_fn)(const void *ptr1, const void *ptr2),
1309 | char *file,
1310 | const int line)
1311 | {
1312 | if(cmp_fn(expected, actual) != 0)
1313 | {
1314 | register_fail(file, line, "Assert are equal failed.");
1315 | }
1316 | }
1317 |
1318 | void assert_are_not_equal_cmp(const void *unexpected,
1319 | const void *actual,
1320 | int(*cmp_fn)(const void *ptr1, const void *ptr2),
1321 | char *file,
1322 | const int line)
1323 | {
1324 | if(cmp_fn(unexpected, actual) == 0)
1325 | {
1326 | register_fail(file, line, "Assert not equal failed.");
1327 | }
1328 | }
1329 |
1330 | void assert_greater_cmp(const void *greater,
1331 | const void *lesser,
1332 | int(*cmp_fn)(const void *ptr1, const void *ptr2),
1333 | char *file,
1334 | const int line)
1335 | {
1336 | if(cmp_fn(greater, lesser) < 1)
1337 | {
1338 | register_fail(file, line, "Assert greater failed.");
1339 | }
1340 | }
1341 |
1342 | void assert_greater_equal_cmp(const void *ge,
1343 | const void *le,
1344 | int(*cmp_fn)(const void *ptr1, const void *ptr2),
1345 | char *file,
1346 | const int line)
1347 | {
1348 | if(cmp_fn(ge, le) < 0)
1349 | {
1350 | register_fail(file, line, "Assert greater or equal failed.");
1351 | }
1352 | }
1353 |
1354 | void assert_less_cmp(const void *lesser,
1355 | const void *greater,
1356 | int(*cmp_fn)(const void *ptr1, const void *ptr2),
1357 | char *file,
1358 | const int line)
1359 | {
1360 | if(cmp_fn(lesser, greater) >= 0)
1361 | {
1362 | register_fail(file, line, "Assert less failed.");
1363 | }
1364 | }
1365 |
1366 |
1367 | void assert_less_equal_cmp(const void *le,
1368 | const void *ge,
1369 | int(*cmp_fn)(const void *ptr1, const void *ptr2),
1370 | char *file,
1371 | const int line)
1372 | {
1373 | if(cmp_fn(le, ge) > 0)
1374 | {
1375 | register_fail(file, line, "Assert less or equal failed.");
1376 | }
1377 | }
1378 |
1379 | void assert_are_equal_ch(const char expected, const char actual, char *file, const int line)
1380 | {
1381 | if(expected != actual)
1382 | {
1383 | register_fail(file, line, "Assert are equal failed: expected '%c', but got '%c'.", expected, actual);
1384 | }
1385 | }
1386 |
1387 | void assert_are_equal_sch(const signed char expected, const signed char actual, char *file, const int line)
1388 | {
1389 | if(expected != actual)
1390 | {
1391 | register_fail(file, line, "Assert are equal failed: expected '%c', but got '%c'.", expected, actual);
1392 | }
1393 | }
1394 |
1395 | void assert_are_equal_uch(const unsigned char expected, const unsigned char actual, char *file, const int line)
1396 | {
1397 | if(expected != actual)
1398 | {
1399 | register_fail(file, line, "Assert are equal failed: expected '%c', but got '%c'.", expected, actual);
1400 | }
1401 | }
1402 |
1403 | void assert_are_equal_int(const intmax_t expected, const intmax_t actual, char *file, const int line)
1404 | {
1405 | if(expected != actual)
1406 | {
1407 | register_fail(file, line, "Assert are equal failed: expected '%ld', but got '%ld'.", expected, actual);
1408 | }
1409 | }
1410 |
1411 | void assert_are_equal_uint(const uintmax_t expected, const uintmax_t actual, char *file, const int line)
1412 | {
1413 | if(expected != actual)
1414 | {
1415 | register_fail(file, line, "Assert are equal failed: expected '%ld', but got '%ld'.", expected, actual);
1416 | }
1417 | }
1418 |
1419 | /**
1420 | * Tests the equality of two floating point numbers.
1421 | *
1422 | * @param expected The first and expected value.
1423 | * @param actual The actual value generated by the code under test.
1424 | *
1425 | * @remarks It is important to known that this test uses the epsilon macro from float.h
1426 | * in its equality test. It is therefore often better to use assert_are_equal_precision()
1427 | * and provide the application specific epsilon.
1428 | */
1429 | void assert_are_equal_dbl(const long double expected, const long double actual, char *file, const int line)
1430 | {
1431 | if(fabsl(expected - actual) > LDBL_EPSILON)
1432 | {
1433 | register_fail(file, line, "Assert are equal failed: expected '%0.8Lf', but got '%0.8Lf'.", expected, actual);
1434 | }
1435 | }
1436 | void assert_are_equal_str(const char *expected, const char *actual, char *file, const int line)
1437 | {
1438 | if((expected == NULL && actual != NULL) ||
1439 | (expected != NULL && actual == NULL) ||
1440 | (expected != NULL && strcmp(expected, actual) != 0))
1441 | {
1442 | register_fail(file, line, "Assert are equal failed: expected '%s', but got '%s'.", expected, actual);
1443 | }
1444 | }
1445 |
1446 | void assert_are_equal_wstr(const wchar_t *expected, const wchar_t *actual, char *file, const int line)
1447 | {
1448 | if((expected == NULL && actual != NULL) ||
1449 | (expected != NULL && actual == NULL) ||
1450 | (expected != NULL && wcscmp(expected, actual) != 0))
1451 | {
1452 | register_fail(file, line, "Assert are equal failed: expected '%ls', but got '%ls'.", expected, actual);
1453 | }
1454 | }
1455 |
1456 | /** Triggered when attempting to compare using an unsupported data type. */
1457 | void assert_are_equal(const void *expected, const void *actual, char *file, const int line)
1458 | {
1459 | register_fail(file, line, "Assert are equal failed: unsupported data type.");
1460 | }
1461 |
1462 | void assert_are_not_equal_ch(const char unexpected, const char actual, char *file, const int line)
1463 | {
1464 | if(unexpected == actual)
1465 | {
1466 | register_fail(file, line, "Assert not equal failed: '%c' and '%c' are equal.", unexpected, actual);
1467 | }
1468 | }
1469 |
1470 | void assert_are_not_equal_sch(const signed char unexpected, const signed char actual, char *file, const int line)
1471 | {
1472 | if(unexpected == actual)
1473 | {
1474 | register_fail(file, line, "Assert not equal failed: '%c' and '%c' are equal.", unexpected, actual);
1475 | }
1476 | }
1477 |
1478 | void assert_are_not_equal_uch(const unsigned char unexpected, const unsigned char actual, char *file, const int line)
1479 | {
1480 | if(unexpected == actual)
1481 | {
1482 | register_fail(file, line, "Assert not equal failed: '%c' and '%c' are equal.", unexpected, actual);
1483 | }
1484 | }
1485 |
1486 | void assert_are_not_equal_int(const intmax_t unexpected, const intmax_t actual, char *file, const int line)
1487 | {
1488 | if(unexpected == actual)
1489 | {
1490 | register_fail(file, line, "Assert not equal failed: '%ld' and '%ld' are equal.", unexpected, actual);
1491 | }
1492 | }
1493 |
1494 | void assert_are_not_equal_uint(const uintmax_t unexpected, const uintmax_t actual, char *file, const int line)
1495 | {
1496 | if(unexpected == actual)
1497 | {
1498 | register_fail(file, line, "Assert not equal failed: '%ld' and '%ld' are equal.", unexpected, actual);
1499 | }
1500 | }
1501 |
1502 | /**
1503 | * Tests the equality of two floating point numbers.
1504 | *
1505 | * @param unexpected The first and unexpected value.
1506 | * @param actual The actual value generated by the code under test.
1507 | *
1508 | * @remarks It is important to known that this test uses the epsilon macro from float.h
1509 | * in its equality test. It is therefore often better to use assert_are_equal_precision()
1510 | * and provide the application specific epsilon.
1511 | */
1512 | void assert_are_not_equal_dbl(const long double unexpected, const long double actual, char *file, const int line)
1513 | {
1514 | if(fabsl(unexpected - actual) <= LDBL_EPSILON)
1515 | {
1516 | register_fail(file, line, "Assert not equal failed: '%0.8Lf' and '%0.8Lf' are equal.", unexpected, actual);
1517 | }
1518 | }
1519 |
1520 | void assert_are_not_equal_str(const char *unexpected, const char *actual, char *file, const int line)
1521 | {
1522 | if((unexpected == NULL && actual == NULL) ||
1523 | (unexpected != NULL && actual != NULL && strcmp(unexpected, actual) == 0))
1524 | {
1525 | register_fail(file, line, "Assert not equal failed: '%s' and '%s' are equal.", unexpected, actual);
1526 | }
1527 | }
1528 |
1529 | void assert_are_not_equal_wstr(const wchar_t *unexpected, const wchar_t *actual, char *file, const int line)
1530 | {
1531 | if((unexpected == NULL && actual == NULL) ||
1532 | (unexpected != NULL && actual != NULL && wcscmp(unexpected, actual) == 0))
1533 | {
1534 | register_fail(file, line, "Assert not equal failed: '%ls' and '%ls' are equal.", unexpected, actual);
1535 | }
1536 | }
1537 |
1538 | /** Triggered when attempting to compare using an unsupported data type. */
1539 | void assert_are_not_equal(const void *expected, const void *actual, char *file, const int line)
1540 | {
1541 | register_fail(file, line, "Assert not equal failed: unsupported data type.");
1542 | }
1543 |
1544 | void assert_are_equal_precision(const long double expected,
1545 | const long double actual,
1546 | const long double epsilon,
1547 | char *file,
1548 | const int line)
1549 | {
1550 | if(fabsl(expected - actual) > epsilon)
1551 | {
1552 | register_fail(file, line, "Assert are equal failed: expected '%0.8Lf', but got '%0.8Lf'.", expected, actual);
1553 | }
1554 | }
1555 |
1556 | void assert_are_not_equal_precision(const long double unexpected,
1557 | const long double actual,
1558 | const long double epsilon,
1559 | char *file,
1560 | const int line)
1561 | {
1562 | if(fabsl(unexpected - actual) <= epsilon)
1563 | {
1564 | register_fail(file, line, "Assert not equal failed: '%0.8Lf' and '%0.8Lf' are equal.", unexpected, actual);
1565 | }
1566 | }
1567 |
1568 | void assert_greater_ch(const char greater, const char lesser, char *file, const int line)
1569 | {
1570 | if(greater <= lesser)
1571 | {
1572 | register_fail(file, line, "Assert greater failed: '%c' is not greater than '%c'.", greater, lesser);
1573 | }
1574 | }
1575 |
1576 | void assert_greater_sch(const signed char greater, const signed char lesser, char *file, const int line)
1577 | {
1578 | if(greater <= lesser)
1579 | {
1580 | register_fail(file, line, "Assert greater failed: '%c' is not greater than '%c'.", greater, lesser);
1581 | }
1582 | }
1583 |
1584 | void assert_greater_uch(const unsigned char greater, const unsigned char lesser, char *file, const int line)
1585 | {
1586 | if(greater <= lesser)
1587 | {
1588 | register_fail(file, line, "Assert greater failed: '%c' is not greater than '%c'.", greater, lesser);
1589 | }
1590 | }
1591 |
1592 | void assert_greater_int(const intmax_t greater, const intmax_t lesser, char *file, const int line)
1593 | {
1594 | if(greater <= lesser)
1595 | {
1596 | register_fail(file, line, "Assert greater failed: '%ld' is not greater than '%ld'.", greater, lesser);
1597 | }
1598 | }
1599 |
1600 | void assert_greater_uint(const uintmax_t greater, const uintmax_t lesser, char *file, const int line)
1601 | {
1602 | if(greater <= lesser)
1603 | {
1604 | register_fail(file, line, "Assert greater failed: '%ld' is not greater than '%ld'.", greater, lesser);
1605 | }
1606 | }
1607 |
1608 | /**
1609 | * Tests the equality of two floating point numbers.
1610 | *
1611 | * @param greater The value that is expected to be greater.
1612 | * @param lesser The value that is expected to be lesser.
1613 | *
1614 | * @remarks It is important to known that this test uses the epsilon macro from float.h
1615 | * in its equality test. It is therefore often better to use assert_greater_precision()
1616 | * and provide the application specific epsilon.
1617 | */
1618 | void assert_greater_dbl(const long double greater, const long double lesser, char *file, const int line)
1619 | {
1620 | if(fabsl(greater - lesser) <= LDBL_EPSILON || greater < lesser)
1621 | {
1622 | register_fail(file, line, "Assert greater failed: '%0.8Lf' is not greater than '%0.8Lf'.", greater, lesser);
1623 | }
1624 | }
1625 | void assert_greater_str(const char *greater, const char *lesser, char *file, const int line)
1626 | {
1627 | if((greater == NULL && lesser != NULL) ||
1628 | (greater == NULL && lesser == NULL) ||
1629 | (greater != NULL && lesser != NULL && strcmp(greater, lesser) <= 0))
1630 | {
1631 | register_fail(file, line, "Assert greater failed: '%s' is not greater than '%s'.", greater, lesser);
1632 | }
1633 | }
1634 |
1635 | void assert_greater_wstr(const wchar_t *greater, const wchar_t *lesser, char *file, const int line)
1636 | {
1637 | if((greater == NULL && lesser != NULL) ||
1638 | (greater == NULL && lesser == NULL) ||
1639 | (greater != NULL && lesser != NULL && wcscmp(greater, lesser) <= 0))
1640 | {
1641 | register_fail(file, line, "Assert greater failed: '%ls' is not greater than '%ls'.", greater, lesser);
1642 | }
1643 | }
1644 |
1645 | /** Triggered when attempting to compare using an unsupported data type. */
1646 | void assert_greater(const void *greater, const void *lesser, char *file, const int line)
1647 | {
1648 | register_fail(file, line, "Assert greater failed: unsupported data type.");
1649 | }
1650 |
1651 | void assert_greater_precision(const long double greater,
1652 | const long double lesser,
1653 | const long double epsilon,
1654 | char * file,
1655 | const int line)
1656 | {
1657 | if(fabsl(greater - lesser) <= epsilon || greater < lesser)
1658 | {
1659 | register_fail(file, line, "Assert greater failed: '%0.8Lf' is not greater than '%0.8Lf'.", greater, lesser);
1660 | }
1661 | }
1662 |
1663 | void assert_greater_equal_ch(const char ge, const char le, char *file, const int line)
1664 | {
1665 | if(ge < le)
1666 | {
1667 | register_fail(file, line, "Assert greater or equal failed: '%c' is lesser than '%c'.", ge, le);
1668 | }
1669 | }
1670 |
1671 | void assert_greater_equal_sch (const signed char ge, const signed char le, char *file, const int line)
1672 | {
1673 | if(ge < le)
1674 | {
1675 | register_fail(file, line, "Assert greater or equal failed: '%c' is lesser than '%c'.", ge, le);
1676 | }
1677 | }
1678 |
1679 | void assert_greater_equal_uch (const unsigned char ge, const unsigned char le, char *file, const int line)
1680 | {
1681 | if(ge < le)
1682 | {
1683 | register_fail(file, line, "Assert greater or equal failed: '%c' is lesser than '%c'.", ge, le);
1684 | }
1685 | }
1686 |
1687 | void assert_greater_equal_int (const intmax_t ge, const intmax_t le, char *file, const int line)
1688 | {
1689 | if(ge < le)
1690 | {
1691 | register_fail(file, line, "Assert greater or equal failed: '%ld' is lesser than '%ld'.", ge, le);
1692 | }
1693 | }
1694 |
1695 | void assert_greater_equal_uint(const uintmax_t ge, const uintmax_t le, char *file, const int line)
1696 | {
1697 | if(ge < le)
1698 | {
1699 | register_fail(file, line, "Assert greater or equal failed: '%ld' is lesser than '%ld'.", ge, le);
1700 | }
1701 | }
1702 |
1703 | /**
1704 | * Tests the equality of two floating point numbers.
1705 | *
1706 | * @param ge The value that is expected to be greater or equal to the second value.
1707 | * @param le The value that is expected to be less than or equal to the first value.
1708 | *
1709 | * @remarks It is important to known that this test uses the epsilon macro from float.h
1710 | * in its equality test. It is therefore often better to use assert_greater_equal_precision()
1711 | * and provide the application specific epsilon.
1712 | */
1713 | void assert_greater_equal_dbl(const long double ge, const long double le, char *file, const int line)
1714 | {
1715 | if(fabsl(ge - le) > LDBL_EPSILON && ge < le)
1716 | {
1717 | register_fail(file, line, "Assert greater or equal failed: '%0.8Lf' is lesser than '%0.8Lf'.", ge, le);
1718 | }
1719 | }
1720 |
1721 | void assert_greater_equal_str(const char *ge, const char *le, char *file, const int line)
1722 | {
1723 | if((ge == NULL && le != NULL) ||
1724 | (ge != NULL && le != NULL && strcmp(ge, le) < 0))
1725 | {
1726 | register_fail(file, line, "Assert greater or equal failed: '%s' is lesser than '%s'.", ge, le);
1727 | }
1728 | }
1729 |
1730 | void assert_greater_equal_wstr(const wchar_t *ge, const wchar_t *le, char *file, const int line)
1731 | {
1732 | if((ge == NULL && le != NULL) ||
1733 | (ge != NULL && le != NULL && wcscmp(ge, le) < 0))
1734 | {
1735 | register_fail(file, line, "Assert greater or equal failed: '%ls' is lesser than '%ls'.", ge, le);
1736 | }
1737 | }
1738 | void assert_greater_equal(const void *ge, const void *le, char *file, const int line)
1739 | {
1740 | register_fail(file, line, "Assert greater or equal failed: unsupported data type.");
1741 | }
1742 |
1743 | void assert_greater_equal_precision(long double ge,
1744 | long double le,
1745 | long double epsilon,
1746 | char *file,
1747 | int line)
1748 | {
1749 | if(fabsl(ge - le) > epsilon && ge < le)
1750 | {
1751 | register_fail(file, line, "Assert greater or equal failed: '%0.8Lf' is lesser than '%0.8Lf'.", ge, le);
1752 | }
1753 | }
1754 |
1755 | void assert_less_ch(const char lesser, const char greater, char *file, const int line)
1756 | {
1757 | if(lesser >= greater)
1758 | {
1759 | register_fail(file, line, "Assert less failed: '%c' is not lesser then '%c'.", lesser, greater);
1760 | }
1761 | }
1762 |
1763 | void assert_less_sch(const signed char lesser, const signed char greater, char *file, const int line)
1764 | {
1765 | if(lesser >= greater)
1766 | {
1767 | register_fail(file, line, "Assert less failed: '%c' is not lesser then '%c'.", lesser, greater);
1768 | }
1769 | }
1770 |
1771 | void assert_less_uch(const unsigned char lesser, const unsigned char greater, char *file, const int line)
1772 | {
1773 | if(lesser >= greater)
1774 | {
1775 | register_fail(file, line, "Assert less failed: '%c' is not lesser then '%c'.", lesser, greater);
1776 | }
1777 | }
1778 |
1779 | void assert_less_int(const intmax_t lesser, const intmax_t greater, char *file, const int line)
1780 | {
1781 | if(lesser >= greater)
1782 | {
1783 | register_fail(file, line, "Assert less failed: '%ld' is not lesser then '%ld'.", lesser, greater);
1784 | }
1785 | }
1786 |
1787 | void assert_less_uint(const uintmax_t lesser, const uintmax_t greater, char *file, const int line)
1788 | {
1789 | if(lesser >= greater)
1790 | {
1791 | register_fail(file, line, "Assert less failed: '%ld' is not lesser then '%ld'.", lesser, greater);
1792 | }
1793 | }
1794 |
1795 | /**
1796 | * Tests the equality of two floating point numbers.
1797 | *
1798 | * @param lesser The value that is expected to be lesser.
1799 | * @param greater The value that is expected to be greater.
1800 | *
1801 | * @remarks It is important to known that this test uses the epsilon macro from float.h
1802 | * in its equality test. It is therefore often better to use assert_greater_precision()
1803 | * and provide the application specific epsilon.
1804 | */
1805 | void assert_less_dbl(const long double lesser, const long double greater, char *file, const int line)
1806 | {
1807 | if(fabsl(greater - lesser) <= LDBL_EPSILON || lesser > greater)
1808 | {
1809 | register_fail(file, line, "Assert less failed: '%0.8Lf' is not lesser then '%0.8Lf'.", lesser, greater);
1810 | }
1811 | }
1812 |
1813 | void assert_less_str(const char *lesser, const char *greater, char *file, const int line)
1814 | {
1815 | if((greater == NULL && lesser != NULL) ||
1816 | (greater == NULL && lesser == NULL) ||
1817 | (greater != NULL && lesser != NULL && strcmp(lesser, greater) >= 0))
1818 | {
1819 | register_fail(file, line, "Assert less failed: '%s' is not lesser then '%s'.", lesser, greater);
1820 | }
1821 | }
1822 |
1823 | void assert_less_wstr(const wchar_t *lesser, const wchar_t *greater, char *file, const int line)
1824 | {
1825 | if((greater == NULL && lesser != NULL) ||
1826 | (greater == NULL && lesser == NULL) ||
1827 | (greater != NULL && lesser != NULL && wcscmp(lesser, greater) >= 0))
1828 | {
1829 | register_fail(file, line, "Assert less failed: '%ls' is not lesser then '%ls'.", lesser, greater);
1830 | }
1831 | }
1832 |
1833 | /** Triggered when attempting to compare using an unsupported data type. */
1834 | void assert_less(const void *lesser, const void *greater, char *file, const int line)
1835 | {
1836 | register_fail(file, line, "Assert less failed: unsupported data type.");
1837 | }
1838 |
1839 | void assert_less_precision(const long double lesser,
1840 | const long double greater,
1841 | const long double epsilon,
1842 | char *file,
1843 | const int line)
1844 | {
1845 | if(fabsl(lesser - greater) <= epsilon || lesser > greater)
1846 | {
1847 | register_fail(file, line, "Assert less failed: '%0.8Lf' is not lesser then '%0.8Lf'.", lesser, greater);
1848 | }
1849 | }
1850 |
1851 | void assert_less_equal_ch(const char le, const char ge, char *file, const int line)
1852 | {
1853 | if(le > ge)
1854 | {
1855 | register_fail(file, line, "Assert less or equal failed: '%c' is greater then '%c'.", le, ge);
1856 | }
1857 | }
1858 |
1859 | void assert_less_equal_sch (const signed char le, const signed char ge, char *file, const int line)
1860 | {
1861 | if(le > ge)
1862 | {
1863 | register_fail(file, line, "Assert less or equal failed: '%c' is greater then '%c'.", le, ge);
1864 | }
1865 | }
1866 |
1867 | void assert_less_equal_uch (const unsigned char le, const unsigned char ge, char *file, const int line)
1868 | {
1869 | if(le > ge)
1870 | {
1871 | register_fail(file, line, "Assert less or equal failed: '%c' is greater then '%c'.", le, ge);
1872 | }
1873 | }
1874 |
1875 | void assert_less_equal_int (const intmax_t le, const intmax_t ge, char *file, const int line)
1876 | {
1877 | if(le > ge)
1878 | {
1879 | register_fail(file, line, "Assert less or equal failed: '%ld' is greater then '%ld'.", le, ge);
1880 | }
1881 | }
1882 |
1883 | void assert_less_equal_uint(const uintmax_t le, const uintmax_t ge, char *file, const int line)
1884 | {
1885 | if(le > ge)
1886 | {
1887 | register_fail(file, line, "Assert less or equal failed: '%ld' is greater then '%ld'.", le, ge);
1888 | }
1889 | }
1890 |
1891 | /**
1892 | * Tests the equality of two floating point numbers.
1893 | *
1894 | * @param le The value that is expected to be lesser or equal to the second value.
1895 | * @param ge The value that is expected to be greater than or equal to the first value.
1896 | *
1897 | * @remarks It is important to known that this test uses the epsilon macro from float.h
1898 | * in its equality test. It is therefore often better to use assert_greater_equal_precision()
1899 | * and provide the application specific epsilon.
1900 | */
1901 | void assert_less_equal_dbl(const long double le, const long double ge, char *file, const int line)
1902 | {
1903 | if(fabsl(ge - le) > LDBL_EPSILON && le > ge)
1904 | {
1905 | register_fail(file, line, "Assert less or equal failed: '%0.8Lf' is greater then '%0.8Lf'.", le, ge);
1906 | }
1907 | }
1908 |
1909 | void assert_less_equal_str(const char *le, const char *ge, char *file, const int line)
1910 | {
1911 | if((ge == NULL && le != NULL) ||
1912 | (ge != NULL && le != NULL && strcmp(le, ge) > 0))
1913 | {
1914 | register_fail(file, line, "Assert less or equal failed: '%s' is greater then '%s'.", le, ge);
1915 | }
1916 | }
1917 |
1918 | void assert_less_equal_wstr(const wchar_t *le, const wchar_t *ge, char *file, const int line)
1919 | {
1920 | if((ge == NULL && le != NULL) ||
1921 | (ge != NULL && le != NULL && wcscmp(le, ge) > 0))
1922 | {
1923 | register_fail(file, line, "Assert less or equal failed: '%ls' is greater then '%ls'.", le, ge);
1924 | }
1925 | }
1926 | void assert_less_equal(const void *le, const void *ge, char *file, const int line)
1927 | {
1928 | register_fail(file, line, "Assert less or equal failed: unsupported data type.");
1929 | }
1930 |
1931 | void assert_less_equal_precision(const long double le,
1932 | const long double ge,
1933 | const long double epsilon,
1934 | char *file,
1935 | const int line)
1936 | {
1937 | if(fabsl(le - ge) > epsilon && le > ge)
1938 | {
1939 | register_fail(file, line, "Assert less or equal failed: '%0.8Lf' is greater then '%0.8Lf'.", le, ge);
1940 | }
1941 | }
1942 |
1943 |
1944 | //endregion asserts
1945 |
1946 | //region runner
1947 |
1948 | /**
1949 | * Discovers the unit test starting at the given address.
1950 | *
1951 | * @param base_test the starting address of which to start the discovery.
1952 | * @return the amount of tests found.
1953 | */
1954 | static int discover(struct unit_test **base_test)
1955 | {
1956 | int count = 0;
1957 | struct unit_test *tmp = *base_test;
1958 |
1959 | while(true)
1960 | {
1961 | if(tmp->marker == EZTEST_MARKER)
1962 | {
1963 | if(strcmp(tmp->test_name, EZTEST_BASE_TEST_NAME) == 0)
1964 | {
1965 | (*base_test)++;
1966 | tmp++;
1967 | continue;
1968 | }
1969 | tmp++;
1970 | count++;
1971 | }
1972 | else
1973 | {
1974 | break;
1975 | }
1976 | }
1977 | if(!options->quiet)
1978 | {
1979 | printf("Test discovery finished, found %d tests.\n\n", count);
1980 | }
1981 | return count;
1982 | }
1983 |
1984 | static bool should_skip(const struct unit_test *test)
1985 | {
1986 | if(!options->skip || skip_list == NULL)
1987 | {
1988 | return false;
1989 | }
1990 | char *skip_list_cp = malloc((strlen(skip_list) + 1) * sizeof(char));
1991 | if(skip_list_cp == NULL)
1992 | {
1993 | return false;
1994 | }
1995 | strcpy(skip_list_cp, skip_list);
1996 |
1997 | char *token;
1998 | token = strtok(skip_list_cp, separator);
1999 | while(token != NULL)
2000 | {
2001 | if(strcmp(token, test->test_suite) == 0)
2002 | {
2003 | free(skip_list_cp);
2004 | return true;
2005 | }
2006 | token = strtok(NULL, separator);
2007 | }
2008 | free(skip_list_cp);
2009 |
2010 | return false;
2011 | }
2012 |
2013 | /**
2014 | * Registers the current result by increasing the result counter
2015 | * and printing the result message.
2016 | */
2017 | static void register_result(const unsigned int time)
2018 | {
2019 | if(result == fail)
2020 | {
2021 | fail_count++;
2022 | print_failed(current, time);
2023 | }
2024 | else if(result == skip)
2025 | {
2026 | skip_count++;
2027 | print_skipped(current, time);
2028 | }
2029 | else
2030 | {
2031 | pass_count++;
2032 | print_passed(current, time);
2033 | }
2034 | }
2035 |
2036 | /**
2037 | * Prints the total test time as long as the quiet options has not been set.
2038 | *
2039 | * @param t The time
2040 | */
2041 | static void print_test_time(const unsigned int t)
2042 | {
2043 | if(options->quiet) return;
2044 |
2045 | printf("Total elapsed time: %dms\n", t);
2046 | }
2047 |
2048 | /**
2049 | * Executes the passed test, running the setup and teardown functions
2050 | * if they are not @code NULL @endcode
2051 | *
2052 | * @param test The test to run.
2053 | * @return The execution time in milliseconds.
2054 | */
2055 | static unsigned int execute(const struct unit_test *test)
2056 | {
2057 | clock_t t;
2058 | t = clock();
2059 | if(test->setup_fn != NULL)
2060 | {
2061 | test->setup_fn();
2062 | }
2063 | test->run_fn();
2064 | if(test->teardown_fn != NULL)
2065 | {
2066 | test->teardown_fn();
2067 | }
2068 | t = clock() - t;
2069 | return ((unsigned int)((((float)t) / CLOCKS_PER_SEC) * 1000));
2070 | }
2071 |
2072 | /** To be executed on signal: SIGSEGV */
2073 | static void onSegfault(int signum)
2074 | {
2075 | register_fail("SIGNAL", signum, "Segmentation fault encountered.");
2076 | register_result(0);
2077 |
2078 | signal(signum, SIG_DFL);
2079 | kill(getpid(), signum);
2080 | }
2081 |
2082 | /**
2083 | * Starts running tests.
2084 | *
2085 | * @param opts Application options (not NULL).
2086 | * @return The amount of failed tests. If the runner encounters an error,
2087 | * then EZTEST_EXIT_FAILURE is returned.
2088 | */
2089 | int eztest_run(struct options *opts)
2090 | {
2091 | assert(opts != NULL);
2092 |
2093 | options = opts;
2094 | current = &EZTEST_STRUCT_NAME(eztest_base_suite, eztest_base_test);
2095 |
2096 | if(options->sigsegv)
2097 | {
2098 | signal(SIGSEGV, onSegfault);
2099 | }
2100 |
2101 | assert_buffer = malloc(ASSERT_BUFFER_SIZE);
2102 | if(assert_buffer == NULL)
2103 | {
2104 | fprintf(stderr, "Failed to allocated memory for the assert buffer.");
2105 | return EZTEST_EXIT_FAILURE;
2106 | }
2107 |
2108 | const int count = discover(¤t);
2109 |
2110 | unsigned int test_time = 0; // Time for the current test.
2111 | unsigned int total_time = 0; // Total time for all tests.
2112 |
2113 | for (int i = 0; i < count; i++, current++)
2114 | {
2115 | if(should_skip(current))
2116 | {
2117 | result = skip;
2118 | }
2119 | else
2120 | {
2121 | // Reset buffer
2122 | assert_buffer[0] = '\0';
2123 | assert_buffer_len = 0;
2124 | // Reset result
2125 | result = undefined; // Reset result before running new test.
2126 | // Run test
2127 | test_time = execute(current);
2128 | total_time += test_time;
2129 | }
2130 | register_result(test_time);
2131 | }
2132 | print_report();
2133 |
2134 | if(options->timer)
2135 | {
2136 | print_test_time(total_time);
2137 | }
2138 |
2139 | free(assert_buffer);
2140 |
2141 | return fail_count;
2142 | }
2143 |
2144 | //endregion runner
2145 |
2146 |
2147 | #endif // TEST_RUNNER
2148 |
2149 | #endif // EZTEST_H
2150 |
2151 |
--------------------------------------------------------------------------------
/eztest/runner.c:
--------------------------------------------------------------------------------
1 | /**
2 |
3 | * @author havardt
4 | *
5 | * @license MIT
6 | *
7 | */
8 |
9 | #define TEST_RUNNER
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include "eztest.h"
19 |
20 | /* Macros */
21 |
22 | #define __PROGRAM_NAME__ "EzTest"
23 | #define __PROGRAM_VERSION__ "3.0.0"
24 | #define __PROGRAM_AUTHOR__ "havardt"
25 | #define __PROGRAM_WEBSITE__ "https://github.com/havardt/EzTest"
26 |
27 | #define DEFAULT_OPTIONS { .no_color = false, .timer = false, .quiet = false, .skip = false, .sigsegv = false }
28 |
29 |
30 | /* Prototypes */
31 |
32 | void print_usage ( FILE * );
33 | int parse_opt ( struct options *, int );
34 | int handle_opts ( struct options *, int, char ** );
35 |
36 |
37 | /* Globals */
38 |
39 | const struct option long_opts[] = {
40 | {"help" , no_argument , NULL, 'h'},
41 | {"version" , no_argument , NULL, 'v'},
42 | {"no-color", no_argument , NULL, 'c'},
43 | {"timer" , no_argument , NULL, 't'},
44 | {"quiet" , no_argument , NULL, 'q'},
45 | {"skip" , required_argument, NULL, 's'},
46 | {"SIGSEGV" , no_argument , NULL, 'f'},
47 | {0}
48 | };
49 |
50 | struct options opts = DEFAULT_OPTIONS;
51 |
52 |
53 | int main(int argc, char **argv)
54 | {
55 | if(handle_opts(&opts, argc, argv) != EZTEST_RESULT_OK)
56 | {
57 | return EXIT_FAILURE;
58 | }
59 |
60 | setlocale(LC_ALL, ""); // Needed to print wide chars/ strings.
61 |
62 | return (eztest_run(&opts) == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
63 | }
64 |
65 | /**
66 | * Prints program usage.
67 | *
68 | * @param fd A file descriptor representing the output location.
69 | */
70 | void print_usage(FILE *fd)
71 | {
72 | assert(fd != NULL);
73 |
74 | fprintf(fd, "\nUsage: %s [OPTIONS]\n\n"
75 | "Options:\n"
76 | " -v --version Print version number.\n"
77 | " -h --help Print help information.\n"
78 | " -c --no-color Only use default color when printing to screen.\n"
79 | " -t --timer Display execution time for each test.\n"
80 | " -q --quiet No output.\n"
81 | " -s --skip Skips all tests in the passed list of test suits.\n"
82 | " -f --SIGSEGV Segmentation fault is displayed like other test failures.\n\n",
83 | __PROGRAM_NAME__);
84 | }
85 |
86 | /**
87 | * Parse application options.
88 | *
89 | * @param opts Pointer to current options.
90 | * @param opt The option to parse.
91 | * @return: On success @code RESULT_OK @endcode; otherwise @code RESULT_ERR @endcode .
92 | */
93 | int parse_opt(struct options *opts, const int opt)
94 | {
95 | switch(opt)
96 | {
97 | case 'v':
98 | printf("%s version %s\n", __PROGRAM_NAME__, __PROGRAM_VERSION__);
99 | exit(EXIT_SUCCESS);
100 |
101 | case 'h':
102 | print_usage(stdout);
103 | exit(EXIT_SUCCESS);
104 |
105 | case 'c':
106 | opts->no_color = true;
107 | break;
108 |
109 | case 't':
110 | opts->timer = true;
111 | break;
112 |
113 | case 'q':
114 | opts->quiet = true;
115 | break;
116 |
117 | case 's':
118 | opts->skip = true;
119 | skip_list = optarg;
120 | break;
121 |
122 | case 'f':
123 | opts->sigsegv = true;
124 | break;
125 |
126 | default:
127 | return EZTEST_RESULT_ERR;
128 | }
129 | return EZTEST_RESULT_OK;
130 | }
131 |
132 | /**
133 | * Processes application options by parsing given options and setting the
134 | * appropriate options.
135 | *
136 | * @param opts Pointer to application options struct.
137 | * @param argc Argument count.
138 | * @param argv Arguments as strings.
139 | * @return @code RESULT_OK @endcode on success and @code RESULT_ERR @endocode on failure.
140 | * Failure may occur if the user has given an unknown option.
141 | */
142 | int handle_opts(struct options *opts, const int argc, char **argv)
143 | {
144 | int opt, opt_index;
145 | while((opt = getopt_long(argc, argv, "vhctqfs:", long_opts, &opt_index)) != -1)
146 | {
147 | if(parse_opt(opts, opt) != EZTEST_RESULT_OK)
148 | {
149 | print_usage(stderr);
150 | return EZTEST_RESULT_ERR;
151 | }
152 | }
153 | return EZTEST_RESULT_OK;
154 | }
155 |
156 |
--------------------------------------------------------------------------------