├── .gitignore ├── .travis.yml ├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── Makefile.am ├── Makefile.am.dist ├── NEWS ├── README ├── README.md ├── autogen.sh ├── cmockery2.pc.in ├── cmockery2.spec ├── configure.ac ├── doc ├── coverage.md ├── html2wiki.sh ├── index.html └── usage.md ├── makerpm.sh ├── packages ├── FreeBSD │ ├── .gitignore │ ├── Makefile │ ├── distinfo │ ├── pkg-descr │ ├── pkg-message │ └── pkg-plist ├── deb.sh ├── deb │ ├── README │ ├── changelog │ ├── compat │ ├── control │ ├── copyright │ ├── docs │ ├── libcmockery-dev.dirs │ ├── libcmockery-dev.install │ ├── libcmockery0.dirs │ ├── libcmockery0.install │ └── rules └── rpm.sh ├── src ├── cmockery.c ├── cmockery │ ├── cmockery.h │ ├── cmockery_override.h │ └── pbc.h └── example │ ├── allocate_module.c │ ├── allocate_module_test.c │ ├── assert_macro.c │ ├── assert_macro_test.c │ ├── assert_module.c │ ├── assert_module_test.c │ ├── calculator.c │ ├── calculator_test.c │ ├── customer_database.c │ ├── customer_database_test.c │ ├── database.h │ ├── game.c │ ├── game_test.c │ ├── key_value.c │ ├── key_value.h │ ├── key_value_test.c │ ├── mem_test.c │ ├── product_database.c │ ├── product_database_test.c │ ├── realloc_test.c │ └── run_tests.c └── windows └── makefile /.gitignore: -------------------------------------------------------------------------------- 1 | ar-lib 2 | aclocal.m4 3 | compile 4 | Makefile.in 5 | autom4te.cache/ 6 | config.guess 7 | config.sub 8 | configure 9 | depcomp 10 | install-sh 11 | ltmain.sh 12 | m4/ 13 | missing 14 | src/cmockery/config.h.in* 15 | test-driver 16 | *.sublime-* -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | compiler: 3 | - gcc 4 | - clang 5 | os: 6 | - linux 7 | - osx 8 | sudo: false 9 | env: 10 | matrix: 11 | - GCOV_FLAG=--enable-gcov 12 | - GCOV_FLAG= 13 | script: 14 | - ./autogen.sh && ./configure $GCOV_FLAG && make check 15 | 16 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | opensource@google.com 2 | lpabon@redhat.com 3 | 4 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | Mon Apr 13 2015 Luis Pabón, Jr. 2 | * Version v1.3.9 3 | * Minor bug fixes(thanks kerrigan29a and RocFang) 4 | * FreeBSD package support (thanks harshavardhana) 5 | 6 | Tue Jun 17 2014 Luis Pabón, Jr. 7 | * Version v1.3.8 8 | * Support for clang (thanks kerrigan29a@gmail.com) 9 | * make check now works on source created by make dist 10 | 11 | Mon Mar 21 2014 Luis Pabon, Jr. 12 | * Version v1.3.7 13 | * Fixed memory check functions 14 | * Added new memory unit test 15 | 16 | Thu Mar 21 2014 Luis Pabon, Jr. 17 | * Version v1.3.6 18 | * Travis and RPM changes 19 | * PPC Support 20 | 21 | Thu Mar 13 2014 Luis Pabon, Jr. 22 | * Version v1.3.4 23 | * Initial Fedora release 24 | 25 | Tue Mar 11 07:33:00 2014 Luis Pabon, Jr. 26 | * cmockery: version 1.3.2 27 | * Fixed issue where make dist was not including autoget.sh - jclift 28 | * Various autoconf fixes 29 | 30 | Wed Feb 18 10:30:00 2014 Luis Pabon, Jr. 31 | * cmockery: version 1.2 32 | * Many configure.ac fixes 33 | * Added CFLAGS to output Gcov information 34 | * Added Programming by contract 35 | * Support to output Junit XML 36 | 37 | Wed Jan 22 16:44:14 2014 Luis Pabon, Jr. 38 | * cmockery: version 0.9 39 | * Added cmockery_override.h to be able to override standard tools 40 | * Changed include directory from google to cmockery 41 | 42 | Mon Sep 15 17:21:22 2008 Google Inc. 43 | * cmockery: version 0.12 44 | * Made it possible to specify additional compiler, lib tool and link 45 | flags on Windows. 46 | * Added Windows makefile to the tar ball. 47 | 48 | Fri Aug 29 10:50:46 2008 Google Inc. 49 | 50 | * cmockery: version 0.11 51 | * Made it possible to specify executable, library and object output 52 | directories. 53 | 54 | Tue Aug 26 10:18:02 2008 Google Inc. 55 | 56 | * cmockery: initial release: 57 | A lightweight library to simplify and generalize the process of 58 | writing unit tests for C applications. 59 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Please refer to doc/usage.md 2 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ## This is a boilerplate file for Google opensource projects. 2 | ## To make it useful, replace <> with actual text for your project. 3 | ## Also, look at comments with "## double hashes" to see if any are worth 4 | ## uncommenting or modifying. 5 | 6 | ## Process this file with automake to produce Makefile.in 7 | 8 | # Make sure that when we re-make ./configure, we get the macros we need 9 | ACLOCAL_AMFLAGS = -I m4 10 | 11 | # This is so we can #include 12 | AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/cmockery 13 | 14 | cmockeryincludedir = $(includedir)/cmockery 15 | ## The .h files you want to install (that is, .h files that people 16 | ## who install this package can include in their own applications.) 17 | cmockeryinclude_HEADERS = src/cmockery/cmockery_override.h\ 18 | src/cmockery/cmockery.h\ 19 | src/cmockery/pbc.h 20 | 21 | docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION) 22 | ## This is for HTML and other documentation you want to install. 23 | ## Add your documentation files (in doc/) in addition to these 24 | ## top-level boilerplate files. Also add a TODO file if you have one. 25 | nodist_doc_DATA = AUTHORS COPYING ChangeLog doc/index.html doc/usage.md \ 26 | doc/coverage.md 27 | 28 | if HAVE_PKG_CONFIG 29 | pkgconfigdir = $(libdir)/pkgconfig 30 | pkgconfig_DATA = @PACKAGE_NAME@.pc 31 | endif 32 | 33 | ## The libraries (.so's) you want to install 34 | lib_LTLIBRARIES = 35 | 36 | ## unittests you want to run when people type 'make check'. 37 | ## TESTS is for binary unittests, check_SCRIPTS for script-based unittests. 38 | ## TESTS_ENVIRONMENT sets environment variables for when you run unittest, 39 | ## but it only seems to take effect for *binary* unittests (argh!) 40 | TESTS = 41 | check_SCRIPTS = 42 | noinst_SCRIPTS = 43 | 44 | 45 | ## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS 46 | 47 | lib_LTLIBRARIES += libcmockery.la 48 | libcmockery_la_SOURCES = src/cmockery/config.h\ 49 | src/cmockery.c\ 50 | src/cmockery/cmockery_override.h\ 51 | src/cmockery/cmockery.h\ 52 | src/cmockery/pbc.h 53 | libcmockery_la_CFLAGS = -I$(top_srcdir)/src/cmockery -DHAVE_CONFIG_H -Wall \ 54 | -Werror 55 | 56 | noinst_PROGRAMS = calculator 57 | nodist_calculator_SOURCES = src/example/calculator.c src/cmockery/config.h 58 | calculator_CFLAGS = 59 | 60 | unit_test_CFLAGS = -I$(top_srcdir)/src/cmockery \ 61 | -I$(top_srcdir)/src/example -DUNIT_TESTING=1 \ 62 | -Wall -Werror -DHAVE_CONFIG_H 63 | 64 | noinst_PROGRAMS += calculator_test 65 | TESTS += calculator_test 66 | nodist_calculator_test_SOURCES = src/example/calculator_test.c \ 67 | $(nodist_calculator_SOURCES) 68 | calculator_test_CFLAGS = $(unit_test_CFLAGS) 69 | calculator_test_LDADD = libcmockery.la 70 | 71 | noinst_PROGRAMS += allocate_module_test 72 | # Don't add this one, it returns a fail exit status, 73 | # which is expected. TESTS += allocate_module_test 74 | nodist_allocate_module_test_SOURCES = src/example/allocate_module_test.c \ 75 | src/example/allocate_module.c 76 | allocate_module_test_CFLAGS = $(unit_test_CFLAGS) 77 | allocate_module_test_LDADD = libcmockery.la 78 | 79 | noinst_PROGRAMS += assert_macro_test 80 | TESTS += assert_macro_test 81 | nodist_assert_macro_test_SOURCES = src/example/assert_macro_test.c \ 82 | src/example/assert_macro.c 83 | assert_macro_test_CFLAGS = $(unit_test_CFLAGS) 84 | assert_macro_test_LDADD = libcmockery.la 85 | 86 | noinst_PROGRAMS += customer_database_test 87 | TESTS += customer_database_test 88 | nodist_customer_database_test_SOURCES = src/example/customer_database_test.c \ 89 | src/example/customer_database.c \ 90 | src/example/database.h 91 | customer_database_test_CFLAGS = $(unit_test_CFLAGS) 92 | customer_database_test_LDADD = libcmockery.la 93 | 94 | noinst_PROGRAMS += key_value_test 95 | TESTS += key_value_test 96 | nodist_key_value_test_SOURCES = src/example/key_value_test.c \ 97 | src/example/key_value.h \ 98 | src/example/key_value.c 99 | key_value_test_CFLAGS = $(unit_test_CFLAGS) 100 | key_value_test_LDADD = libcmockery.la 101 | 102 | noinst_PROGRAMS += product_database_test 103 | TESTS += product_database_test 104 | product_database_testdir = src/example 105 | nodist_product_database_test_SOURCES = src/example/product_database_test.c \ 106 | src/example/product_database.c \ 107 | src/example/database.h 108 | product_database_test_CFLAGS = $(unit_test_CFLAGS) 109 | product_database_test_LDADD = libcmockery.la 110 | 111 | noinst_PROGRAMS += game_test 112 | TESTS += game_test 113 | nodist_game_test_SOURCES = src/example/game_test.c src/example/game.c 114 | game_test_CFLAGS = $(unit_test_CFLAGS) 115 | game_test_LDADD = libcmockery.la 116 | 117 | noinst_PROGRAMS += run_tests 118 | TESTS += run_tests 119 | nodist_run_tests_SOURCES = src/example/run_tests.c 120 | run_tests_CFLAGS = $(unit_test_CFLAGS) 121 | run_tests_LDADD = libcmockery.la 122 | 123 | noinst_PROGRAMS += realloc_test 124 | TESTS += realloc_test 125 | nodist_realloc_test_SOURCES = src/example/realloc_test.c 126 | realloc_test_CFLAGS = $(unit_test_CFLAGS) 127 | realloc_test_LDADD = libcmockery.la 128 | 129 | noinst_PROGRAMS += mem_test 130 | TESTS += mem_test 131 | nodist_mem_test_SOURCES = src/example/mem_test.c 132 | mem_test_CFLAGS = $(unit_test_CFLAGS) 133 | mem_test_LDADD = libcmockery.la 134 | 135 | ## ^^^^ END OF RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS 136 | 137 | 138 | ## This should always include $(TESTS), but may also include other 139 | ## binaries that you compile but don't want automatically installed. 140 | noinst_PROGRAMS += $(TESTS) 141 | 142 | rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec 143 | @cd packages && ./rpm.sh ${PACKAGE} ${VERSION} 144 | 145 | deb: dist-gzip packages/deb.sh packages/deb/* 146 | @cd packages && ./deb.sh ${PACKAGE} ${VERSION} 147 | 148 | ## If you're using libtool, add 'libtool' here. Also add this rule: 149 | libtool: $(LIBTOOL_DEPS) 150 | $(SHELL) ./config.status --recheck 151 | EXTRA_DIST = autogen.sh README.md $(SCRIPTS) 152 | 153 | CLEANFILES = *.gcda *.gcno *_xunit.xml 154 | 155 | dist-hook: 156 | cp $(top_srcdir)/Makefile.am.dist $(top_distdir)/Makefile.am 157 | -------------------------------------------------------------------------------- /Makefile.am.dist: -------------------------------------------------------------------------------- 1 | ## This is a boilerplate file for Google opensource projects. 2 | ## To make it useful, replace <> with actual text for your project. 3 | ## Also, look at comments with "## double hashes" to see if any are worth 4 | ## uncommenting or modifying. 5 | 6 | ## Process this file with automake to produce Makefile.in 7 | 8 | # Make sure that when we re-make ./configure, we get the macros we need 9 | ACLOCAL_AMFLAGS = -I m4 10 | 11 | # This is so we can #include 12 | AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/cmockery 13 | 14 | cmockeryincludedir = $(includedir)/cmockery 15 | ## The .h files you want to install (that is, .h files that people 16 | ## who install this package can include in their own applications.) 17 | cmockeryinclude_HEADERS = src/cmockery/cmockery_override.h\ 18 | src/cmockery/cmockery.h\ 19 | src/cmockery/pbc.h 20 | 21 | docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION) 22 | ## This is for HTML and other documentation you want to install. 23 | ## Add your documentation files (in doc/) in addition to these 24 | ## top-level boilerplate files. Also add a TODO file if you have one. 25 | nodist_doc_DATA = AUTHORS COPYING ChangeLog 26 | 27 | if HAVE_PKG_CONFIG 28 | pkgconfigdir = $(libdir)/pkgconfig 29 | pkgconfig_DATA = @PACKAGE_NAME@.pc 30 | endif 31 | 32 | ## The libraries (.so's) you want to install 33 | lib_LTLIBRARIES = 34 | 35 | ## unittests you want to run when people type 'make check'. 36 | ## TESTS is for binary unittests, check_SCRIPTS for script-based unittests. 37 | ## TESTS_ENVIRONMENT sets environment variables for when you run unittest, 38 | ## but it only seems to take effect for *binary* unittests (argh!) 39 | TESTS = 40 | check_SCRIPTS = 41 | noinst_SCRIPTS = 42 | 43 | 44 | ## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS 45 | 46 | lib_LTLIBRARIES += libcmockery.la 47 | libcmockery_la_SOURCES = src/cmockery/config.h\ 48 | src/cmockery.c\ 49 | src/cmockery/cmockery_override.h\ 50 | src/cmockery/cmockery.h\ 51 | src/cmockery/pbc.h 52 | libcmockery_la_CFLAGS = -I$(top_srcdir)/src/cmockery -DHAVE_CONFIG_H 53 | 54 | ## ^^^^ END OF RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS 55 | 56 | ## If you're using libtool, add 'libtool' here. Also add this rule: 57 | CLEANFILES = *.gcda *.gcno *_xunit.xml 58 | libtool: $(LIBTOOL_DEPS) 59 | $(SHELL) ./config.status --recheck 60 | EXTRA_DIST = autogen.sh README.md $(SCRIPTS) 61 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lpabon/cmockery2/415181aeb971a2ea440ae51cab1300c6d46e7a45/NEWS -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | see README.md 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/lpabon/cmockery2.svg?branch=master)](https://travis-ci.org/lpabon/cmockery2) 2 | [![Join the chat at https://gitter.im/lpabon/cmockery2](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/lpabon/cmockery2?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 3 | 4 | Cmockery tests are compiled into a stand-alone executable and linked 5 | with the cmockery library, the standard C library and module being 6 | tested. Any symbols external to the module being tested should be 7 | mocked - replaced with functions that return values determined by 8 | the test - within the test application. Even though significant 9 | differences may exist between the target execution environment of a 10 | code module and the environment used to test the code the unit 11 | testing is still valid since its goal is to test the logic of a 12 | code modules at a functional level and not necessarily all of its 13 | interactions with the target execution environment. 14 | 15 | Other features: 16 | * Lightweight C Unit test with mocking support 17 | * JUnit XML report output which can be used with Jenkins 18 | * Provides design-by-contract support 19 | 20 | This project is a successor of http://code.google.com/p/cmockery-staging/ 21 | which is a successor of Google's http://code.google.com/p/cmockery/. 22 | 23 | 24 | # Documentation 25 | 26 | * [Usage Guide](doc/usage.md) 27 | * [Coverage Support with Jenkins](doc/coverage.md) 28 | 29 | # Presentations 30 | * [Devconf 2015](http://slides-lpabon.rhcloud.com/02052015_devconf_cmockery2.html) 31 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Before using, you should figure out all the .m4 macros that your 4 | # configure.m4 script needs and make sure they exist in the autoconf/ 5 | # directory. 6 | # 7 | # These are the files that this script might edit: 8 | # aclocal.m4 configure Makefile.in src/config.h.in \ 9 | # depcomp config.guess config.sub install-sh missing mkinstalldirs \ 10 | # ltmain.sh 11 | # 12 | # Here's a command you can run to see what files aclocal will import: 13 | # aclocal -I ../autoconf --output=- | sed -n 's/^m4_include..\([^]]*\).*/\1/p' 14 | 15 | rm -rf autom4te.cache > /dev/null 2>&1 16 | rm -f m4/libtool.m4 m4/lt*.m4 > /dev/null 2>&1 17 | if [ ! -d m4 ] ; then 18 | mkdir m4 19 | fi 20 | 21 | trap 'rm -f aclocal.m4.tmp' EXIT 22 | 23 | # Use version 1.9 of aclocal and automake if available. 24 | ACLOCAL=aclocal-1.9 25 | if ! env "$ACLOCAL" --version > /dev/null 2>&1 ; then 26 | ACLOCAL=aclocal 27 | fi 28 | 29 | AUTOMAKE=automake-1.9 30 | if ! env "$AUTOMAKE" --version > /dev/null 2>&1 ; then 31 | AUTOMAKE=automake 32 | fi 33 | 34 | # glibtoolize is used for Mac OS X 35 | LIBTOOLIZE=libtoolize 36 | if ! env "$LIBTOOLIZE" --version > /dev/null 2>&1 ; then 37 | LIBTOOLIZE=glibtoolize 38 | fi 39 | 40 | # aclocal tries to overwrite aclocal.m4 even if the contents haven't 41 | # changed, which is annoying when the file is not open for edit (in 42 | # p4). We work around this by writing to a temp file and just 43 | # updating the timestamp if the file hasn't change. 44 | echo "Running $ACLOCAL ..." 45 | "$ACLOCAL" --force -I m4 --output=aclocal.m4.tmp 46 | if cmp aclocal.m4.tmp aclocal.m4 > /dev/null 2>&1 ; then 47 | touch aclocal.m4 # pretend that we regenerated the file 48 | rm -f aclocal.m4.tmp 49 | else 50 | mv aclocal.m4.tmp aclocal.m4 # we did set -e above, so we die if this fails 51 | fi 52 | 53 | echo "Running autoheader ..." 54 | autoheader -f -W all 55 | echo "Running $LIBTOOLIZE ..." 56 | "$LIBTOOLIZE" --automake -c -f 57 | echo "Running autoconf ..." 58 | autoconf -f -W all,no-obsolete 59 | echo "Running automake ..." 60 | "$AUTOMAKE" -a -c -f --foreign -W all 61 | 62 | rm -rf autom4te.cache 63 | exit 0 64 | -------------------------------------------------------------------------------- /cmockery2.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: @PACKAGE_NAME@ 7 | Version: @PACKAGE_VERSION@ 8 | Description: Lightweight C unit testing framework with mocking support. 9 | 10 | Libs: -L${libdir} -lcmockery @LIBS@ 11 | Cflags: -I${includedir} -Wall -Werror -DUNIT_TESTING=1 12 | -------------------------------------------------------------------------------- /cmockery2.spec: -------------------------------------------------------------------------------- 1 | Name: cmockery2 2 | Summary: Lightweight C unit testing framework 3 | Version: 1.3.9 4 | Release: 1%{?dist} 5 | Group: System Environment/Libraries 6 | URL: https://github.com/lpabon/%{name} 7 | License: ASL 2.0 8 | Source0: https://github.com/lpabon/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz 9 | Buildroot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) 10 | BuildRequires: automake libtool pkgconfig 11 | 12 | %description 13 | Cmockery tests are compiled into a stand-alone executable and linked 14 | with the cmockery library, the standard C library and module being 15 | tested. Any symbols external to the module being tested should be 16 | mocked - replaced with functions that return values determined by 17 | the test - within the test application. Even though significant 18 | differences may exist between the target execution environment of a 19 | code module and the environment used to test the code the unit 20 | testing is still valid since its goal is to test the logic of a 21 | code modules at a functional level and not necessarily all of its 22 | interactions with the target execution environment. 23 | 24 | Other features: 25 | * Lightweight C Unit test with mocking support 26 | * JUnit XML report output which can be used with Jenkins 27 | * Provides design-by-contract support 28 | 29 | This project is a successor of http://code.google.com/p/cmockery-staging/ 30 | which is a successor of Google's http://code.google.com/p/cmockery/. 31 | 32 | %package devel 33 | Summary: Lightweight C unit testing framework 34 | Group: Development/Libraries 35 | Requires: %{name}%{?_isa} = %{version}-%{release} 36 | 37 | %description devel 38 | Cmockery tests are compiled into a stand-alone executable and linked 39 | with the Cmockery library, the standard C library and module being 40 | tested. Any symbols external to the module being tested should be 41 | mocked - replaced with functions that return values determined by 42 | the test - within the test application. Even though significant 43 | differences may exist between the target execution environment of a 44 | code module and the environment used to test the code the unit 45 | testing is still valid since its goal is to test the logic of a 46 | code modules at a functional level and not necessarily all of its 47 | interactions with the target execution environment. 48 | 49 | Other features: 50 | * Lightweight C Unit test with mocking support 51 | * JUnit XML report output which can be used with Jenkins 52 | * Provides design-by-contract support 53 | 54 | This project is a successor of http://code.google.com/p/cmockery-staging/ 55 | which is a successor of Google's http://code.google.com/p/cmockery/. 56 | 57 | Package provides necessary headers for C unit test development 58 | 59 | %prep 60 | %setup -q 61 | 62 | %build 63 | ./autogen.sh 64 | %configure 65 | make %{?_smp_mflags} 66 | 67 | %install 68 | %{__rm} -rf %{buildroot} 69 | %if ( 0%{?rhel} && 0%{?rhel} < 6 ) 70 | #EL5 does not have the make_install macro 71 | make install DESTDIR=%{buildroot} 72 | %else 73 | %make_install 74 | %endif 75 | 76 | %check 77 | make check 78 | 79 | %post -p /sbin/ldconfig 80 | 81 | %postun -p /sbin/ldconfig 82 | 83 | %clean 84 | %{__rm} -rf %{buildroot} 85 | 86 | %files 87 | %{_docdir}/cmockery* 88 | %{_libdir}/libcmockery.so.* 89 | 90 | %files devel 91 | %{_includedir}/cmockery* 92 | %{_libdir}/libcmockery.so 93 | %{_libdir}/pkgconfig/cmockery2.pc 94 | %exclude %{_libdir}/libcmockery.a 95 | %exclude %{_libdir}/libcmockery.la 96 | 97 | %changelog 98 | * Mon Apr 13 2015 Luis Pabón, Jr. - 1.3.9-1 99 | - Minor bug fixes 100 | 101 | * Tue Jun 17 2014 Luis Pabón, Jr. - 1.3.8-1 102 | - clang support 103 | 104 | * Mon Mar 24 2014 Luis Pabon, Jr. - 1.3.7-1 105 | - Fixed memory check functions 106 | - Added new memory unit test 107 | 108 | * Fri Mar 21 2014 Luis Pabon, Jr. - 1.3.6-1 109 | - PPC fixes 110 | 111 | * Thu Mar 13 2014 Luis Pabon, Jr. - 1.3.4-1 112 | - Initial Fedora release 113 | 114 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | ## To make it useful, replace <> with actual text for your project. 2 | ## Also, look at comments with "## double hashes" to see if any are worth 3 | ## uncommenting or modifying. 4 | 5 | ## Process this file with autoconf to produce configure. 6 | ## In general, the safest way to proceed is to run ./autogen.sh 7 | 8 | # make sure we're interpreted by some minimal autoconf 9 | AC_PREREQ(2.57) 10 | 11 | AC_INIT(cmockery2, 1.3.9, lpabon@redhat.com) 12 | AC_CONFIG_AUX_DIR([.]) 13 | 14 | # The argument here is just something that should be in the current directory 15 | # (for sanity checking) 16 | AC_CONFIG_SRCDIR(README.md) 17 | AM_INIT_AUTOMAKE 18 | AC_GNU_SOURCE 19 | m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) 20 | AC_CONFIG_HEADERS(src/cmockery/config.h) 21 | 22 | # Checks for programs. 23 | AC_PROG_CC 24 | AC_PROG_CPP 25 | AC_PROG_CXX 26 | 27 | # Check if CC is linked to CLANG 28 | AC_MSG_CHECKING([if compiling with clang]) 29 | AC_COMPILE_IFELSE( 30 | [AC_LANG_PROGRAM([], [[ 31 | #ifndef __clang__ 32 | not clang 33 | #endif 34 | ]])], 35 | [CLANG=yes], [CLANG=no]) 36 | AC_MSG_RESULT([$CLANG]) 37 | AM_CONDITIONAL(CLANG, test "$CLANG" = yes) 38 | 39 | AM_CONDITIONAL(GCC, test "$GCC" = yes) # let the Makefile know if we're gcc 40 | 41 | OLD_CFLAGS=$CFLAGS 42 | CFLAGS= 43 | 44 | # Enable gcov suport. 45 | AC_ARG_ENABLE([gcov], 46 | AC_HELP_STRING([--enable-gcov], 47 | [build binaries with gcov support]), [use_gcov=yes], [use_gcov=no]) 48 | if test "x$use_gcov" = xyes; then 49 | if test "x$CLANG" = xyes; then 50 | CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage" 51 | else 52 | CFLAGS="$CFLAGS --coverage" 53 | fi 54 | fi 55 | AM_CONDITIONAL(GCOV, test "$use_gcov" = yes) 56 | 57 | if test "x$use_gcov" = xyes; then 58 | CFLAGS="$CFLAGS -O0 -g -Wall" 59 | else 60 | CFLAGS="$CFLAGS $OLD_CFLAGS" 61 | fi 62 | 63 | # Uncomment this if you'll be exporting libraries (.so's) 64 | # Use AC_PROG_LIBTOOL instead of LT_INIT because 65 | # we need it to support EL5 66 | AC_PROG_LIBTOOL 67 | AC_SUBST(LIBTOOL_DEPS) 68 | 69 | # Check whether some low-level functions/files are available 70 | AC_HEADER_STDC 71 | 72 | # For older versions of automake 73 | AM_PROG_CC_C_O 74 | 75 | # Here are some examples of how to check for the existence of a fn or file 76 | ##AC_CHECK_FUNCS(memmove) 77 | ##AC_CHECK_HEADERS(sys/resource.h) 78 | AC_CHECK_FUNCS(setjmp) 79 | AC_CHECK_FUNCS(longjmp) 80 | AC_CHECK_FUNCS(strcmp) 81 | AC_CHECK_FUNCS(strcpy) 82 | AC_CHECK_FUNCS(memcpy) 83 | AC_CHECK_FUNCS(memset) 84 | AC_CHECK_FUNCS(malloc) 85 | AC_CHECK_FUNCS(calloc) 86 | AC_CHECK_FUNCS(free) 87 | AC_CHECK_FUNCS(exit) 88 | AC_CHECK_FUNCS(signal) 89 | AC_CHECK_FUNCS(printf) 90 | AC_CHECK_FUNCS(fprintf) 91 | AC_CHECK_FUNCS(snprintf) 92 | AC_CHECK_FUNCS(vsnprintf) 93 | AC_CHECK_FUNCS(gettimeofday) 94 | AC_CHECK_FUNCS(strsignal) 95 | AC_CHECK_HEADERS(assert.h) 96 | AC_CHECK_HEADERS(malloc.h) 97 | AC_CHECK_HEADERS(setjmp.h) 98 | AC_CHECK_HEADERS(stdarg.h) 99 | AC_CHECK_HEADERS(stddef.h) 100 | AC_CHECK_HEADERS(stdio.h) 101 | AC_CHECK_HEADERS(stdlib.h) 102 | AC_CHECK_HEADERS(string.h) 103 | AC_CHECK_HEADERS(signal.h) 104 | AC_CHECK_HEADERS(inttypes.h) 105 | AC_CHECK_HEADERS(stdint.h) 106 | AC_CHECK_HEADERS(sys/time.h) 107 | AC_CHECK_TYPES([unsigned long long, uintmax_t, uintptr_t]) 108 | 109 | AC_PREFIX_DEFAULT(/usr) 110 | 111 | # If pkg-config 112 | AC_CHECK_PROG(PKG_CONFIG, pkg-config, yes) 113 | AM_CONDITIONAL([HAVE_PKG_CONFIG], [test "x$PKG_CONFIG" != "x"]) 114 | AS_IF([test "x$PKG_CONFIG" != "x"], [ 115 | AC_CONFIG_FILES([cmockery2.pc]) 116 | ]) 117 | 118 | ## Check out ../autoconf/ for other macros you can call to do useful stuff 119 | 120 | # Write generated configuration file 121 | AC_CONFIG_FILES([Makefile]) 122 | AC_OUTPUT 123 | -------------------------------------------------------------------------------- /doc/coverage.md: -------------------------------------------------------------------------------- 1 | # Enabling Coverage Support with Jenkins 2 | To enable coverage support you will need to install the utility [Gcovr][]. Gcovr will analize the output from GNU Gcov and create a [Cobertura][] compatible XML file to be consumed by the Jenkins Cobertura plugin. 3 | 4 | To install `gcovr` type the following command: 5 | 6 | ``` 7 | $ sudo easy_install gcovr 8 | ``` 9 | 10 | To enable [GNU Gcov][] support in your programs, you need to enable coverage support by adding the following CFLAGS to our build: 11 | 12 | * In GCC 13 | 14 | ``` 15 | CFLAGS += -O0 --coverage 16 | LDFLAGS += -lgcov 17 | ``` 18 | 19 | * In LLVM Clang 20 | 21 | ``` 22 | CFLAGS += -O0 -fprofile-arcs -ftest-coverage 23 | ``` 24 | 25 | Once you have built your programs using the new flags, running the program will enable GNU Gcov to generate two files, one ending with `*.gcda` and another ending in `*.gcno`. These files will be analyzed by `gcovr` to create the Corbertura XML files using the following command: 26 | 27 | ``` 28 | $ gcovr -r . --xml -o coverage.xml 29 | ``` 30 | 31 | Gcovr has many more options. Please visit their page at [gcovr.com][] 32 | 33 | [Cobertura]: http://cobertura.sourceforge.net 34 | [Gcovr]: http://gcovr.com 35 | [gcovr.com]: http://gcovr.com 36 | [GNU Gcov]: http://gcc.gnu.org/onlinedocs/gcc/Gcov.html 37 | 38 | -------------------------------------------------------------------------------- /doc/html2wiki.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Translate really simple html to googlecode.com wiki. 4 | # 5 | # Usage: cat input.html | html2wiki.sh > outputwiki.txt 6 | # 7 | # Most of this script is simple sed substitutions with an awk script to handle 8 | # hierarchical lists. 9 | 10 | # Awk program to escape all instances of * outside of 11 | awk ' 12 | BEGIN { in_listing = 0; } 13 | /<[Ll][Ii][Ss][Tt][Ii][Nn][Gg]>/ { in_listing = 1; } 14 | /<\/[Ll][Ii][Ss][Tt][Ii][Nn][Gg]>/ { in_listing = 0; } 15 | /.*/ { 16 | if (in_listing) { 17 | print $0; 18 | } else { 19 | print gensub("*", "`*`", "g", $0) 20 | } 21 | }' | \ 22 | # Awk program to convert hierarchical unordered and ordered lists into 23 | # googlecode wiki list markup. This is limited to converting very simple 24 | # html lists in the form: 25 | # 26 | #
    27 | #
  • item 1
  • 28 | # ... 29 | #
  • item N
  • 30 | #
31 | # 32 | # This script also removes leading spaces from all lines outside of 33 | # sections. 34 | awk ' 35 | BEGIN { 36 | list_type_none = 0; 37 | list_type_ordered = 1; 38 | list_type_unordered = 2; 39 | # Number of nested lists. 40 | list_depth = 0; 41 | # Number of items in the list. 42 | list_items[list_depth] = 0; 43 | # Type of list. 44 | list_type[list_depth] = list_type_none; 45 | # Do nott strip whitespace from listing sections. 46 | in_listing = 0; 47 | } 48 | 49 | # Generate a string of indent spaces. 50 | function list_indent(indent) { 51 | format = sprintf("%%%ds", indent); 52 | return sprintf(format, ""); 53 | } 54 | 55 | /<[Ll][Ii][Ss][Tt][Ii][Nn][Gg]>/ { in_listing = 1; } 56 | /<\/[Ll][Ii][Ss][Tt][Ii][Nn][Gg]>/ { in_listing = 0; } 57 | 58 | # Process all lines non-blank lines. 59 | /^.*$/ { 60 | # Remove leading white space. 61 | if (!in_listing) { 62 | output_string = gensub(/^ */, "", 1, $0); 63 | } else { 64 | output_string = $0; 65 | } 66 | search_string = output_string 67 | 68 | # Replace list tags with googlecode wiki markup. 69 | while (match(search_string, /<[^>]*>/, matches)) { 70 | tag = matches[0]; 71 | search_string = substr(search_string, 72 | matches[0, "start"] + matches[0, "length"]); 73 | if (match(tag, /^<[Uu][Ll]>$/)) { 74 | list_depth++; 75 | list_type[list_depth] = list_type_unordered; 76 | list_items[list_depth] = 0; 77 | output_string = gensub(tag, "", 1, output_string); 78 | } else if (match(tag, /^[Oo][Ll]>$/)) { 79 | list_depth++; 80 | list_type[list_depth] = list_type_ordered; 81 | list_items[list_depth] = 0; 82 | output_string = gensub(tag, "", 1, output_string); 83 | } else if (match(tag, /^<\/[Ll][Ii]>$/)) { 84 | output_string = gensub(tag, "", 1, output_string); 85 | } else if (list_depth) { 86 | if (match(tag, /^<[Ll][Ii]>$/)) { 87 | if (list_type[list_depth] == list_type_unordered) { 88 | output_string = gensub(tag, list_indent(list_depth) "* ", 1, 89 | output_string); 90 | } else if (list_type[list_depth] == list_type_ordered) { 91 | output_string = gensub(tag, list_indent(list_depth) "# ", 1, 92 | output_string); 93 | } 94 | } else if (match(tag, /^<\/[Uu][Ll]>$/) || 95 | match(tag, /^<\/[Ou][Ll]>$/)) { 96 | output_string = gensub(tag, "", 1, output_string); 97 | list_depth --; 98 | } 99 | } 100 | } 101 | # If a list is being parsed then filter blank lines. 102 | if (list_depth == 0 || length(output_string)) { 103 | print output_string 104 | } 105 | } 106 | ' | \ 107 | # This sed program translates really simple html into wiki suitable for 108 | # googlecode.com. 109 | # 110 | # Supported tags: 111 | #

112 | #
113 | #

114 | #

115 | #

116 | #

117 | #

118 | # 119 | # 120 | # .* 121 | # .* 122 | # @\n@g; 138 | s@<[[Bb][Rr]]>@\n@g; 139 | s@@=@g; 140 | s@@==@g; 141 | s@@===@g; 142 | s@@====@g; 143 | s@@====@g; 144 | s@@*@g; 145 | s@@_@g; 146 | s@<[Ll][Ii][Ss][Tt][Ii][Nn][Gg]>@{{{@g; 147 | s@@}}}@g; 148 | s@<[Aa].*?href="#(.*)?">(.*)?@[#\1 \2]@g; 149 | s@<[Aa].*?href="(.*)?">(.*)?@[http://cmockery.googlecode.com/svn/trunk/doc/\1 \2]@g; 150 | s@<[Aa].*?name="(.*)?">@@g; 151 | s@@@g; 152 | s@<.*?>@@g; 153 | s@<@<@g; 154 | s@>@>@g;' 155 | -------------------------------------------------------------------------------- /doc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Cmockery 4 | 5 | 6 |

Cmockery Unit Testing Framework

7 |

Cmockery is a lightweight library that is used to author C unit tests.

8 | 9 |
28 | 29 |

Motivation

30 |

There are a variety of C unit testing frameworks available however many of 31 | them are fairly complex and require the latest compiler technology. Some 32 | development requires the use of old compilers which makes it difficult to 33 | use some unit testing frameworks. In addition many unit testing frameworks 34 | assume the code being tested is an application or module that is targeted to 35 | the same platform that will ultimately execute the test. Because of this 36 | assumption many frameworks require the inclusion of standard C library headers 37 | in the code module being tested which may collide with the custom or 38 | incomplete implementation of the C library utilized by the code under test.

39 | 40 |

Cmockery only requires a test application is linked with the standard C 41 | library which minimizes conflicts with standard C library headers. Also, 42 | Cmockery tries avoid the use of some of the newer features of C compilers.

43 | 44 |

This results in Cmockery being a relatively small library that can be used 45 | to test a variety of exotic code. If a developer wishes to simply test an 46 | application with the latest compiler then other unit testing frameworks maybe 47 | preferable.

48 | 49 |

Overview

50 |

Cmockery tests are compiled into stand-alone executables and linked with 51 | the Cmockery library, the standard C library and module being tested. Any 52 | symbols external to the module being tested should be mocked - replaced with 53 | functions that return values determined by the test - within the test 54 | application. Even though significant differences may exist between the target 55 | execution environment of a code module and the environment used to test the 56 | code the unit testing is still valid since its goal is to test the logic of a 57 | code modules at a functional level and not necessarily all of its interactions 58 | with the target execution environment.

59 | 60 |

It may not be possible to compile a module into a test application without 61 | some modification, therefore the preprocessor symbol UNIT_TESTING should 62 | be defined when Cmockery unit test applications are compiled so code within the 63 | module can be conditionally compiled for tests.

64 | 65 |

Test Execution

66 |

Cmockery unit test cases are functions with the signature 67 | void function(void **state). Cmockery test applications initialize a 68 | table with test case function pointers using unit_test*() macros. This 69 | table is then passed to the run_tests() macro to execute the tests. 70 | 71 | run_tests() sets up the appropriate exception / signal handlers and 72 | other data structures prior to running each test function. When a unit test 73 | is complete run_tests() performs various checks to determine whether 74 | the test succeeded.

75 | 76 |

Using run_tests()

77 | run_tests.c 78 | 79 | #include <stdarg.h> 80 | #include <stddef.h> 81 | #include <setjmp.h> 82 | #include <cmockery.h> 83 | 84 | // A test case that does nothing and succeeds. 85 | void null_test_success(void **state) { 86 | } 87 | 88 | int main(int argc, char* argv[]) { 89 | const UnitTest tests[] = { 90 | unit_test(null_test_success), 91 | }; 92 | return run_tests(tests); 93 | } 94 | 95 | 96 |

Exception Handling

97 |

Before a test function is executed by run_tests(), 98 | exception / signal handlers are overridden with a handler that simply 99 | displays an error and exits a test function if an exception occurs. If an 100 | exception occurs outside of a test function, for example in Cmockery itself, 101 | the application aborts execution and returns an error code.

102 | 103 |

Failure Conditions

104 |

If a failure occurs during a test function that's executed via 105 | run_tests(), the test function is aborted and the application's 106 | execution resumes with the next test function. 107 | 108 | Test failures are ultimately signalled via the Cmockery function fail(). 109 | The following events will result in the Cmockery library signalling a test 110 | failure... 111 | 112 |

122 |

123 | 124 |

Assertions

125 |

Runtime assert macros like the standard C library's assert() should 126 | be redefined in modules being tested to use Cmockery's mock_assert() 127 | function. Normally mock_assert() signals a 128 | test failure. If a function is called using 129 | the expect_assert_failure() macro, any calls to mock_assert() 130 | within the function will result in the execution of the test. If no 131 | calls to mock_assert() occur during the function called via 132 | expect_assert_failure() a test failure is signalled.

133 | 134 |

Using mock_assert()

135 | assert_module.c 136 | 137 | #include <assert.h> 138 | 139 | // If unit testing is enabled override assert with mock_assert(). 140 | #if UNIT_TESTING 141 | extern void mock_assert(const int result, const char* const expression, 142 | const char * const file, const int line); 143 | #undef assert 144 | #define assert(expression) \ 145 | mock_assert((int)(expression), #expression, __FILE__, __LINE__); 146 | #endif // UNIT_TESTING 147 | 148 | void increment_value(int * const value) { 149 | assert(value); 150 | (*value) ++; 151 | } 152 | 153 | void decrement_value(int * const value) { 154 | if (value) { 155 | *value --; 156 | } 157 | } 158 | 159 | assert_module_test.c 160 | 161 | #include <stdarg.h> 162 | #include <stddef.h> 163 | #include <setjmp.h> 164 | #include <cmockery.h> 165 | 166 | extern void increment_value(int * const value); 167 | 168 | /* This test case will fail but the assert is caught by run_tests() and the 169 | * next test is executed. */ 170 | void increment_value_fail(void **state) { 171 | increment_value(NULL); 172 | } 173 | 174 | // This test case succeeds since increment_value() asserts on the NULL pointer. 175 | void increment_value_assert(void **state) { 176 | expect_assert_failure(increment_value(NULL)); 177 | } 178 | 179 | /* This test case fails since decrement_value() doesn't assert on a NULL 180 | * pointer. */ 181 | void decrement_value_fail(void **state) { 182 | expect_assert_failure(decrement_value(NULL)); 183 | } 184 | 185 | int main(int argc, char *argv[]) { 186 | const UnitTest tests[] = { 187 | unit_test(increment_value_fail), 188 | unit_test(increment_value_assert), 189 | unit_test(decrement_value_fail), 190 | }; 191 | return run_tests(tests); 192 | } 193 | 194 | 195 |

Assert Macros

196 | 197 |

Cmockery provides an assortment of assert macros that tests applications 198 | should use use in preference to the C standard library's assert macro. On an 199 | assertion failure a Cmockery assert macro will write the failure to the 200 | standard error stream and signal a test failure. Due to limitations of the 201 | C language the general C standard library assert() and Cmockery's 202 | assert_true() and assert_false() macros can only display the expression that 203 | caused the assert failure. Cmockery's type specific assert macros, 204 | assert_{type}_equal() and assert_{type}_not_equal(), display the data that 205 | caused the assertion failure which increases data visibility aiding 206 | debugging of failing test cases.

207 | 208 |

Using assert_{type}_equal() macros

209 | assert_macro.c 210 | 211 | #include <string.h> 212 | 213 | static const char* status_code_strings[] = { 214 | "Address not found", 215 | "Connection dropped", 216 | "Connection timed out", 217 | }; 218 | 219 | const char* get_status_code_string(const unsigned int status_code) { 220 | return status_code_strings[status_code]; 221 | }; 222 | 223 | unsigned int string_to_status_code(const char* const status_code_string) { 224 | unsigned int i; 225 | for (i = 0; i < sizeof(status_code_strings) / 226 | sizeof(status_code_strings[0]); i++) { 227 | if (strcmp(status_code_strings[i], status_code_string) == 0) { 228 | return i; 229 | } 230 | } 231 | return ~0U; 232 | } 233 | 234 | assert_macro_test.c 235 | 236 | #include <stdarg.h> 237 | #include <stddef.h> 238 | #include <setjmp.h> 239 | #include <cmockery.h> 240 | 241 | extern const char* get_status_code_string(const unsigned int status_code); 242 | extern unsigned int string_to_status_code( 243 | const char* const status_code_string); 244 | 245 | /* This test will fail since the string returned by get_status_code_string(0) 246 | * doesn't match "Connection timed out". */ 247 | void get_status_code_string_test(void **state) { 248 | assert_string_equal(get_status_code_string(0), "Address not found"); 249 | assert_string_equal(get_status_code_string(1), "Connection timed out"); 250 | } 251 | 252 | // This test will fail since the status code of "Connection timed out" isn't 1 253 | void string_to_status_code_test(void **state) { 254 | assert_int_equal(string_to_status_code("Address not found"), 0); 255 | assert_int_equal(string_to_status_code("Connection timed out"), 1); 256 | } 257 | 258 | int main(int argc, char *argv[]) { 259 | const UnitTest tests[] = { 260 | unit_test(get_status_code_string_test), 261 | unit_test(string_to_status_code_test), 262 | }; 263 | return run_tests(tests); 264 | } 265 | 266 | 267 |

Dynamic Memory Allocation

268 | 269 |

To test for memory leaks, buffer overflows and underflows a module being 270 | tested by Cmockery should replace calls to malloc(), calloc() and 271 | free() to test_malloc(), test_calloc() and 272 | test_free() respectively. Each time a block is deallocated using 273 | test_free() it is checked for corruption, if a corrupt block is found 274 | a test failure is signalled. All blocks 275 | allocated using the test_*() allocation functions are tracked by the 276 | Cmockery library. When a test completes if any allocated blocks (memory leaks) 277 | remain they are reported and a test failure is signalled.

278 |

For simplicity Cmockery currently executes all tests in one process. 279 | Therefore all test cases in a test application share a single address space 280 | which means memory corruption from a single test case could potentially cause 281 | the test application to exit prematurely.

282 | 283 |

Using Cmockery's Allocators

284 | allocate_module.c 285 | 286 | #include <malloc.h> 287 | 288 | #if UNIT_TESTING 289 | extern void* _test_malloc(const size_t size, const char* file, const int line); 290 | extern void* _test_calloc(const size_t number_of_elements, const size_t size, 291 | const char* file, const int line); 292 | extern void _test_free(void* const ptr, const char* file, const int line); 293 | 294 | #define malloc(size) _test_malloc(size, __FILE__, __LINE__) 295 | #define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) 296 | #define free(ptr) _test_free(ptr, __FILE__, __LINE__) 297 | #endif // UNIT_TESTING 298 | 299 | void leak_memory() { 300 | int * const temporary = (int*)malloc(sizeof(int)); 301 | *temporary = 0; 302 | } 303 | 304 | void buffer_overflow() { 305 | char * const memory = (char*)malloc(sizeof(int)); 306 | memory[sizeof(int)] = '!'; 307 | free(memory); 308 | } 309 | 310 | void buffer_underflow() { 311 | char * const memory = (char*)malloc(sizeof(int)); 312 | memory[-1] = '!'; 313 | free(memory); 314 | } 315 | 316 | allocate_module_test.c 317 | 318 | #include <stdarg.h> 319 | #include <stddef.h> 320 | #include <setjmp.h> 321 | #include <cmockery.h> 322 | 323 | extern void leak_memory(); 324 | extern void buffer_overflow(); 325 | extern void buffer_underflow(); 326 | 327 | // Test case that fails as leak_memory() leaks a dynamically allocated block. 328 | void leak_memory_test(void **state) { 329 | leak_memory(); 330 | } 331 | 332 | // Test case that fails as buffer_overflow() corrupts an allocated block. 333 | void buffer_overflow_test(void **state) { 334 | buffer_overflow(); 335 | } 336 | 337 | // Test case that fails as buffer_underflow() corrupts an allocated block. 338 | void buffer_underflow_test(void **state) { 339 | buffer_underflow(); 340 | } 341 | 342 | int main(int argc, char* argv[]) { 343 | const UnitTest tests[] = { 344 | unit_test(leak_memory_test), 345 | unit_test(buffer_overflow_test), 346 | unit_test(buffer_underflow_test), 347 | }; 348 | return run_tests(tests); 349 | } 350 | 351 | 352 |

Mock Functions

353 | 354 |

A unit test should ideally isolate the function or module being tested 355 | from any external dependencies. This can be performed using mock functions 356 | that are either statically or dynamically linked with the module being tested. 357 | Mock functions must be statically linked when the code being tested directly 358 | references external functions. Dynamic linking is simply the process of 359 | setting a function pointer in a table used by the tested module to reference 360 | a mock function defined in the unit test.

361 | 362 |

Return Values

363 | 364 |

In order to simplify the implementation of mock functions Cmockery provides 365 | functionality which stores return values for mock functions in each test 366 | case using will_return(). These values are then returned by each mock 367 | function using calls to mock(). 368 | 369 | Values passed to will_return() are added to a queue for each function 370 | specified. Each successive call to mock() from a function removes a 371 | return value from the queue. This makes it possible for a mock function to use 372 | multiple calls to mock() to return output parameters in addition to a 373 | return value. In addition this allows the specification of return values for 374 | multiple calls to a mock function.

375 | 376 |

Using will_return()

377 | database.h 378 | 379 | typedef struct DatabaseConnection DatabaseConnection; 380 | 381 | /* Function that takes an SQL query string and sets results to an array of 382 | * pointers with the result of the query. The value returned specifies the 383 | * number of items in the returned array of results. The returned array of 384 | * results are statically allocated and should not be deallocated using free() 385 | */ 386 | typedef unsigned int (*QueryDatabase)( 387 | DatabaseConnection* const connection, const char * const query_string, 388 | void *** const results); 389 | 390 | // Connection to a database. 391 | struct DatabaseConnection { 392 | const char *url; 393 | unsigned int port; 394 | QueryDatabase query_database; 395 | }; 396 | 397 | // Connect to a database. 398 | DatabaseConnection* connect_to_database(const char * const url, 399 | const unsigned int port); 400 | 401 | customer_database.c 402 | 403 | #include <stddef.h> 404 | #include <stdio.h> 405 | #include <database.h> 406 | #ifdef _WIN32 407 | #define snprintf _snprintf 408 | #endif // _WIN32 409 | 410 | // Connect to the database containing customer information. 411 | DatabaseConnection* connect_to_customer_database() { 412 | return connect_to_database("customers.abcd.org", 321); 413 | } 414 | 415 | /* Find the ID of a customer by his/her name returning a value > 0 if 416 | * successful, 0 otherwise. */ 417 | unsigned int get_customer_id_by_name( 418 | DatabaseConnection * const connection, 419 | const char * const customer_name) { 420 | char query_string[256]; 421 | int number_of_results; 422 | void **results; 423 | snprintf(query_string, sizeof(query_string), 424 | "SELECT ID FROM CUSTOMERS WHERE NAME = %s", customer_name); 425 | number_of_results = connection->query_database(connection, query_string, 426 | &results); 427 | if (number_of_results != 1) { 428 | return -1; 429 | } 430 | return (unsigned int)results[0]; 431 | } 432 | 433 | customer_database_test.c 434 | 435 | #include <stdarg.h> 436 | #include <stddef.h> 437 | #include <setjmp.h> 438 | #include <cmockery.h> 439 | #include <database.h> 440 | 441 | 442 | extern DatabaseConnection* connect_to_customer_database(); 443 | extern unsigned int get_customer_id_by_name( 444 | DatabaseConnection * const connection, const char * const customer_name); 445 | 446 | // Mock query database function. 447 | unsigned int mock_query_database( 448 | DatabaseConnection* const connection, const char * const query_string, 449 | void *** const results) { 450 | *results = (void**)mock(); 451 | return (unsigned int)mock(); 452 | } 453 | 454 | // Mock of the connect to database function. 455 | DatabaseConnection* connect_to_database(const char * const database_url, 456 | const unsigned int port) { 457 | return (DatabaseConnection*)mock(); 458 | } 459 | 460 | void test_connect_to_customer_database(void **state) { 461 | will_return(connect_to_database, 0x0DA7ABA53); 462 | assert_true(connect_to_customer_database() == 463 | (DatabaseConnection*)0x0DA7ABA53); 464 | } 465 | 466 | /* This test fails as the mock function connect_to_database() will have no 467 | * value to return. */ 468 | void fail_connect_to_customer_database(void **state) { 469 | will_return(connect_to_database, 0x0DA7ABA53); 470 | assert_true(connect_to_customer_database() == 471 | (DatabaseConnection*)0x0DA7ABA53); 472 | } 473 | 474 | void test_get_customer_id_by_name(void **state) { 475 | DatabaseConnection connection = { 476 | "somedatabase.somewhere.com", 12345678, mock_query_database 477 | }; 478 | // Return a single customer ID when mock_query_database() is called. 479 | int customer_ids = 543; 480 | will_return(mock_query_database, &customer_ids); 481 | will_return(mock_query_database, 1); 482 | assert_int_equal(get_customer_id_by_name(&connection, "john doe"), 543); 483 | } 484 | 485 | int main(int argc, char* argv[]) { 486 | const UnitTest tests[] = { 487 | unit_test(test_connect_to_customer_database), 488 | unit_test(fail_connect_to_customer_database), 489 | unit_test(test_get_customer_id_by_name), 490 | }; 491 | return run_tests(tests); 492 | } 493 | 494 | 495 |

Checking Parameters

496 |

In addition to storing the return values of mock functions, Cmockery 497 | provides functionality to store expected values for mock function parameters 498 | using the expect_*() functions provided. A mock function parameter can then 499 | be validated using the check_expected() macro. 500 | 501 |

Successive calls to expect_*() macros for a parameter queues values to 502 | check the specified parameter. check_expected() checks a function parameter 503 | against the next value queued using expect_*(), if the parameter check fails a 504 | test failure is signalled. In addition if check_expected() is called and 505 | no more parameter values are queued a test failure occurs.

506 | 507 |

Using expect_*()

508 | product_database.c 509 | 510 | #include <database.h> 511 | 512 | // Connect to the database containing customer information. 513 | DatabaseConnection* connect_to_product_database() { 514 | return connect_to_database("products.abcd.org", 322); 515 | } 516 | 517 | product_database_test.c 518 | 519 | #include <stdarg.h> 520 | #include <stddef.h> 521 | #include <setjmp.h> 522 | #include <cmockery.h> 523 | #include <database.h> 524 | 525 | extern DatabaseConnection* connect_to_product_database(); 526 | 527 | /* Mock connect to database function. 528 | * NOTE: This mock function is very general could be shared between tests 529 | * that use the imaginary database.h module. */ 530 | DatabaseConnection* connect_to_database(const char * const url, 531 | const unsigned int port) { 532 | check_expected(url); 533 | check_expected(port); 534 | return (DatabaseConnection*)mock(); 535 | } 536 | 537 | void test_connect_to_product_database(void **state) { 538 | expect_string(connect_to_database, url, "products.abcd.org"); 539 | expect_value(connect_to_database, port, 322); 540 | will_return(connect_to_database, 0xDA7ABA53); 541 | assert_int_equal(connect_to_product_database(), 0xDA7ABA53); 542 | } 543 | 544 | /* This test will fail since the expected URL is different to the URL that is 545 | * passed to connect_to_database() by connect_to_product_database(). */ 546 | void test_connect_to_product_database_bad_url(void **state) { 547 | expect_string(connect_to_database, url, "products.abcd.com"); 548 | expect_value(connect_to_database, port, 322); 549 | will_return(connect_to_database, 0xDA7ABA53); 550 | assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53); 551 | } 552 | 553 | /* This test will fail since the mock connect_to_database() will attempt to 554 | * retrieve a value for the parameter port which isn't specified by this 555 | * test function. */ 556 | void test_connect_to_product_database_missing_parameter(void **state) { 557 | expect_string(connect_to_database, url, "products.abcd.org"); 558 | will_return(connect_to_database, 0xDA7ABA53); 559 | assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53); 560 | } 561 | 562 | int main(int argc, char* argv[]) { 563 | const UnitTest tests[] = { 564 | unit_test(test_connect_to_product_database), 565 | unit_test(test_connect_to_product_database_bad_url), 566 | unit_test(test_connect_to_product_database_missing_parameter), 567 | }; 568 | return run_tests(tests); 569 | } 570 | 571 | 572 |

Test State

573 | 574 |

Cmockery allows the specification of multiple setup and tear down functions 575 | for each test case. Setup functions, specified by the unit_test_setup() 576 | or unit_test_setup_teardown() macros allow common initialization to be 577 | shared between multiple test cases. In addition, tear down functions, 578 | specified by the unit_test_teardown() or 579 | unit_test_setup_teardown() macros provide a code path that is always 580 | executed for a test case even when it fails.

581 | 582 |

Using unit_test_setup_teardown()

583 | key_value.c 584 | 585 | #include <stddef.h> 586 | #include <stdlib.h> 587 | #include <string.h> 588 | 589 | typedef struct KeyValue { 590 | unsigned int key; 591 | const char* value; 592 | } KeyValue; 593 | 594 | static KeyValue *key_values = NULL; 595 | static unsigned int number_of_key_values = 0; 596 | 597 | void set_key_values(KeyValue * const new_key_values, 598 | const unsigned int new_number_of_key_values) { 599 | key_values = new_key_values; 600 | number_of_key_values = new_number_of_key_values; 601 | } 602 | 603 | // Compare two key members of KeyValue structures. 604 | int key_value_compare_keys(const void *a, const void *b) { 605 | return (int)((KeyValue*)a)->key - (int)((KeyValue*)b)->key; 606 | } 607 | 608 | // Search an array of key value pairs for the item with the specified value. 609 | KeyValue* find_item_by_value(const char * const value) { 610 | unsigned int i; 611 | for (i = 0; i < number_of_key_values; i++) { 612 | if (strcmp(key_values[i].value, value) == 0) { 613 | return &key_values[i]; 614 | } 615 | } 616 | return NULL; 617 | } 618 | 619 | // Sort an array of key value pairs by key. 620 | void sort_items_by_key() { 621 | qsort(key_values, number_of_key_values, sizeof(*key_values), 622 | key_value_compare_keys); 623 | } 624 | 625 | key_value_test.c 626 | 627 | #include <stdarg.h> 628 | #include <stddef.h> 629 | #include <setjmp.h> 630 | #include <string.h> 631 | #include <cmockery.h> 632 | 633 | /* This is duplicated here from the module setup_teardown.c to reduce the 634 | * number of files used in this test. */ 635 | typedef struct KeyValue { 636 | unsigned int key; 637 | const char* value; 638 | } KeyValue; 639 | 640 | void set_key_values(KeyValue * const new_key_values, 641 | const unsigned int new_number_of_key_values); 642 | extern KeyValue* find_item_by_value(const char * const value); 643 | extern void sort_items_by_key(); 644 | 645 | static KeyValue key_values[] = { 646 | { 10, "this" }, 647 | { 52, "test" }, 648 | { 20, "a" }, 649 | { 13, "is" }, 650 | }; 651 | 652 | void create_key_values(void **state) { 653 | KeyValue * const items = (KeyValue*)test_malloc(sizeof(key_values)); 654 | memcpy(items, key_values, sizeof(key_values)); 655 | *state = (void*)items; 656 | set_key_values(items, sizeof(key_values) / sizeof(key_values[0])); 657 | } 658 | 659 | void destroy_key_values(void **state) { 660 | test_free(*state); 661 | set_key_values(NULL, 0); 662 | } 663 | 664 | void test_find_item_by_value(void **state) { 665 | unsigned int i; 666 | for (i = 0; i < sizeof(key_values) / sizeof(key_values[0]); i++) { 667 | KeyValue * const found = find_item_by_value(key_values[i].value); 668 | assert_true(found); 669 | assert_int_equal(found->key, key_values[i].key); 670 | assert_string_equal(found->value, key_values[i].value); 671 | } 672 | } 673 | 674 | void test_sort_items_by_key(void **state) { 675 | unsigned int i; 676 | KeyValue * const kv = *state; 677 | sort_items_by_key(); 678 | for (i = 1; i < sizeof(key_values) / sizeof(key_values[0]); i++) { 679 | assert_true(kv[i - 1].key < kv[i].key); 680 | } 681 | } 682 | 683 | int main(int argc, char* argv[]) { 684 | const UnitTest tests[] = { 685 | unit_test_setup_teardown(test_find_item_by_value, create_key_values, 686 | destroy_key_values), 687 | unit_test_setup_teardown(test_sort_items_by_key, create_key_values, 688 | destroy_key_values), 689 | }; 690 | return run_tests(tests); 691 | } 692 | 693 | 694 |

Example

695 | 696 |

A small command line calculator 697 | calculator.c application 698 | and test application that full exercises the calculator application 699 | calculator_test.c 700 | are provided as an example of Cmockery's features discussed in this document. 701 |

702 | 703 |
704 |
705 | Last modified: Wed Jul 22 12:11:43 PDT 2009 706 | 707 | -------------------------------------------------------------------------------- /doc/usage.md: -------------------------------------------------------------------------------- 1 | 2 | # Cmockery Unit Testing Framework 3 | Cmockery is a lightweight library that is used to author C unit tests. 4 | 5 | ## Motivation 6 | There are a variety of C unit testing frameworks available however many of them are fairly complex and require the latest compiler technology. Some development requires the use of old compilers which makes it difficult to use some unit testing frameworks. In addition many unit testing frameworks assume the code being tested is an application or module that is targeted to the same platform that will ultimately execute the test. Because of this assumption many frameworks require the inclusion of standard C library headers in the code module being tested which may collide with the custom or incomplete implementation of the C library utilized by the code under test. 7 | 8 | Cmockery only requires a test application is linked with the standard C library which minimizes conflicts with standard C library headers. Also, Cmockery tries avoid the use of some of the newer features of C compilers. 9 | 10 | This results in Cmockery being a relatively small library that can be used to test a variety of exotic code. If a developer wishes to simply test an application with the latest compiler then other unit testing frameworks maybe preferable. 11 | 12 | ## Overview 13 | Cmockery tests are compiled into stand-alone executables and linked with the Cmockery library, the standard C library and module being tested. Any symbols external to the module being tested should be mocked - replaced with functions that return values determined by the test - within the test application. Even though significant differences may exist between the target execution environment of a code module and the environment used to test the code the unit testing is still valid since its goal is to test the logic of a code modules at a functional level and not necessarily all of its interactions with the target execution environment. 14 | 15 | It may not be possible to compile a module into a test application without some modification, therefore the preprocessor symbol UNIT_TESTING should be defined when Cmockery unit test applications are compiled so code within the module can be conditionally compiled for tests. 16 | 17 | ## Installation 18 | 19 | ### Binary Installation 20 | Cmockery can be installed on Fedora/EPEL systems by doing the following: 21 | 22 | ``` 23 | $ sudo yum install cmockery2 cmockery2-devel 24 | ``` 25 | 26 | ### Installing from the source 27 | 28 | #### Environment Setup 29 | 30 | * Ubuntu 31 | 32 | ```sh 33 | $ sudo apt-get -y install libtool make autoconf automake gcc 34 | ``` 35 | 36 | * Fedora/RHEL 37 | 38 | ```sh 39 | $ sudo yum -y install libtool make autoconf automake gcc 40 | ``` 41 | 42 | * Mac (with Homebrew) 43 | ```sh 44 | xcode-select --install # if we to install clang 45 | 46 | $ brew install autoconf automake libtool 47 | ``` 48 | 49 | #### Build cmockery 50 | 51 | ```sh 52 | $ ./autogen.sh 53 | $ ./configure 54 | $ make 55 | ``` 56 | 57 | ## Test Execution 58 | Cmockery unit test cases are functions with the signature void `function(void **state)`. Cmockery test applications initialize a table with test case function pointers using `unit_test*()` macros. This table is then passed to the `run_tests()` macro to execute the tests. `run_tests()` sets up the appropriate exception / signal handlers and other data structures prior to running each test function. When a unit test is complete `run_tests()` performs various checks to determine whether the test succeeded. 59 | 60 | The second parameter to `run_tests()` is the prefix to the xUnit XML report in the following format: *prefix*\_xunit.xml. For example, calling `run_tests(tests, "abcd")` will create an xUnit XML report called `abcd_xunit.xml`. 61 | 62 | ### Using run_tests() 63 | 64 | #### run\_test.c 65 | 66 | ```c 67 | #include 68 | #include 69 | #include 70 | #include 71 | 72 | // A test case that does nothing and succeeds. 73 | void null_test_success(void **state) { 74 | } 75 | 76 | int main(int argc, char* argv[]) { 77 | const UnitTest tests[] = { 78 | unit_test(null_test_success), 79 | }; 80 | return run_tests(tests, "run"); 81 | } 82 | ``` 83 | 84 | ## Exception Handling 85 | Before a test function is executed by run_tests(), exception / signal handlers are overridden with a handler that simply displays an error and exits a test function if an exception occurs. If an exception occurs outside of a test function, for example in Cmockery itself, the application aborts execution and returns an error code. 86 | 87 | ## Failure Conditions 88 | If a failure occurs during a test function that's executed via run_tests(), the test function is aborted and the application's execution resumes with the next test function. Test failures are ultimately signalled via the Cmockery function fail(). The following events will result in the Cmockery library signalling a test failure... 89 | 90 | ## Assertions 91 | Runtime assert macros like the standard C library's assert() should be redefined in modules being tested to use Cmockery's mock_assert() function. Normally mock_assert() signals a test failure. If a function is called using the expect_assert_failure() macro, any calls to mock_assert() within the function will result in the execution of the test. If no calls to mock_assert() occur during the function called via expect_assert_failure() a test failure is signalled. This is easily handled by including `cmockery_override.h`. 92 | 93 | ### Using mock_assert() 94 | 95 | #### assert\_module.c 96 | 97 | ```c 98 | #include 99 | 100 | // Override functions in the program to be tested 101 | #if UNIT_TESTING 102 | // Must be last include 103 | #include 104 | #endif // UNIT_TESTING 105 | 106 | void increment_value(int * const value) { 107 | assert(value); 108 | (*value) ++; 109 | } 110 | 111 | void decrement_value(int * const value) { 112 | if (value) { 113 | *value --; 114 | } 115 | } 116 | ``` 117 | 118 | ### assert\_module\_test.c 119 | 120 | ```c 121 | #include 122 | #include 123 | #include 124 | #include 125 | 126 | extern void increment_value(int * const value); 127 | 128 | /* This test case will fail but the assert is caught by run_tests() and the 129 | * next test is executed. */ 130 | void increment_value_fail(void **state) { 131 | increment_value(NULL); 132 | } 133 | 134 | // This test case succeeds since increment_value() asserts on the NULL pointer. 135 | void increment_value_assert(void **state) { 136 | expect_assert_failure(increment_value(NULL)); 137 | } 138 | 139 | /* This test case fails since decrement_value() doesn't assert on a NULL 140 | * pointer. */ 141 | void decrement_value_fail(void **state) { 142 | expect_assert_failure(decrement_value(NULL)); 143 | } 144 | 145 | int main(int argc, char *argv[]) { 146 | const UnitTest tests[] = { 147 | unit_test(increment_value_fail), 148 | unit_test(increment_value_assert), 149 | unit_test(decrement_value_fail), 150 | }; 151 | return run_tests(tests, "assert_module"); 152 | } 153 | ``` 154 | 155 | ## Assert Macros 156 | 157 | Cmockery provides an assortment of assert macros that tests applications should use use in preference to the C standard library's assert macro. On an assertion failure a Cmockery assert macro will write the failure to the standard error stream and signal a test failure. Due to limitations of the C language the general C standard library `assert()` and Cmockery's `assert_true()` and `assert_false()` macros can only display the expression that caused the assert failure. Cmockery's type specific assert macros, `assert_{type}_equal()` and `assert_{type}_not_equal()`, display the data that caused the assertion failure which increases data visibility aiding debugging of failing test cases. 158 | 159 | ### Using assert\_{type}\_equal() macros 160 | 161 | #### assert\_macro.c 162 | 163 | ```c 164 | #include 165 | 166 | static const char* status_code_strings[] = { 167 | "Address not found", 168 | "Connection dropped", 169 | "Connection timed out", 170 | }; 171 | 172 | const char* get_status_code_string(const unsigned int status_code) { 173 | return status_code_strings[status_code]; 174 | }; 175 | 176 | unsigned int string_to_status_code(const char* const status_code_string) { 177 | unsigned int i; 178 | for (i = 0; i < sizeof(status_code_strings) / 179 | sizeof(status_code_strings[0]); i++) { 180 | if (strcmp(status_code_strings[i], status_code_string) == 0) { 181 | return i; 182 | } 183 | } 184 | return ~0U; 185 | } 186 | ``` 187 | 188 | #### assert\_macro\_test.c 189 | 190 | ```c 191 | #include 192 | #include 193 | #include 194 | #include 195 | 196 | extern const char* get_status_code_string(const unsigned int status_code); 197 | extern unsigned int string_to_status_code( 198 | const char* const status_code_string); 199 | 200 | /* This test will fail since the string returned by get_status_code_string(0) 201 | * doesn't match "Connection timed out". */ 202 | void get_status_code_string_test(void **state) { 203 | assert_string_equal(get_status_code_string(0), "Address not found"); 204 | assert_string_equal(get_status_code_string(1), "Connection timed out"); 205 | } 206 | 207 | // This test will fail since the status code of "Connection timed out" isn't 1 208 | void string_to_status_code_test(void **state) { 209 | assert_int_equal(string_to_status_code("Address not found"), 0); 210 | assert_int_equal(string_to_status_code("Connection timed out"), 1); 211 | } 212 | 213 | int main(int argc, char *argv[]) { 214 | const UnitTest tests[] = { 215 | unit_test(get_status_code_string_test), 216 | unit_test(string_to_status_code_test), 217 | }; 218 | return run_tests(tests, "assert_macro"); 219 | } 220 | ``` 221 | 222 | ## Dynamic Memory Allocation 223 | 224 | To test for memory leaks, buffer overflows and underflows a module being tested by Cmockery should replace calls to `malloc()`, `calloc()` and `free()` to `test_malloc()`, `test_calloc()` and `test_free()` respectively. This can be handled by including `cmockery_override.h`. Each time a block is deallocated using `test_free()` it is checked for corruption, if a corrupt block is found a test failure is signalled. All blocks allocated using the `test_*()` allocation functions are tracked by the Cmockery library. When a test completes if any allocated blocks (memory leaks) remain they are reported and a test failure is signalled. 225 | 226 | For simplicity Cmockery currently executes all tests in one process. Therefore all test cases in a test application share a single address space which means memory corruption from a single test case could potentially cause the test application to exit prematurely. 227 | 228 | ### Using Cmockery's Allocators 229 | 230 | #### allocate\_module.c 231 | 232 | ```c 233 | #include 234 | #ifdef UNIT_TESTING 235 | /* Must be last include */ 236 | #include 237 | #endif 238 | 239 | void leak_memory(void); 240 | void buffer_overflow(void); 241 | void buffer_underflow(void); 242 | 243 | void leak_memory(void) { 244 | int * const temporary = (int*)malloc(sizeof(int)); 245 | *temporary = 0; 246 | } 247 | 248 | void buffer_overflow(void) { 249 | char * const memory = (char*)malloc(sizeof(int)); 250 | memory[sizeof(int)] = '!'; 251 | free(memory); 252 | } 253 | 254 | void buffer_underflow(void) { 255 | char * const memory = (char*)malloc(sizeof(int)); 256 | memory[-1] = '!'; 257 | free(memory); 258 | } 259 | ``` 260 | 261 | #### allocate\_module\_test.c 262 | 263 | ```c 264 | #include 265 | #include 266 | #include 267 | #include 268 | #include 269 | 270 | extern void leak_memory(); 271 | extern void buffer_overflow(); 272 | extern void buffer_underflow(); 273 | 274 | // Test case that fails as leak_memory() leaks a dynamically allocated block. 275 | static void leak_memory_test(void **state) { 276 | leak_memory(); 277 | } 278 | 279 | // Test case that fails as buffer_overflow() corrupts an allocated block. 280 | static void buffer_overflow_test(void **state) { 281 | buffer_overflow(); 282 | } 283 | 284 | // Test case that fails as buffer_underflow() corrupts an allocated block. 285 | static void buffer_underflow_test(void **state) { 286 | buffer_underflow(); 287 | } 288 | 289 | int main(int argc, char* argv[]) { 290 | const UnitTest tests[] = { 291 | unit_test(leak_memory_test), 292 | unit_test(buffer_overflow_test), 293 | unit_test(buffer_underflow_test), 294 | }; 295 | return run_tests(tests, "allocate_module_test"); 296 | } 297 | ``` 298 | 299 | ## Mock Functions 300 | 301 | A unit test should ideally isolate the function or module being tested from any external dependencies. This can be performed using mock functions that are either statically or dynamically linked with the module being tested. Mock functions must be statically linked when the code being tested directly references external functions. Dynamic linking is simply the process of setting a function pointer in a table used by the tested module to reference a mock function defined in the unit test. 302 | 303 | ### Return Values 304 | 305 | In order to simplify the implementation of mock functions Cmockery provides functionality which stores return values for mock functions in each test case using will_`return()`. These values are then returned by each mock function using calls to `mock()`. Values passed to `will_return()` are added to a queue for each function specified. Each successive call to `mock()` from a function removes a return value from the queue. This makes it possible for a mock function to use multiple calls to `mock()` to return output parameters in addition to a return value. In addition this allows the specification of return values for multiple calls to a mock function. 306 | 307 | #### Using will\_return() 308 | 309 | ##### database.h 310 | 311 | ```c 312 | typedef struct DatabaseConnection DatabaseConnection; 313 | 314 | /* Function that takes an SQL query string and sets results to an array of 315 | * pointers with the result of the query. The value returned specifies the 316 | * number of items in the returned array of results. The returned array of 317 | * results are statically allocated and should not be deallocated using free() 318 | */ 319 | typedef unsigned int (*QueryDatabase)( 320 | DatabaseConnection* const connection, const char * const query_string, 321 | void *** const results); 322 | 323 | // Connection to a database. 324 | struct DatabaseConnection { 325 | const char *url; 326 | unsigned int port; 327 | QueryDatabase query_database; 328 | }; 329 | ``` 330 | 331 | ##### customer\_database.c 332 | 333 | ```c 334 | #include 335 | #include 336 | #include 337 | #include 338 | #ifdef _WIN32 339 | #define snprintf _snprintf 340 | #endif // _WIN32 341 | 342 | DatabaseConnection* connect_to_customer_database(void); 343 | unsigned int get_customer_id_by_name( 344 | DatabaseConnection * const connection, 345 | const char * const customer_name); 346 | 347 | // Connect to the database containing customer information. 348 | DatabaseConnection* connect_to_customer_database(void) { 349 | return connect_to_database("customers.abcd.org", 321); 350 | } 351 | 352 | /* Find the ID of a customer by his/her name returning a value > 0 if 353 | * successful, 0 otherwise. */ 354 | unsigned int get_customer_id_by_name( 355 | DatabaseConnection * const connection, 356 | const char * const customer_name) { 357 | char query_string[256]; 358 | int number_of_results; 359 | void **results; 360 | snprintf(query_string, sizeof(query_string), 361 | "SELECT ID FROM CUSTOMERS WHERE NAME = %s", customer_name); 362 | number_of_results = connection->query_database(connection, query_string, 363 | &results); 364 | if (number_of_results != 1) { 365 | return -1; 366 | } 367 | return (uintptr_t)results[0]; 368 | } 369 | ``` 370 | 371 | ##### customer\_database\_test.c 372 | 373 | ```c 374 | #include 375 | #include 376 | #include 377 | #include 378 | #include 379 | #include 380 | 381 | extern DatabaseConnection* connect_to_customer_database(); 382 | extern unsigned int get_customer_id_by_name( 383 | DatabaseConnection * const connection, const char * const customer_name); 384 | 385 | // Mock query database function. 386 | static unsigned int mock_query_database( 387 | DatabaseConnection* const connection, const char * const query_string, 388 | void *** const results) { 389 | *results = (void**)((uintptr_t)mock()); 390 | return (unsigned int)mock(); 391 | } 392 | 393 | // Mock of the connect to database function. 394 | DatabaseConnection* connect_to_database(const char * const database_url, 395 | const unsigned int port) { 396 | return (DatabaseConnection*)((uintptr_t)mock()); 397 | } 398 | 399 | static void test_connect_to_customer_database(void **state) { 400 | will_return(connect_to_database, 0x0DA7ABA53); 401 | assert_int_equal((uintptr_t)connect_to_customer_database(), 0x0DA7ABA53); 402 | } 403 | 404 | /* This test fails as the mock function connect_to_database() will have no 405 | * value to return. */ 406 | static void test_fail_connect_to_customer_database(void **state) { 407 | assert_true(connect_to_customer_database() == 408 | (DatabaseConnection*)0x0DA7ABA53); 409 | } 410 | 411 | static void test_get_customer_id_by_name(void **state) { 412 | DatabaseConnection connection = { 413 | "somedatabase.somewhere.com", 12345678, mock_query_database 414 | }; 415 | // Return a single customer ID when mock_query_database() is called. 416 | int customer_ids = 543; 417 | will_return(mock_query_database, &customer_ids); 418 | will_return(mock_query_database, 1); 419 | assert_int_equal(get_customer_id_by_name(&connection, "john doe"), 543); 420 | } 421 | 422 | int main(void) { 423 | const UnitTest tests[] = { 424 | unit_test(test_connect_to_customer_database), 425 | unit_test(test_get_customer_id_by_name), 426 | unit_test(test_fail_connect_to_customer_database), 427 | }; 428 | return run_tests(tests, "customer_database"); 429 | } 430 | ``` 431 | 432 | 433 | 434 | ## Checking Parameters 435 | 436 | In addition to storing the return values of mock functions, Cmockery provides functionality to store expected values for mock function parameters using the `expect_*()` functions provided. A mock function parameter can then be validated using the `check_expected()` macro. 437 | 438 | Successive calls to `expect_*()` macros for a parameter queues values to check the specified parameter. `check_expected()` checks a function parameter against the next value queued using `expect_*()`, if the parameter check fails a test failure is signalled. In addition if `check_expected()` is called and no more parameter values are queued a test failure occurs. 439 | 440 | ### Using expect\_\*() 441 | 442 | #### product\_database.c 443 | 444 | ```c 445 | #include 446 | 447 | DatabaseConnection* connect_to_product_database(void); 448 | 449 | // Connect to the database containing customer information. 450 | DatabaseConnection* connect_to_product_database(void) { 451 | return connect_to_database("products.abcd.org", 322); 452 | } 453 | ``` 454 | 455 | #### product\_database\_test.c 456 | 457 | ```c 458 | #include 459 | #include 460 | #include 461 | #include 462 | #include 463 | #include 464 | 465 | extern DatabaseConnection* connect_to_product_database(void); 466 | 467 | /* Mock connect to database function. 468 | * NOTE: This mock function is very general could be shared between tests 469 | * that use the imaginary database.h module. */ 470 | DatabaseConnection* connect_to_database(const char * const url, 471 | const unsigned int port) { 472 | check_expected(url); 473 | check_expected(port); 474 | return (DatabaseConnection*)((uintptr_t)mock()); 475 | } 476 | 477 | static void test_connect_to_product_database(void **state) { 478 | expect_string(connect_to_database, url, "products.abcd.org"); 479 | expect_value(connect_to_database, port, 322); 480 | will_return(connect_to_database, 0xDA7ABA53); 481 | assert_int_equal((uintptr_t)connect_to_product_database(), 0xDA7ABA53); 482 | } 483 | 484 | /* This test will fail since the expected URL is different to the URL that is 485 | * passed to connect_to_database() by connect_to_product_database(). */ 486 | static void test_connect_to_product_database_bad_url(void **state) { 487 | expect_string(connect_to_database, url, "products.abcd.com"); 488 | expect_value(connect_to_database, port, 322); 489 | will_return(connect_to_database, 0xDA7ABA53); 490 | assert_int_equal((uintptr_t)connect_to_product_database(), 0xDA7ABA53); 491 | } 492 | 493 | /* This test will fail since the mock connect_to_database() will attempt to 494 | * retrieve a value for the parameter port which isn't specified by this 495 | * test function. */ 496 | static void test_connect_to_product_database_missing_parameter(void **state) { 497 | expect_string(connect_to_database, url, "products.abcd.org"); 498 | will_return(connect_to_database, 0xDA7ABA53); 499 | assert_int_equal((uintptr_t)connect_to_product_database(), 0xDA7ABA53); 500 | } 501 | 502 | int main(void) { 503 | const UnitTest tests[] = { 504 | unit_test(test_connect_to_product_database), 505 | unit_test(test_connect_to_product_database_bad_url), 506 | unit_test(test_connect_to_product_database_missing_parameter), 507 | }; 508 | return run_tests(tests, "product_database"); 509 | } 510 | ``` 511 | 512 | ## Test State 513 | 514 | Cmockery allows the specification of multiple setup and tear down functions for each test case. Setup functions, specified by the unit_test_setup() or unit_test_setup_teardown() macros allow common initialization to be shared between multiple test cases. In addition, tear down functions, specified by the unit_test_teardown() or unit_test_setup_teardown() macros provide a code path that is always executed for a test case even when it fails. 515 | 516 | ### Using unit\_test\_setup\_teardown() 517 | 518 | #### key\_value.c 519 | 520 | ```c 521 | #include 522 | #include 523 | #include 524 | 525 | #include "key_value.h" 526 | 527 | static KeyValue *key_values = NULL; 528 | static unsigned int number_of_key_values = 0; 529 | 530 | void set_key_values(KeyValue * const new_key_values, 531 | const unsigned int new_number_of_key_values) { 532 | key_values = new_key_values; 533 | number_of_key_values = new_number_of_key_values; 534 | } 535 | 536 | // Compare two key members of KeyValue structures. 537 | static int key_value_compare_keys(const void *a, const void *b) { 538 | return (int)((KeyValue*)a)->key - (int)((KeyValue*)b)->key; 539 | } 540 | 541 | // Search an array of key value pairs for the item with the specified value. 542 | KeyValue* find_item_by_value(const char * const value) { 543 | unsigned int i; 544 | for (i = 0; i < number_of_key_values; i++) { 545 | if (strcmp(key_values[i].value, value) == 0) { 546 | return &key_values[i]; 547 | } 548 | } 549 | return NULL; 550 | } 551 | 552 | // Sort an array of key value pairs by key. 553 | void sort_items_by_key(void) { 554 | qsort(key_values, number_of_key_values, sizeof(*key_values), 555 | key_value_compare_keys); 556 | } 557 | ``` 558 | 559 | #### key\_value\_test.c 560 | 561 | ```c 562 | #include 563 | #include 564 | #include 565 | #include 566 | #include 567 | #include 568 | 569 | #include "key_value.h" 570 | 571 | static KeyValue key_values[] = { 572 | { 10, "this" }, 573 | { 52, "test" }, 574 | { 20, "a" }, 575 | { 13, "is" }, 576 | }; 577 | 578 | static void create_key_values(void **state) { 579 | KeyValue * const items = (KeyValue*)test_malloc(sizeof(key_values)); 580 | memcpy(items, key_values, sizeof(key_values)); 581 | *state = (void*)items; 582 | set_key_values(items, sizeof(key_values) / sizeof(key_values[0])); 583 | } 584 | 585 | static void destroy_key_values(void **state) { 586 | test_free(*state); 587 | set_key_values(NULL, 0); 588 | } 589 | 590 | static void test_find_item_by_value(void **state) { 591 | unsigned int i; 592 | for (i = 0; i < sizeof(key_values) / sizeof(key_values[0]); i++) { 593 | KeyValue * const found = find_item_by_value(key_values[i].value); 594 | assert_true(found != NULL); 595 | assert_int_equal(found->key, key_values[i].key); 596 | assert_string_equal(found->value, key_values[i].value); 597 | } 598 | } 599 | 600 | static void test_sort_items_by_key(void **state) { 601 | unsigned int i; 602 | KeyValue * const kv = *state; 603 | sort_items_by_key(); 604 | for (i = 1; i < sizeof(key_values) / sizeof(key_values[0]); i++) { 605 | assert_true(kv[i - 1].key < kv[i].key); 606 | } 607 | } 608 | 609 | int main(void) { 610 | const UnitTest tests[] = { 611 | unit_test_setup_teardown(test_find_item_by_value, create_key_values, 612 | destroy_key_values), 613 | unit_test_setup_teardown(test_sort_items_by_key, create_key_values, 614 | destroy_key_values), 615 | }; 616 | return run_tests(tests, "key_value"); 617 | } 618 | ``` 619 | 620 | ## Example 621 | 622 | A small command line calculator `calculator.c` application and test application that full exercises the calculator application `calculator_test.c` are provided as an example of Cmockery's features discussed in this document. 623 | -------------------------------------------------------------------------------- /makerpm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Simple script to create RPMs 4 | 5 | 6 | cleanup() 7 | { 8 | rm -rf ${RPMBUILDDIR} > /dev/null 2>&1 9 | rm -f ${PKGCONFIG} > /dev/null 2>&1 10 | } 11 | 12 | fail() 13 | { 14 | exit 0 15 | cleanup 16 | echo $1 17 | exit $2 18 | } 19 | 20 | create_dir() 21 | { 22 | if [ ! -d "$1" ] ; then 23 | mkdir -p "$1" 24 | if [ $? -ne 0 ] ; then 25 | fail "Unable to create dir $1" $? 26 | fi 27 | fi 28 | } 29 | 30 | gittotar() 31 | { 32 | # Only archives committed changes 33 | # Export the current commited git changes to a directory 34 | git archive --format=tar --prefix=${SRCTAR_DIR}/ HEAD | gzip -c > ${SRCTAR} 35 | if [ $? -ne 0 -o \! -s ${SRCTAR} ] ; then 36 | fail "Unable to create git archive" $? 37 | fi 38 | } 39 | 40 | prep() 41 | { 42 | rm -rf ${RPMBUILDDIR} > /dev/null 2>&1 43 | create_dir ${RPMBUILDDIR} 44 | create_dir ${RPMBUILDDIR}/SOURCES 45 | 46 | # Create a tar file out of the current committed changes 47 | gittotar 48 | 49 | } 50 | 51 | create_rpm() 52 | { 53 | cp -f ${SRCTAR} ${RPMBUILDDIR}/SOURCES 54 | # Create the rpm 55 | # _topdir Notifies rpmbuild the location of the root directory 56 | # containing the RPM information 57 | rpmbuild --define "_topdir ${RPMBUILDDIR}" \ 58 | -ta ${SRCTAR} 59 | if [ $? -ne 0 ] ; then 60 | fail "Unable to create rpm" $? 61 | fi 62 | 63 | # Move the rpms to the root directory 64 | } 65 | 66 | create_src() 67 | { 68 | git archive --format=tar --prefix=${SRCTAR_DIR}/ HEAD | gzip -c > ${SRCTAR} 69 | if [ $? -ne 0 ] ; then 70 | fail "Unable to create source archive" 71 | fi 72 | } 73 | 74 | ################## MAIN ##################### 75 | 76 | 77 | ## RPM NAME 78 | RPMNAME=cmockery2 79 | PKG_NAME=$RPMNAME 80 | PKG_VERSION=1.3.9 81 | 82 | BUILDDIR=$PWD/build 83 | RPMBUILDDIR=${BUILDDIR}/rpmbuild 84 | RPMBUILDDIR_RPMS=${RPMBUILDDIR}/RPMS 85 | RPMBUILDDIR_SRPMS=${RPMBUILDDIR}/SRPMS 86 | SRCNAME=${RPMNAME}-${PKG_VERSION} 87 | SRCTAR_DIR=${PKG_NAME}-${PKG_VERSION} 88 | SRCTAR=${RPMBUILDDIR}/${SRCNAME}.tar.gz 89 | 90 | prep 91 | create_src 92 | create_rpm 93 | -------------------------------------------------------------------------------- /packages/FreeBSD/.gitignore: -------------------------------------------------------------------------------- 1 | work 2 | -------------------------------------------------------------------------------- /packages/FreeBSD/Makefile: -------------------------------------------------------------------------------- 1 | # Created by: Harshavardhana 2 | # $FreeBSD$ 3 | # 4 | 5 | PORTNAME= cmockery2 6 | PORTVERSION= 1.3.9 7 | CATEGORIES= sysutils 8 | MASTER_SITES= https://codeload.github.com/lpabon/cmockery2/tar.gz/ 9 | DISTNAME= v1.3.9 10 | EXTRACT_SUFX= 11 | 12 | MAINTAINER= harsha@harshavardhana.net 13 | COMMENT= Cmockery2 revival of Cmockery unit test framework from Google 14 | 15 | LICENSE= APACHE20 16 | 17 | WRKSRC= ${WRKDIR}/cmockery2-${PORTVERSION} 18 | 19 | USES= libtool:build pkgconfig 20 | USE_AUTOTOOLS= automake autoconf aclocal libtoolize autoheader 21 | AUTOMAKE_ARGS= --add-missing 22 | GNU_CONFIGURE= yes 23 | USE_LDCONFIG= yes 24 | 25 | INSTALL_TARGET= install-strip 26 | # Disable gcov on FreeBSD 27 | # CONFIGURE_ARGS= --enable-gcov 28 | 29 | post-patch: 30 | @${REINPLACE_CMD} -e '/^docdir =/s|-$$(VERSION)||' \ 31 | -e '/^pkgconfigdir =/s|$$(libdir)|$$(prefix)/libdata|' \ 32 | ${WRKSRC}/Makefile.am 33 | 34 | .include 35 | -------------------------------------------------------------------------------- /packages/FreeBSD/distinfo: -------------------------------------------------------------------------------- 1 | SHA256 (v1.3.8) = 6178e2fc51653d1b15f5d7cc10e0f48adcbf6cd07c1acf793ea26bfa789e7ef7 2 | SIZE (v1.3.8) = 54110 3 | -------------------------------------------------------------------------------- /packages/FreeBSD/pkg-descr: -------------------------------------------------------------------------------- 1 | This is a port of Cmockery2, Cmockery2 is revival of Google's unit 2 | test framework. 3 | 4 | WWW: https://github.com/lpabon/cmockery2 5 | -------------------------------------------------------------------------------- /packages/FreeBSD/pkg-message: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | For more information on cmockery2, documentation is available at 4 | https://github.com/lpabon/cmockery2/blob/master/doc/usage.md 5 | 6 | ================================================================= 7 | -------------------------------------------------------------------------------- /packages/FreeBSD/pkg-plist: -------------------------------------------------------------------------------- 1 | include/cmockery/cmockery.h 2 | include/cmockery/cmockery_override.h 3 | include/cmockery/pbc.h 4 | lib/libcmockery.a 5 | lib/libcmockery.so 6 | lib/libcmockery.so.0 7 | lib/libcmockery.so.0.0.0 8 | libdata/pkgconfig/cmockery2.pc 9 | %%PORTDOCS%%%%DOCSDIR%%/AUTHORS 10 | %%PORTDOCS%%%%DOCSDIR%%/COPYING 11 | %%PORTDOCS%%%%DOCSDIR%%/ChangeLog 12 | %%PORTDOCS%%%%DOCSDIR%%/coverage.md 13 | %%PORTDOCS%%%%DOCSDIR%%/index.html 14 | %%PORTDOCS%%%%DOCSDIR%%/usage.md 15 | %%PORTDOCS%%@dirrm %%DOCSDIR%% 16 | @dirrmtry include/cmockery 17 | -------------------------------------------------------------------------------- /packages/deb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # This takes one commandline argument, the name of the package. If no 4 | # name is given, then we'll end up just using the name associated with 5 | # an arbitrary .tar.gz file in the rootdir. That's fine: there's probably 6 | # only one. 7 | # 8 | # Run this from the 'packages' directory, just under rootdir 9 | 10 | ## Set LIB to lib if exporting a library, empty-string else 11 | LIB= 12 | #LIB=lib 13 | 14 | PACKAGE="$1" 15 | 16 | # We can only build Debian packages, if the Debian build tools are installed 17 | if [ \! -x /usr/bin/debuild ]; then 18 | echo "Cannot find /usr/bin/debuild. Not building Debian packages." 1>&2 19 | exit 0 20 | fi 21 | 22 | # Double-check we're in the packages directory, just under rootdir 23 | if [ \! -r ../Makefile -a \! -r ../INSTALL ]; then 24 | echo "Must run $0 in the 'packages' directory, under the root directory." 1>&2 25 | echo "Also, you must run \"make dist\" before running this script." 1>&2 26 | exit 0 27 | fi 28 | 29 | # Find the top directory for this package 30 | topdir="${PWD%/*}" 31 | 32 | # Find the tar archive built by "make dist" 33 | archive="$(basename "$(ls -1 ${topdir}/$PACKAGE*.tar.gz | tail -n 1)" .tar.gz)" 34 | if [ -z "${archive}" ]; then 35 | echo "Cannot find ../$PACKAGE*.tar.gz. Run \"make dist\" first." 1>&2 36 | exit 0 37 | fi 38 | 39 | # Create a pristine directory for building the Debian package files 40 | trap 'rm -rf '`pwd`/tmp'; exit $?' EXIT SIGHUP SIGINT SIGTERM 41 | 42 | rm -rf tmp 43 | mkdir -p tmp 44 | cd tmp 45 | 46 | # Debian has very specific requirements about the naming of build 47 | # directories, and tar archives. It also wants to write all generated 48 | # packages to the parent of the source directory. We accommodate these 49 | # requirements by building directly from the tar file. 50 | ln -s "${topdir}/${archive}.tar.gz" "${LIB}${archive}.orig.tar.gz" 51 | tar zfx "${LIB}${archive}.orig.tar.gz" 52 | [ -n "${LIB}" ] && mv "${archive}" "${LIB}${archive}" 53 | cd "${LIB}${archive}" 54 | # This is one of those 'specific requirements': where the deb control files live 55 | ln -s "packages/deb" "debian" 56 | 57 | # Now, we can call Debian's standard build tool 58 | debuild -uc -us 59 | cd ../.. # get back to the original top-level dir 60 | 61 | # We'll put the result in a subdirectory that's named after the OS version 62 | # we've made this .deb file for. 63 | destdir="debian-$(cat /etc/debian_version 2>/dev/null || echo UNKNOWN)" 64 | 65 | rm -rf "$destdir" 66 | mkdir -p "$destdir" 67 | mv $(find tmp -mindepth 1 -maxdepth 1 -type f) "$destdir" 68 | 69 | echo 70 | echo "The Debian package files are located in $PWD/$destdir" 71 | -------------------------------------------------------------------------------- /packages/deb/README: -------------------------------------------------------------------------------- 1 | The list of files here isn't complete. For a step-by-step guide on 2 | how to set this package up correctly, check out 3 | http://www.debian.org/doc/maint-guide/ 4 | 5 | Most of the files that are in this directory are boilerplate. 6 | However, you may need to change the list of binary-arch dependencies 7 | in 'rules'. 8 | -------------------------------------------------------------------------------- /packages/deb/changelog: -------------------------------------------------------------------------------- 1 | cmockery (0.1-2) unstable; urgency=low 2 | * cmockery: version 0.12 3 | Made it possible to specify additional compiler, lib tool and link 4 | flags on Windows. 5 | Added Windows makefile to the tar ball. 6 | 7 | -- Google Inc. Mon, 28 Aug 2008 17:43:20 -0700 8 | -------------------------------------------------------------------------------- /packages/deb/compat: -------------------------------------------------------------------------------- 1 | 4 2 | -------------------------------------------------------------------------------- /packages/deb/control: -------------------------------------------------------------------------------- 1 | Source: cmockery 2 | Section: libdevel 3 | Priority: optional 4 | Maintainer: Google Inc, 5 | Build-Depends: debhelper (>= 4.0.0), binutils 6 | Standards-Version: 3.6.1 7 | 8 | Package: libcmockery-dev 9 | Section: libdevel 10 | Architecture: any 11 | Depends: libcmockery0 (= ${Source-Version}) 12 | Description: The cmockery package contains a lightweight library to simplify 13 | and generalize the process of writing unit tests for C applications. 14 | 15 | Package: libcmockery0 16 | Section: libs 17 | Architecture: any 18 | Description: The cmockery package contains static and debug libraries and 19 | header files for the development of test applications using %name. 20 | 21 | -------------------------------------------------------------------------------- /packages/deb/copyright: -------------------------------------------------------------------------------- 1 | This package was debianized by Google Inc. on 2 | 28 August 2008. 3 | 4 | It was downloaded from http://code.google.com/ 5 | 6 | Upstream Author: opensource@google.com 7 | 8 | Copyright (c) 2006, Google Inc. 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are 13 | met: 14 | 15 | * Redistributions of source code must retain the above copyright 16 | notice, this list of conditions and the following disclaimer. 17 | * Redistributions in binary form must reproduce the above 18 | copyright notice, this list of conditions and the following disclaimer 19 | in the documentation and/or other materials provided with the 20 | distribution. 21 | * Neither the name of Google Inc. nor the names of its 22 | contributors may be used to endorse or promote products derived from 23 | this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | -------------------------------------------------------------------------------- /packages/deb/docs: -------------------------------------------------------------------------------- 1 | AUTHORS 2 | COPYING 3 | ChangeLog 4 | INSTALL 5 | NEWS 6 | README.md 7 | doc/usage.md 8 | -------------------------------------------------------------------------------- /packages/deb/libcmockery-dev.dirs: -------------------------------------------------------------------------------- 1 | usr/lib 2 | usr/include 3 | usr/include/google 4 | 5 | -------------------------------------------------------------------------------- /packages/deb/libcmockery-dev.install: -------------------------------------------------------------------------------- 1 | usr/include/google/* 2 | usr/lib/lib*.so 3 | usr/lib/lib*.a 4 | usr/lib/lib*.la 5 | debian/tmp/usr/include/google/* 6 | debian/tmp/usr/lib/lib*.so 7 | debian/tmp/usr/lib/lib*.a 8 | debian/tmp/usr/lib/lib*.la 9 | 10 | -------------------------------------------------------------------------------- /packages/deb/libcmockery0.dirs: -------------------------------------------------------------------------------- 1 | usr/lib 2 | -------------------------------------------------------------------------------- /packages/deb/libcmockery0.install: -------------------------------------------------------------------------------- 1 | usr/lib/lib*.so.* 2 | debian/tmp/usr/lib/lib*.so.* 3 | -------------------------------------------------------------------------------- /packages/deb/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | 13 | # These are used for cross-compiling and for saving the configure script 14 | # from having to guess our platform (since we know it already) 15 | DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) 16 | DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) 17 | 18 | 19 | CFLAGS = -Wall -g 20 | 21 | ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) 22 | CFLAGS += -O0 23 | else 24 | CFLAGS += -O2 25 | endif 26 | ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) 27 | INSTALL_PROGRAM += -s 28 | endif 29 | 30 | # shared library versions, option 1 31 | #version=2.0.5 32 | #major=2 33 | # option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so 34 | version=`ls src/.libs/lib*.so.* | \ 35 | awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'` 36 | major=`ls src/.libs/lib*.so.* | \ 37 | awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'` 38 | 39 | config.status: configure 40 | dh_testdir 41 | # Add here commands to configure the package. 42 | CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info 43 | 44 | 45 | build: build-stamp 46 | build-stamp: config.status 47 | dh_testdir 48 | 49 | # Add here commands to compile the package. 50 | $(MAKE) 51 | 52 | touch build-stamp 53 | 54 | clean: 55 | dh_testdir 56 | dh_testroot 57 | rm -f build-stamp 58 | 59 | # Add here commands to clean up after the build process. 60 | -$(MAKE) distclean 61 | ifneq "$(wildcard /usr/share/misc/config.sub)" "" 62 | cp -f /usr/share/misc/config.sub config.sub 63 | endif 64 | ifneq "$(wildcard /usr/share/misc/config.guess)" "" 65 | cp -f /usr/share/misc/config.guess config.guess 66 | endif 67 | 68 | 69 | dh_clean 70 | 71 | install: build 72 | dh_testdir 73 | dh_testroot 74 | dh_clean -k 75 | dh_installdirs 76 | 77 | # Add here commands to install the package into debian/tmp 78 | $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp 79 | 80 | 81 | # Build architecture-independent files here. 82 | binary-indep: build install 83 | # We have nothing to do by default. 84 | 85 | # Build architecture-dependent files here. 86 | binary-arch: build install 87 | dh_testdir 88 | dh_testroot 89 | dh_installchangelogs ChangeLog 90 | dh_installdocs 91 | dh_installexamples 92 | dh_install --sourcedir=debian/tmp 93 | # dh_installmenu 94 | # dh_installdebconf 95 | # dh_installlogrotate 96 | # dh_installemacsen 97 | # dh_installpam 98 | # dh_installmime 99 | # dh_installinit 100 | # dh_installcron 101 | # dh_installinfo 102 | dh_installman 103 | dh_link 104 | dh_strip 105 | dh_compress 106 | dh_fixperms 107 | # dh_perl 108 | # dh_python 109 | dh_makeshlibs 110 | dh_installdeb 111 | dh_shlibdeps 112 | dh_gencontrol 113 | dh_md5sums 114 | dh_builddeb 115 | 116 | binary: binary-indep binary-arch 117 | .PHONY: build clean binary-indep binary-arch binary install 118 | -------------------------------------------------------------------------------- /packages/rpm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # Run this from the 'packages' directory, just under rootdir 4 | 5 | # We can only build rpm packages, if the rpm build tools are installed 6 | if [ \! -x /usr/bin/rpmbuild ] 7 | then 8 | echo "Cannot find /usr/bin/rpmbuild. Not building an rpm." 1>&2 9 | exit 0 10 | fi 11 | 12 | # Check the commandline flags 13 | PACKAGE="$1" 14 | VERSION="$2" 15 | fullname="${PACKAGE}-${VERSION}" 16 | archive=../$fullname.tar.gz 17 | 18 | if [ -z "$1" -o -z "$2" ] 19 | then 20 | echo "Usage: $0 " 1>&2 21 | exit 0 22 | fi 23 | 24 | # Double-check we're in the packages directory, just under rootdir 25 | if [ \! -r ../Makefile -a \! -r ../INSTALL ] 26 | then 27 | echo "Must run $0 in the 'packages' directory, under the root directory." 1>&2 28 | echo "Also, you must run \"make dist\" before running this script." 1>&2 29 | exit 0 30 | fi 31 | 32 | if [ \! -r "$archive" ] 33 | then 34 | echo "Cannot find $archive. Run \"make dist\" first." 1>&2 35 | exit 0 36 | fi 37 | 38 | # Create the directory where the input lives, and where the output should live 39 | RPM_SOURCE_DIR="/tmp/rpmsource-$fullname" 40 | RPM_BUILD_DIR="/tmp/rpmbuild-$fullname" 41 | 42 | trap 'rm -rf $RPM_SOURCE_DIR $RPM_BUILD_DIR; exit $?' EXIT SIGHUP SIGINT SIGTERM 43 | 44 | rm -rf "$RPM_SOURCE_DIR" "$RPM_BUILD_DIR" 45 | mkdir "$RPM_SOURCE_DIR" 46 | mkdir "$RPM_BUILD_DIR" 47 | 48 | cp "$archive" "$RPM_SOURCE_DIR" 49 | 50 | rpmbuild -bb rpm/rpm.spec \ 51 | --define "NAME $PACKAGE" \ 52 | --define "VERSION $VERSION" \ 53 | --define "_sourcedir $RPM_SOURCE_DIR" \ 54 | --define "_builddir $RPM_BUILD_DIR" \ 55 | --define "_rpmdir $RPM_SOURCE_DIR" 56 | 57 | # We put the output in a directory based on what system we've built for 58 | destdir=rpm-unknown 59 | if [ -r /etc/issue ] 60 | then 61 | grep "Red Hat.*release 7" /etc/issue >/dev/null 2>&1 && destdir=rh7 62 | grep "Red Hat.*release 8" /etc/issue >/dev/null 2>&1 && destdir=rh8 63 | grep "Red Hat.*release 9" /etc/issue >/dev/null 2>&1 && destdir=rh9 64 | if grep Fedora /etc/issue >/dev/null; then 65 | destdir=fc`grep Fedora /etc/issue | cut -d' ' -f 4`; 66 | fi 67 | fi 68 | 69 | rm -rf "$destdir" 70 | mkdir -p "$destdir" 71 | # We want to get not only the main package but devel etc, hence the middle * 72 | mv "$RPM_SOURCE_DIR"/*/"${PACKAGE}"-*"${VERSION}"*.rpm "$destdir" 73 | 74 | echo 75 | echo "The rpm package file(s) are located in $PWD/$destdir" 76 | -------------------------------------------------------------------------------- /src/cmockery/cmockery.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef CMOCKERY_H_ 17 | #define CMOCKERY_H_ 18 | 19 | #include 20 | 21 | // Windows 22 | #ifdef _WIN32 23 | #if _MSC_VER < 1500 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif // __cplusplus 27 | int __stdcall IsDebuggerPresent(); 28 | #ifdef __cplusplus 29 | } /* extern "C" */ 30 | #endif // __cplusplus 31 | #endif // _MSC_VER < 1500 32 | #endif // _WIN32 33 | 34 | /* 35 | * These headers or their equivalents should be included prior to including 36 | * this header file. 37 | * 38 | * #include 39 | * #include 40 | * #include 41 | * #include 42 | * 43 | * This allows test applications to use custom definitions of C standard 44 | * library functions and types. 45 | */ 46 | 47 | // For those who are used to __func__ from gcc. 48 | #ifndef __func__ 49 | #define __func__ __FUNCTION__ 50 | #endif 51 | 52 | /* Printf formats used to display uintmax_t. */ 53 | #ifdef _WIN32 54 | 55 | #ifndef PRIdMAX 56 | #define PRIdMAX "I64d" 57 | #endif /* PRIdMAX */ 58 | #ifndef PRIiMAX 59 | #define PRIiMAX "I64i" 60 | #endif /* PRIiMAX */ 61 | #ifndef PRIoMAX 62 | #define PRIoMAX "I64o" 63 | #endif /* PRIoMAX */ 64 | #ifndef PRIuMAX 65 | #define PRIuMAX "I64u" 66 | #endif /* PRIuMAX */ 67 | #ifndef PRIxMAX 68 | #define PRIxMAX "I64x" 69 | #endif /* PRIxMAX */ 70 | #ifndef PRIXMAX 71 | #define PRIXMAX "I64X" 72 | #endif /* PRIXMAX */ 73 | 74 | #else /* _WIN32 */ 75 | 76 | #ifndef PRIdMAX 77 | #define PRIdMAX "lld" 78 | #endif /* PRIdMAX */ 79 | #ifndef PRIiMAX 80 | #define PRIiMAX "lli" 81 | #endif /* PRIiMAX */ 82 | #ifndef PRIoMAX 83 | #define PRIoMAX "llo" 84 | #endif /* PRIoMAX */ 85 | #ifndef PRIuMAX 86 | #define PRIuMAX "llu" 87 | #endif /* PRIuMAX */ 88 | #ifndef PRIxMAX 89 | #define PRIxMAX "llx" 90 | #endif /* PRIxMAX */ 91 | #ifndef PRIXMAX 92 | #define PRIXMAX "llX" 93 | #endif /* PRIXMAX */ 94 | 95 | #endif /* _WIN32 */ 96 | 97 | // Perform an unsigned cast to uintmax_t. 98 | #define cast_to_largest_integral_type(value) \ 99 | ((uintmax_t)((size_t)(value))) 100 | 101 | /* Smallest integral type capable of holding a pointer. */ 102 | #ifndef _UINTPTR_T 103 | #define _UINTPTR_T 104 | #ifdef _WIN32 105 | 106 | /* WIN32 is an ILP32 platform */ 107 | typedef unsigned long uintptr_t; 108 | #endif /* _WIN32 */ 109 | #endif /* _UINTPTR_T */ 110 | 111 | /* Perform an unsigned cast to uintptr_t. */ 112 | #define cast_to_pointer_integral_type(value) \ 113 | ((uintptr_t)(value)) 114 | 115 | /* Perform a cast of a pointer to uintmax_t */ 116 | #define cast_ptr_to_largest_integral_type(value) \ 117 | cast_to_largest_integral_type(cast_to_pointer_integral_type(value)) 118 | 119 | // Retrieves a return value for the current function. 120 | #define mock() _mock(__func__, __FILE__, __LINE__) 121 | 122 | /* Stores a value to be returned by the specified function later. 123 | * The count parameter returns the number of times the value should be returned 124 | * by mock(). If count is set to -1 the value will always be returned. 125 | */ 126 | #define will_return(function, value) \ 127 | _will_return(#function, __FILE__, __LINE__, \ 128 | cast_to_largest_integral_type(value), 1) 129 | #define will_always_return(function, value) \ 130 | _will_return(#function, __FILE__, __LINE__, \ 131 | cast_to_largest_integral_type(value), -1) 132 | #define will_return_count(function, value, count) \ 133 | _will_return(#function, __FILE__, __LINE__, \ 134 | cast_to_largest_integral_type(value), count) 135 | 136 | /* Add a custom parameter checking function. If the event parameter is NULL 137 | * the event structure is allocated internally by this function. If event 138 | * parameter is provided it must be allocated on the heap and doesn't need to 139 | * be deallocated by the caller. 140 | */ 141 | #define expect_check(function, parameter, check_function, check_data) \ 142 | _expect_check(#function, #parameter, __FILE__, __LINE__, check_function, \ 143 | cast_to_largest_integral_type(check_data), NULL, 1) 144 | 145 | /* Add an event to check a parameter, using check_expected(), against a set of 146 | * values. See will_return() for a description of the count parameter. 147 | */ 148 | #define expect_in_set(function, parameter, value_array) \ 149 | expect_in_set_count(function, parameter, value_array, 1) 150 | #define expect_in_set_count(function, parameter, value_array, count) \ 151 | _expect_in_set(#function, #parameter, __FILE__, __LINE__, value_array, \ 152 | sizeof(value_array) / sizeof((value_array)[0]), count) 153 | #define expect_not_in_set(function, parameter, value_array) \ 154 | expect_not_in_set_count(function, parameter, value_array, 1) 155 | #define expect_not_in_set_count(function, parameter, value_array, count) \ 156 | _expect_not_in_set( \ 157 | #function, #parameter, __FILE__, __LINE__, value_array, \ 158 | sizeof(value_array) / sizeof((value_array)[0]), count) 159 | 160 | 161 | /* Add an event to check a parameter, using check_expected(), against a 162 | * signed range. Where range is minimum <= value <= maximum. 163 | * See will_return() for a description of the count parameter. 164 | */ 165 | #define expect_in_range(function, parameter, minimum, maximum) \ 166 | expect_in_range_count(function, parameter, minimum, maximum, 1) 167 | #define expect_in_range_count(function, parameter, minimum, maximum, count) \ 168 | _expect_in_range(#function, #parameter, __FILE__, __LINE__, minimum, \ 169 | maximum, count) 170 | 171 | /* Add an event to check a parameter, using check_expected(), against a 172 | * signed range. Where range is value < minimum or value > maximum. 173 | * See will_return() for a description of the count parameter. 174 | */ 175 | #define expect_not_in_range(function, parameter, minimum, maximum) \ 176 | expect_not_in_range_count(function, parameter, minimum, maximum, 1) 177 | #define expect_not_in_range_count(function, parameter, minimum, maximum, \ 178 | count) \ 179 | _expect_not_in_range(#function, #parameter, __FILE__, __LINE__, \ 180 | minimum, maximum, count) 181 | 182 | /* Add an event to check whether a parameter, using check_expected(), is or 183 | * isn't a value. See will_return() for a description of the count parameter. 184 | */ 185 | #define expect_value(function, parameter, value) \ 186 | expect_value_count(function, parameter, value, 1) 187 | #define expect_value_count(function, parameter, value, count) \ 188 | _expect_value(#function, #parameter, __FILE__, __LINE__, \ 189 | cast_to_largest_integral_type(value), count) 190 | #define expect_not_value(function, parameter, value) \ 191 | expect_not_value_count(function, parameter, value, 1) 192 | #define expect_not_value_count(function, parameter, value, count) \ 193 | _expect_not_value(#function, #parameter, __FILE__, __LINE__, \ 194 | cast_to_largest_integral_type(value), count) 195 | 196 | /* Add an event to check whether a parameter, using check_expected(), 197 | * is or isn't a string. See will_return() for a description of the count 198 | * parameter. 199 | */ 200 | #define expect_string(function, parameter, string) \ 201 | expect_string_count(function, parameter, string, 1) 202 | #define expect_string_count(function, parameter, string, count) \ 203 | _expect_string(#function, #parameter, __FILE__, __LINE__, \ 204 | (const char*)(string), count) 205 | #define expect_not_string(function, parameter, string) \ 206 | expect_not_string_count(function, parameter, string, 1) 207 | #define expect_not_string_count(function, parameter, string, count) \ 208 | _expect_not_string(#function, #parameter, __FILE__, __LINE__, \ 209 | (const char*)(string), count) 210 | 211 | /* Add an event to check whether a parameter, using check_expected() does or 212 | * doesn't match an area of memory. See will_return() for a description of 213 | * the count parameter. 214 | */ 215 | #define expect_memory(function, parameter, memory, size) \ 216 | expect_memory_count(function, parameter, memory, size, 1) 217 | #define expect_memory_count(function, parameter, memory, size, count) \ 218 | _expect_memory(#function, #parameter, __FILE__, __LINE__, \ 219 | (const void*)(memory), size, count) 220 | #define expect_not_memory(function, parameter, memory, size) \ 221 | expect_not_memory_count(function, parameter, memory, size, 1) 222 | #define expect_not_memory_count(function, parameter, memory, size, count) \ 223 | _expect_not_memory(#function, #parameter, __FILE__, __LINE__, \ 224 | (const void*)(memory), size, count) 225 | 226 | 227 | /* Add an event to allow any value for a parameter checked using 228 | * check_expected(). See will_return() for a description of the count 229 | * parameter. 230 | */ 231 | #define expect_any(function, parameter) \ 232 | expect_any_count(function, parameter, 1) 233 | #define expect_any_count(function, parameter, count) \ 234 | _expect_any(#function, #parameter, __FILE__, __LINE__, count) 235 | 236 | /* Determine whether a function parameter is correct. This ensures the next 237 | * value queued by one of the expect_*() macros matches the specified variable. 238 | */ 239 | #define check_expected(parameter) \ 240 | _check_expected(__func__, #parameter, __FILE__, __LINE__, \ 241 | cast_to_largest_integral_type(parameter)) 242 | 243 | // Assert that the given expression is true. 244 | #define assert_true(c) _assert_true(cast_to_largest_integral_type(c), #c, \ 245 | __FILE__, __LINE__) 246 | // Assert that the given expression is false. 247 | #define assert_false(c) _assert_true(!(cast_to_largest_integral_type(c)), #c, \ 248 | __FILE__, __LINE__) 249 | 250 | // Assert that the given pointer is non-NULL. 251 | #define assert_non_null(c) _assert_true(cast_ptr_to_largest_integral_type(c), #c, \ 252 | __FILE__, __LINE__) 253 | // Assert that the given pointer is NULL. 254 | #define assert_null(c) _assert_true(!(cast_ptr_to_largest_integral_type(c)), #c, \ 255 | __FILE__, __LINE__) 256 | 257 | // Assert two given pointers are equal 258 | #define assert_ptr_equal(a, b) \ 259 | _assert_int_equal(cast_ptr_to_largest_integral_type(a), \ 260 | cast_ptr_to_largest_integral_type(b), \ 261 | __FILE__, __LINE__) 262 | // Assert that the two given integers are not equal, otherwise fail. 263 | #define assert_ptr_not_equal(a, b) \ 264 | _assert_int_not_equal(cast_ptr_to_largest_integral_type(a), \ 265 | cast_ptr_to_largest_integral_type(b), \ 266 | __FILE__, __LINE__) 267 | 268 | // Assert that the two given integers are equal, otherwise fail. 269 | #define assert_int_equal(a, b) \ 270 | _assert_int_equal(cast_to_largest_integral_type(a), \ 271 | cast_to_largest_integral_type(b), \ 272 | __FILE__, __LINE__) 273 | // Assert that the two given integers are not equal, otherwise fail. 274 | #define assert_int_not_equal(a, b) \ 275 | _assert_int_not_equal(cast_to_largest_integral_type(a), \ 276 | cast_to_largest_integral_type(b), \ 277 | __FILE__, __LINE__) 278 | 279 | // Assert that the two given strings are equal, otherwise fail. 280 | #define assert_string_equal(a, b) \ 281 | _assert_string_equal((const char*)(a), (const char*)(b), __FILE__, \ 282 | __LINE__) 283 | // Assert that the two given strings are not equal, otherwise fail. 284 | #define assert_string_not_equal(a, b) \ 285 | _assert_string_not_equal((const char*)(a), (const char*)(b), __FILE__, \ 286 | __LINE__) 287 | 288 | // Assert that the two given areas of memory are equal, otherwise fail. 289 | #define assert_memory_equal(a, b, size) \ 290 | _assert_memory_equal((const char*)(a), (const char*)(b), size, __FILE__, \ 291 | __LINE__) 292 | // Assert that the two given areas of memory are not equal, otherwise fail. 293 | #define assert_memory_not_equal(a, b, size) \ 294 | _assert_memory_not_equal((const char*)(a), (const char*)(b), size, \ 295 | __FILE__, __LINE__) 296 | 297 | // Assert that the specified value is >= minimum and <= maximum. 298 | #define assert_in_range(value, minimum, maximum) \ 299 | _assert_in_range( \ 300 | cast_to_largest_integral_type(value), \ 301 | cast_to_largest_integral_type(minimum), \ 302 | cast_to_largest_integral_type(maximum), __FILE__, __LINE__) 303 | 304 | // Assert that the specified value is < minimum or > maximum 305 | #define assert_not_in_range(value, minimum, maximum) \ 306 | _assert_not_in_range( \ 307 | cast_to_largest_integral_type(value), \ 308 | cast_to_largest_integral_type(minimum), \ 309 | cast_to_largest_integral_type(maximum), __FILE__, __LINE__) 310 | 311 | // Assert that the specified value is within a set. 312 | #define assert_in_set(value, values, number_of_values) \ 313 | _assert_in_set(value, values, number_of_values, __FILE__, __LINE__) 314 | // Assert that the specified value is not within a set. 315 | #define assert_not_in_set(value, values, number_of_values) \ 316 | _assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__) 317 | 318 | 319 | // Forces the test to fail immediately and quit. 320 | #define fail() _fail(__FILE__, __LINE__) 321 | 322 | // Initializes a UnitTest structure. 323 | #define unit_test(f) { #f, f, UNIT_TEST_FUNCTION_TYPE_TEST } 324 | #define unit_test_setup(test, setup) \ 325 | { #test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP } 326 | #define unit_test_teardown(test, teardown) \ 327 | { #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN } 328 | 329 | // Used only for cmockery internal tests 330 | #define unit_test_expect_failure(f) \ 331 | { #f, f, UNIT_TEST_FUNCTION_TYPE_TEST_EXPECT_FAILURE} 332 | 333 | /* Initialize an array of UnitTest structures with a setup function for a test 334 | * and a teardown function. Either setup or teardown can be NULL. 335 | */ 336 | #define unit_test_setup_teardown(test, setup, teardown) \ 337 | unit_test_setup(test, setup), \ 338 | unit_test(test), \ 339 | unit_test_teardown(test, teardown) 340 | 341 | /* 342 | * Run tests specified by an array of UnitTest structures. The following 343 | * example illustrates this macro's use with the unit_test macro. 344 | * 345 | * void Test0(); 346 | * void Test1(); 347 | * 348 | * int main(int argc, char* argv[]) { 349 | * const UnitTest tests[] = { 350 | * unit_test(Test0); 351 | * unit_test(Test1); 352 | * }; 353 | * return run_tests(tests); 354 | * } 355 | */ 356 | #define run_tests(tests, test_suite_name) _run_tests(tests, \ 357 | sizeof(tests) / sizeof(tests)[0], \ 358 | (test_suite_name)) 359 | 360 | // Dynamic allocators 361 | #define test_malloc(size) _test_malloc(size, __FILE__, __LINE__) 362 | #define test_calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) 363 | #define test_free(ptr) _test_free(ptr, __FILE__, __LINE__) 364 | 365 | /* 366 | * Ensure mock_assert() is called. If mock_assert() is called the assert 367 | * expression string is returned. 368 | * For example: 369 | * 370 | * #define assert mock_assert 371 | * 372 | * void showmessage(const char *message) { 373 | * assert(message); 374 | * } 375 | * 376 | * int main(int argc, const char* argv[]) { 377 | * expect_assert_failure(show_message(NULL)); 378 | * printf("succeeded\n"); 379 | * return 0; 380 | * } 381 | */ 382 | #define expect_assert_failure(function_call) \ 383 | { \ 384 | const int result = setjmp(global_expect_assert_env); \ 385 | global_expecting_assert = 1; \ 386 | if (result) { \ 387 | print_message("Expected assertion %s occurred\n", \ 388 | global_last_failed_assert); \ 389 | global_expecting_assert = 0; \ 390 | } else { \ 391 | function_call ; \ 392 | global_expecting_assert = 0; \ 393 | print_error("Expected assert in %s\n", #function_call); \ 394 | _fail(__FILE__, __LINE__); \ 395 | } \ 396 | } 397 | 398 | // Function prototype for setup, test and teardown functions. 399 | typedef void (*UnitTestFunction)(void **state); 400 | 401 | // Function that determines whether a function parameter value is correct. 402 | typedef int (*CheckParameterValue)(const uintmax_t value, 403 | const uintmax_t check_value_data); 404 | 405 | // Type of the unit test function. 406 | typedef enum UnitTestFunctionType { 407 | /** Normal unit test */ 408 | UNIT_TEST_FUNCTION_TYPE_TEST = 0, 409 | /** Setup state for a unit test */ 410 | UNIT_TEST_FUNCTION_TYPE_SETUP, 411 | /** Teardown state used by a unit test */ 412 | UNIT_TEST_FUNCTION_TYPE_TEARDOWN, 413 | /** Used only for cmockery internal tests */ 414 | UNIT_TEST_FUNCTION_TYPE_TEST_EXPECT_FAILURE, 415 | } UnitTestFunctionType; 416 | 417 | /* Stores a unit test function with its name and type. 418 | * NOTE: Every setup function must be paired with a teardown function. It's 419 | * possible to specify NULL function pointers. 420 | */ 421 | typedef struct UnitTest { 422 | const char* name; 423 | UnitTestFunction function; 424 | UnitTestFunctionType function_type; 425 | } UnitTest; 426 | 427 | 428 | // Location within some source code. 429 | typedef struct SourceLocation { 430 | const char* file; 431 | int line; 432 | } SourceLocation; 433 | 434 | // Event that's called to check a parameter value. 435 | typedef struct CheckParameterEvent { 436 | SourceLocation location; 437 | const char *parameter_name; 438 | CheckParameterValue check_value; 439 | uintmax_t check_value_data; 440 | } CheckParameterEvent; 441 | 442 | // Used by expect_assert_failure() and mock_assert(). 443 | extern volatile int global_expecting_assert; 444 | extern jmp_buf global_expect_assert_env; 445 | extern const char * global_last_failed_assert; 446 | 447 | // Retrieves a value for the given function, as set by "will_return". 448 | uintmax_t _mock(const char * const function, const char* const file, 449 | const int line); 450 | 451 | void _expect_check( 452 | const char* const function, const char* const parameter, 453 | const char* const file, const int line, 454 | const CheckParameterValue check_function, 455 | const uintmax_t check_data, CheckParameterEvent * const event, 456 | const int count); 457 | 458 | void _expect_in_set( 459 | const char* const function, const char* const parameter, 460 | const char* const file, const int line, const uintmax_t values[], 461 | const size_t number_of_values, const int count); 462 | void _expect_not_in_set( 463 | const char* const function, const char* const parameter, 464 | const char* const file, const int line, const uintmax_t values[], 465 | const size_t number_of_values, const int count); 466 | 467 | void _expect_in_range( 468 | const char* const function, const char* const parameter, 469 | const char* const file, const int line, 470 | const uintmax_t minimum, 471 | const uintmax_t maximum, const int count); 472 | void _expect_not_in_range( 473 | const char* const function, const char* const parameter, 474 | const char* const file, const int line, 475 | const uintmax_t minimum, 476 | const uintmax_t maximum, const int count); 477 | 478 | void _expect_value( 479 | const char* const function, const char* const parameter, 480 | const char* const file, const int line, const uintmax_t value, 481 | const int count); 482 | void _expect_not_value( 483 | const char* const function, const char* const parameter, 484 | const char* const file, const int line, const uintmax_t value, 485 | const int count); 486 | 487 | void _expect_string( 488 | const char* const function, const char* const parameter, 489 | const char* const file, const int line, const char* string, 490 | const int count); 491 | void _expect_not_string( 492 | const char* const function, const char* const parameter, 493 | const char* const file, const int line, const char* string, 494 | const int count); 495 | 496 | void _expect_memory( 497 | const char* const function, const char* const parameter, 498 | const char* const file, const int line, const void* const memory, 499 | const size_t size, const int count); 500 | void _expect_not_memory( 501 | const char* const function, const char* const parameter, 502 | const char* const file, const int line, const void* const memory, 503 | const size_t size, const int count); 504 | 505 | void _expect_any( 506 | const char* const function, const char* const parameter, 507 | const char* const file, const int line, const int count); 508 | 509 | void _check_expected( 510 | const char * const function_name, const char * const parameter_name, 511 | const char* file, const int line, const uintmax_t value); 512 | 513 | void _will_return(const char * const function_name, const char * const file, 514 | const int line, const uintmax_t value, 515 | const int count); 516 | void _assert_true(const uintmax_t result, 517 | const char* const expression, 518 | const char * const file, const int line); 519 | void _assert_int_equal( 520 | const uintmax_t a, const uintmax_t b, 521 | const char * const file, const int line); 522 | void _assert_int_not_equal( 523 | const uintmax_t a, const uintmax_t b, 524 | const char * const file, const int line); 525 | void _assert_string_equal(const char * const a, const char * const b, 526 | const char * const file, const int line); 527 | void _assert_string_not_equal(const char * const a, const char * const b, 528 | const char *file, const int line); 529 | void _assert_memory_equal(const void * const a, const void * const b, 530 | const size_t size, const char* const file, 531 | const int line); 532 | void _assert_memory_not_equal(const void * const a, const void * const b, 533 | const size_t size, const char* const file, 534 | const int line); 535 | void _assert_in_range( 536 | const uintmax_t value, const uintmax_t minimum, 537 | const uintmax_t maximum, const char* const file, const int line); 538 | void _assert_not_in_range( 539 | const uintmax_t value, const uintmax_t minimum, 540 | const uintmax_t maximum, const char* const file, const int line); 541 | void _assert_in_set( 542 | const uintmax_t value, const uintmax_t values[], 543 | const size_t number_of_values, const char* const file, const int line); 544 | void _assert_not_in_set( 545 | const uintmax_t value, const uintmax_t values[], 546 | const size_t number_of_values, const char* const file, const int line); 547 | 548 | void _fail(const char * const file, const int line); 549 | 550 | // test_suite_name is the prefix to the %s_xunit.xml report 551 | int _run_tests(const UnitTest * const tests, 552 | const size_t number_of_tests, 553 | const char *test_suite_name); 554 | 555 | // Standard output and error print methods. 556 | void print_error(const char* const format, ...); 557 | void vprint_message(const char* const format, va_list args); 558 | void vprint_error(const char* const format, va_list args); 559 | 560 | #endif // CMOCKERY_H_ 561 | -------------------------------------------------------------------------------- /src/cmockery/cmockery_override.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Luis Pabon, Jr. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Override common functions to use test functions. 19 | * 20 | * Add the following as the last include to your code: 21 | * 22 | * #ifdef UNIT_TESTING 23 | * #include 24 | * #endif 25 | * 26 | */ 27 | #ifdef UNIT_TESTING 28 | 29 | #ifndef CMOCKERY_OVERRIDE_H_ 30 | #define CMOCKERY_OVERRIDE_H_ 31 | /* Prototypes */ 32 | extern void* _test_malloc(const size_t size, const char* file, const int line); 33 | extern void* _test_calloc(const size_t number_of_elements, const size_t size, 34 | const char* file, const int line); 35 | extern void* _test_realloc(void* ptr, const size_t size, const char* file, const int line); 36 | extern void _test_free(void* const ptr, const char* file, const int line); 37 | 38 | extern void print_message(const char *format, ...); 39 | 40 | // Can be used to replace assert in tested code so that in conjunction with 41 | // check_assert() it's possible to determine whether an assert condition has 42 | // failed without stopping a test. 43 | extern void mock_assert(const int result, const char* const expression, 44 | const char * const file, const int line); 45 | 46 | #endif /* CMOCKERY_OVERRIDE_H_ */ 47 | 48 | /* Reset any previous definitions */ 49 | #ifdef assert 50 | #undef assert 51 | #endif // assert 52 | 53 | #ifdef malloc 54 | #undef malloc 55 | #endif // malloc 56 | 57 | #ifdef calloc 58 | #undef calloc 59 | #endif // calloc 60 | 61 | #ifdef free 62 | #undef free 63 | #endif // free 64 | 65 | /* Redirect to use test functions */ 66 | #define assert(expression) \ 67 | mock_assert((int)(expression), #expression, __FILE__, __LINE__) 68 | 69 | // Redirect malloc, calloc and free to the unit test allocators. 70 | #define test_malloc(size) _test_malloc(size, __FILE__, __LINE__) 71 | #define test_calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) 72 | #define test_realloc(ptr, size) _test_realloc(ptr, size, __FILE__, __LINE__) 73 | #define test_free(ptr) _test_free(ptr, __FILE__, __LINE__) 74 | #define malloc test_malloc 75 | #define calloc test_calloc 76 | #define realloc test_realloc 77 | #define free test_free 78 | 79 | 80 | #endif /* UNIT_TESTING */ 81 | -------------------------------------------------------------------------------- /src/cmockery/pbc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Luis Pabon, Jr. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Programming by Contract is a programming methodology 19 | * which binds the caller and the function called to a 20 | * contract. The contract is represented using Hoare Triple: 21 | * {P} C {Q} 22 | * where {P} is the precondition before executing command C, 23 | * and {Q} is the postcondition. 24 | * 25 | * See also: 26 | * http://en.wikipedia.org/wiki/Design_by_contract 27 | * http://en.wikipedia.org/wiki/Hoare_logic 28 | * http://dlang.org/dbc.html 29 | */ 30 | #ifndef CMOCKERY_PBC_H_ 31 | #define CMOCKERY_PBC_H_ 32 | 33 | #if defined(UNIT_TESTING) || defined (DEBUG) 34 | 35 | #include 36 | 37 | /* 38 | * Checks caller responsibility against contract 39 | */ 40 | #define REQUIRE(cond) assert(cond) 41 | 42 | /* 43 | * Checks function reponsability against contract. 44 | */ 45 | #define ENSURE(cond) assert(cond) 46 | 47 | /* 48 | * While REQUIRE and ENSURE apply to functions, INVARIANT 49 | * applies to classes/structs. It ensures that intances 50 | * of the class/struct are consistent. In other words, 51 | * that the instance has not been corrupted. 52 | */ 53 | #define INVARIANT(invariant_fnc) do { (invariant_fnc) } while (0) 54 | 55 | #else 56 | 57 | #define REQUIRE(cond) do {} while (0) 58 | #define ENSURE(cond) do {} while (0) 59 | #define INVARIANT(invariant_fnc) do {} while (0) 60 | 61 | #endif /* defined(UNIT_TESTING) || defined (DEBUG) */ 62 | #endif /* CMOCKERY_PBC_H_ */ 63 | 64 | -------------------------------------------------------------------------------- /src/example/allocate_module.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifdef HAVE_CONFIG_H 17 | #include "config.h" 18 | #endif 19 | #ifdef HAVE_MALLOC_H 20 | #include 21 | #endif 22 | #include 23 | 24 | #ifdef UNIT_TESTING 25 | /* Must be last include */ 26 | #include 27 | #endif 28 | 29 | void leak_memory(void); 30 | void buffer_overflow(void); 31 | void buffer_underflow(void); 32 | 33 | void leak_memory(void) { 34 | int * const temporary = (int*)malloc(sizeof(int)); 35 | *temporary = 0; 36 | } 37 | 38 | void buffer_overflow(void) { 39 | char * const memory = (char*)malloc(sizeof(int)); 40 | memory[sizeof(int)] = '!'; 41 | free(memory); 42 | } 43 | 44 | void buffer_underflow(void) { 45 | char * const memory = (char*)malloc(sizeof(int)); 46 | memory[-1] = '!'; 47 | free(memory); 48 | } 49 | -------------------------------------------------------------------------------- /src/example/allocate_module_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | extern void leak_memory(); 23 | extern void buffer_overflow(); 24 | extern void buffer_underflow(); 25 | 26 | // Test case that fails as leak_memory() leaks a dynamically allocated block. 27 | static void leak_memory_test(void **state) { 28 | leak_memory(); 29 | } 30 | 31 | // Test case that fails as buffer_overflow() corrupts an allocated block. 32 | static void buffer_overflow_test(void **state) { 33 | buffer_overflow(); 34 | } 35 | 36 | // Test case that fails as buffer_underflow() corrupts an allocated block. 37 | static void buffer_underflow_test(void **state) { 38 | buffer_underflow(); 39 | } 40 | 41 | int main(int argc, char* argv[]) { 42 | const UnitTest tests[] = { 43 | unit_test_expect_failure(leak_memory_test), 44 | unit_test_expect_failure(buffer_overflow_test), 45 | unit_test_expect_failure(buffer_underflow_test), 46 | }; 47 | return run_tests(tests, "allocate_module_test"); 48 | } 49 | -------------------------------------------------------------------------------- /src/example/assert_macro.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | static const char* status_code_strings[] = { 19 | "Address not found", 20 | "Connection dropped", 21 | "Connection timed out", 22 | }; 23 | 24 | const char* get_status_code_string(const unsigned int status_code) { 25 | return status_code_strings[status_code]; 26 | }; 27 | 28 | unsigned int string_to_status_code(const char* const status_code_string) { 29 | unsigned int i; 30 | for (i = 0; i < sizeof(status_code_strings) / 31 | sizeof(status_code_strings[0]); i++) { 32 | if (strcmp(status_code_strings[i], status_code_string) == 0) { 33 | return i; 34 | } 35 | } 36 | return ~0U; 37 | } 38 | -------------------------------------------------------------------------------- /src/example/assert_macro_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | extern const char* get_status_code_string(const unsigned int status_code); 23 | extern unsigned int string_to_status_code( 24 | const char* const status_code_string); 25 | 26 | /* This test will fail since the string returned by get_status_code_string(0) 27 | * doesn't match "Connection timed out". */ 28 | void get_status_code_string_test(void **state) { 29 | assert_string_equal(get_status_code_string(0), "Address not found"); 30 | assert_string_equal(get_status_code_string(1), "Connection timed out"); 31 | } 32 | 33 | // This test will fail since the status code of "Connection timed out" isn't 1 34 | void string_to_status_code_test(void **state) { 35 | assert_int_equal(string_to_status_code("Address not found"), 0); 36 | assert_int_equal(string_to_status_code("Connection timed out"), 1); 37 | } 38 | 39 | int main(int argc, char *argv[]) { 40 | const UnitTest tests[] = { 41 | unit_test_expect_failure(get_status_code_string_test), 42 | unit_test_expect_failure(string_to_status_code_test), 43 | }; 44 | return run_tests(tests, "assert_macro"); 45 | } 46 | -------------------------------------------------------------------------------- /src/example/assert_module.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | // If unit testing is enabled override assert with mock_assert(). 19 | #ifdef UNIT_TESTING 20 | #include 21 | #include 22 | #endif 23 | 24 | void increment_value(int * const value) { 25 | assert(value); 26 | (*value) ++; 27 | } 28 | 29 | void decrement_value(int * const value) { 30 | if (value) { 31 | (*value) --; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/example/assert_module_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | extern void increment_value(int * const value); 23 | 24 | /* This test case will fail but the assert is caught by run_tests() and the 25 | * next test is executed. */ 26 | void increment_value_fail(void **state) { 27 | increment_value(NULL); 28 | } 29 | 30 | // This test case succeeds since increment_value() asserts on the NULL pointer. 31 | void increment_value_assert(void **state) { 32 | expect_assert_failure(increment_value(NULL)); 33 | } 34 | 35 | /* This test case fails since decrement_value() doesn't assert on a NULL 36 | * pointer. */ 37 | void decrement_value_fail(void **state) { 38 | expect_assert_failure(decrement_value(NULL)); 39 | } 40 | 41 | int main(int argc, char *argv[]) { 42 | const UnitTest tests[] = { 43 | unit_test(increment_value_fail), 44 | unit_test(increment_value_assert), 45 | unit_test(decrement_value_fail), 46 | }; 47 | return run_tests(tests, "assert_module"); 48 | } 49 | -------------------------------------------------------------------------------- /src/example/calculator.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // A calculator example used to demonstrate the cmockery testing library. 18 | 19 | #ifdef HAVE_CONFIG_H 20 | #include "config.h" 21 | #endif 22 | #include 23 | #ifdef HAVE_MALLOC_H 24 | #include 25 | #endif 26 | #include 27 | #include 28 | #include 29 | 30 | #include // From cmockery 31 | 32 | #ifdef UNIT_TESTING 33 | 34 | /* Redirect printf to a function in the test application so it's possible to 35 | * test the standard output. */ 36 | #ifdef printf 37 | #undef printf 38 | #endif // printf 39 | extern int example_test_printf(const char *format, ...); 40 | #define printf example_test_printf 41 | 42 | /* Redirect fprintf to a function in the test application so it's possible to 43 | * test error messages. */ 44 | #ifdef fprintf 45 | #undef fprintf 46 | #endif // fprintf 47 | extern int example_test_fprintf(FILE * const file, const char *format, ...); 48 | #define fprintf example_test_fprintf 49 | 50 | /* main is defined in the unit test so redefine name of the the main function 51 | * here. */ 52 | int example_main(int argc, char *argv[]); 53 | #define main example_main 54 | 55 | /* All functions in this object need to be exposed to the test application, 56 | * so redefine static to nothing. */ 57 | #define static 58 | 59 | #include 60 | #endif 61 | 62 | // A binary arithmetic integer operation (add, subtract etc.) 63 | typedef int (*BinaryOperator)(int a, int b); 64 | 65 | // Structure which maps operator strings to functions. 66 | typedef struct OperatorFunction { 67 | const char* operator; 68 | BinaryOperator function; 69 | } OperatorFunction; 70 | 71 | 72 | BinaryOperator find_operator_function_by_string( 73 | const size_t number_of_operator_functions, 74 | const OperatorFunction * const operator_functions, 75 | const char* const operator_string); 76 | 77 | int perform_operation( 78 | int number_of_arguments, char *arguments[], 79 | const size_t number_of_operator_functions, 80 | const OperatorFunction * const operator_functions, 81 | int * const number_of_intermediate_values, 82 | int ** const intermediate_values, int * const error_occurred); 83 | 84 | static int add(int a, int b); 85 | static int subtract(int a, int b); 86 | static int multiply(int a, int b); 87 | static int divide(int a, int b); 88 | 89 | // Associate operator strings to functions. 90 | static OperatorFunction operator_function_map[] = { 91 | {"+", add}, 92 | {"-", subtract}, 93 | {"*", multiply}, 94 | {"/", divide}, 95 | }; 96 | 97 | static int add(int a, int b) { 98 | return a + b; 99 | } 100 | 101 | static int subtract(int a, int b) { 102 | return a - b; 103 | } 104 | 105 | static int multiply(int a, int b) { 106 | return a * b; 107 | } 108 | 109 | static int divide(int a, int b) { 110 | REQUIRE(b != 0); // Check for divide by zero. 111 | return a / b; 112 | } 113 | 114 | /* Searches the specified array of operator_functions for the function 115 | * associated with the specified operator_string. This function returns the 116 | * function associated with operator_string if successful, NULL otherwise. 117 | */ 118 | BinaryOperator find_operator_function_by_string( 119 | const size_t number_of_operator_functions, 120 | const OperatorFunction * const operator_functions, 121 | const char* const operator_string) { 122 | size_t i; 123 | 124 | REQUIRE(!number_of_operator_functions || operator_functions); 125 | REQUIRE(operator_string != NULL); 126 | 127 | for (i = 0; i < number_of_operator_functions; i++) { 128 | const OperatorFunction *const operator_function = 129 | &operator_functions[i]; 130 | if (strcmp(operator_function->operator, operator_string) == 0) { 131 | return operator_function->function; 132 | } 133 | } 134 | return NULL; 135 | } 136 | 137 | /* Perform a series of binary arithmetic integer operations with no operator 138 | * precedence. 139 | * 140 | * The input expression is specified by arguments which is an array of 141 | * containing number_of_arguments strings. Operators invoked by the expression 142 | * are specified by the array operator_functions containing 143 | * number_of_operator_functions, OperatorFunction structures. The value of 144 | * each binary operation is stored in a pointer returned to intermediate_values 145 | * which is allocated by malloc(). 146 | * 147 | * If successful, this function returns the integer result of the operations. 148 | * If an error occurs while performing the operation error_occurred is set to 149 | * 1, the operation is aborted and 0 is returned. 150 | */ 151 | int perform_operation( 152 | int number_of_arguments, char *arguments[], 153 | const size_t number_of_operator_functions, 154 | const OperatorFunction * const operator_functions, 155 | int * const number_of_intermediate_values, 156 | int ** const intermediate_values, int * const error_occurred) { 157 | char *end_of_integer; 158 | int value; 159 | int i; 160 | REQUIRE(!number_of_arguments || arguments); 161 | REQUIRE(!number_of_operator_functions || operator_functions); 162 | REQUIRE(error_occurred != NULL); 163 | REQUIRE(number_of_intermediate_values != NULL); 164 | REQUIRE(intermediate_values != NULL); 165 | 166 | *error_occurred = 0; 167 | *number_of_intermediate_values = 0; 168 | *intermediate_values = NULL; 169 | if (!number_of_arguments) 170 | return 0; 171 | 172 | // Parse the first value. 173 | value = (int)strtol(arguments[0], &end_of_integer, 10); 174 | if (end_of_integer == arguments[0]) { 175 | // If an error occurred while parsing the integer. 176 | fprintf(stderr, "Unable to parse integer from argument %s\n", 177 | arguments[0]); 178 | *error_occurred = 1; 179 | return 0; 180 | } 181 | 182 | // Allocate an array for the output values. 183 | *intermediate_values = calloc(((number_of_arguments - 1) / 2), 184 | sizeof(**intermediate_values)); 185 | 186 | i = 1; 187 | while (i < number_of_arguments) { 188 | int other_value; 189 | const char* const operator_string = arguments[i]; 190 | const BinaryOperator function = find_operator_function_by_string( 191 | number_of_operator_functions, operator_functions, operator_string); 192 | int * const intermediate_value = 193 | &((*intermediate_values)[*number_of_intermediate_values]); 194 | (*number_of_intermediate_values) ++; 195 | 196 | if (!function) { 197 | fprintf(stderr, "Unknown operator %s, argument %d\n", 198 | operator_string, i); 199 | *error_occurred = 1; 200 | break; 201 | } 202 | i ++; 203 | 204 | if (i == number_of_arguments) { 205 | fprintf(stderr, "Binary operator %s missing argument\n", 206 | operator_string); 207 | *error_occurred = 1; 208 | break; 209 | } 210 | 211 | other_value = (int)strtol(arguments[i], &end_of_integer, 10); 212 | if (end_of_integer == arguments[i]) { 213 | // If an error occurred while parsing the integer. 214 | fprintf(stderr, "Unable to parse integer %s of argument %d\n", 215 | arguments[i], i); 216 | *error_occurred = 1; 217 | break; 218 | } 219 | i ++; 220 | 221 | // Perform the operation and store the intermediate value. 222 | *intermediate_value = function(value, other_value); 223 | value = *intermediate_value; 224 | } 225 | if (*error_occurred) { 226 | free(*intermediate_values); 227 | *intermediate_values = NULL; 228 | *number_of_intermediate_values = 0; 229 | return 0; 230 | } 231 | return value; 232 | } 233 | 234 | int main(int argc, char *argv[]) { 235 | int return_value; 236 | int number_of_intermediate_values; 237 | int *intermediate_values; 238 | // Peform the operation. 239 | const int result = perform_operation( 240 | argc - 1, &argv[1], 241 | sizeof(operator_function_map) / sizeof(operator_function_map[0]), 242 | operator_function_map, &number_of_intermediate_values, 243 | &intermediate_values, &return_value); 244 | 245 | // If no errors occurred display the result. 246 | if (!return_value && argc > 1) { 247 | int i; 248 | int intermediate_value_index = 0; 249 | printf("%s\n", argv[1]); 250 | for (i = 2; i < argc; i += 2) { 251 | assert(intermediate_value_index < number_of_intermediate_values); 252 | printf(" %s %s = %d\n", argv[i], argv[i + 1], 253 | intermediate_values[intermediate_value_index++]); 254 | } 255 | printf("= %d\n", result); 256 | } 257 | if (intermediate_values) { 258 | free(intermediate_values); 259 | } 260 | 261 | return return_value; 262 | } 263 | -------------------------------------------------------------------------------- /src/example/calculator_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "cmockery.h" 21 | #include 22 | 23 | #ifdef _WIN32 24 | // Compatibility with the Windows standard C library. 25 | #define vsnprintf _vsnprintf 26 | #endif // _WIN32 27 | 28 | #define array_length(x) (sizeof(x) / sizeof((x)[0])) 29 | 30 | /* To simplify this code, these functions and data structures could have been 31 | * separated out from the application example.c into a header shared with 32 | * test application. However, this example illustrates how it's possible to 33 | * test existing code with little modification. */ 34 | 35 | typedef int (*BinaryOperator)(int a, int b); 36 | 37 | typedef struct OperatorFunction { 38 | const char* operator; 39 | BinaryOperator function; 40 | } OperatorFunction; 41 | 42 | extern int add(int a, int b); 43 | extern int subtract(int a, int b); 44 | extern int multiply(int a, int b); 45 | extern int divide(int a, int b); 46 | extern BinaryOperator find_operator_function_by_string( 47 | const size_t number_of_operator_functions, 48 | const OperatorFunction * const operator_functions, 49 | const char* const operator_string); 50 | extern int perform_operation( 51 | int number_of_arguments, char *arguments[], 52 | const size_t number_of_operator_functions, 53 | const OperatorFunction * const operator_functions, 54 | int * const number_of_intermediate_values, 55 | int ** const intermediate_values, int * const error_occurred); 56 | extern int example_main(int argc, char *argv[]); 57 | 58 | int example_test_fprintf(FILE* const file, const char *format, ...); 59 | int example_test_printf(const char *format, ...); 60 | 61 | char temporary_buffer[256]; 62 | 63 | /* A mock fprintf function that checks the value of strings printed to the 64 | * standard error stream. */ 65 | int example_test_fprintf(FILE* const file, const char *format, ...) { 66 | int return_value; 67 | va_list args; 68 | assert_ptr_equal(file, stderr); 69 | va_start(args, format); 70 | return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer), 71 | format, args); 72 | check_expected(temporary_buffer); 73 | va_end(args); 74 | return return_value; 75 | } 76 | 77 | /* A mock printf function that checks the value of strings printed to the 78 | * standard output stream. */ 79 | int example_test_printf(const char *format, ...) { 80 | int return_value; 81 | va_list args; 82 | va_start(args, format); 83 | return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer), 84 | format, args); 85 | check_expected(temporary_buffer); 86 | va_end(args); 87 | return return_value; 88 | } 89 | 90 | // A mock binary operator function. 91 | static int binary_operator(int a, int b) { 92 | check_expected(a); 93 | check_expected(b); 94 | return (int)mock(); 95 | } 96 | 97 | 98 | // Ensure add() adds two integers correctly. 99 | static void test_add(void **state) { 100 | assert_int_equal(add(3, 3), 6); 101 | assert_int_equal(add(3, -3), 0); 102 | } 103 | 104 | // Ensure subtract() subtracts two integers correctly. 105 | static void test_subtract(void **state) { 106 | assert_int_equal(subtract(3, 3), 0); 107 | assert_int_equal(subtract(3, -3), 6); 108 | } 109 | 110 | // Ensure multiple() mulitplies two integers correctly. 111 | static void test_multiply(void **state) { 112 | assert_int_equal(multiply(3, 3), 9); 113 | assert_int_equal(multiply(3, 0), 0); 114 | } 115 | 116 | // Ensure divide() divides one integer by another correctly. 117 | static void test_divide(void **state) { 118 | assert_int_equal(divide(10, 2), 5); 119 | assert_int_equal(divide(2, 10), 0); 120 | } 121 | 122 | // Ensure divide() asserts when trying to divide by zero. 123 | static void test_divide_by_zero(void **state) { 124 | expect_assert_failure(divide(100, 0)); 125 | } 126 | 127 | /* Ensure find_operator_function_by_string() asserts when a NULL pointer is 128 | * specified as the table to search. */ 129 | static void test_find_operator_function_by_string_null_functions(void **state) { 130 | expect_assert_failure(find_operator_function_by_string(1, NULL, "test")); 131 | } 132 | 133 | /* Ensure find_operator_function_by_string() asserts when a NULL pointer is 134 | * specified as the string to search for. */ 135 | static void test_find_operator_function_by_string_null_string(void **state) { 136 | const OperatorFunction operator_functions[] = { 137 | {"+", binary_operator}, 138 | }; 139 | expect_assert_failure(find_operator_function_by_string( 140 | array_length(operator_functions), operator_functions, NULL)); 141 | } 142 | 143 | /* Ensure find_operator_function_by_string() returns NULL when a NULL pointer 144 | * is specified as the table to search when the table size is 0. */ 145 | static void test_find_operator_function_by_string_valid_null_functions(void **state) { 146 | assert_int_equal(find_operator_function_by_string(0, NULL, "test"), NULL); 147 | } 148 | 149 | /* Ensure find_operator_function_by_string() returns NULL when searching for 150 | * an operator string that isn't in the specified table. */ 151 | static void test_find_operator_function_by_string_not_found(void **state) { 152 | const OperatorFunction operator_functions[] = { 153 | {"+", binary_operator}, 154 | {"-", binary_operator}, 155 | {"/", binary_operator}, 156 | }; 157 | assert_int_equal(find_operator_function_by_string( 158 | array_length(operator_functions), operator_functions, "test"), 159 | NULL); 160 | } 161 | 162 | /* Ensure find_operator_function_by_string() returns the correct function when 163 | * searching for an operator string that is in the specified table. */ 164 | static void test_find_operator_function_by_string_found(void **state) { 165 | const OperatorFunction operator_functions[] = { 166 | {"+", (BinaryOperator)0x12345678}, 167 | {"-", (BinaryOperator)0xDEADBEEF}, 168 | {"/", (BinaryOperator)0xABADCAFE}, 169 | }; 170 | assert_int_equal(find_operator_function_by_string( 171 | array_length(operator_functions), operator_functions, "-"), 172 | 0xDEADBEEF); 173 | } 174 | 175 | // Ensure perform_operation() asserts when a NULL arguments array is specified. 176 | static void test_perform_operation_null_args(void **state) { 177 | const OperatorFunction operator_functions[] = { 178 | {"+", binary_operator}, 179 | }; 180 | int number_of_intermediate_values; 181 | int *intermediate_values; 182 | int error_occurred; 183 | expect_assert_failure(perform_operation( 184 | 1, NULL, array_length(operator_functions), operator_functions, 185 | &number_of_intermediate_values, &intermediate_values, 186 | &error_occurred)); 187 | } 188 | 189 | /* Ensure perform_operation() asserts when a NULL operator_functions array is 190 | * specified. */ 191 | static void test_perform_operation_null_operator_functions(void **state) { 192 | char *args[] = { 193 | "1", "+", "2", "*", "4" 194 | }; 195 | int number_of_intermediate_values; 196 | int *intermediate_values; 197 | int error_occurred; 198 | expect_assert_failure(perform_operation( 199 | array_length(args), args, 1, NULL, &number_of_intermediate_values, 200 | &intermediate_values, &error_occurred)); 201 | } 202 | 203 | /* Ensure perform_operation() asserts when a NULL pointer is specified for 204 | * number_of_intermediate_values. */ 205 | static void test_perform_operation_null_number_of_intermediate_values(void **state) { 206 | const OperatorFunction operator_functions[] = { 207 | {"+", binary_operator}, 208 | }; 209 | char *args[] = { 210 | "1", "+", "2", "*", "4" 211 | }; 212 | int *intermediate_values; 213 | int error_occurred; 214 | expect_assert_failure(perform_operation( 215 | array_length(args), args, 1, operator_functions, NULL, 216 | &intermediate_values, &error_occurred)); 217 | } 218 | 219 | /* Ensure perform_operation() asserts when a NULL pointer is specified for 220 | * intermediate_values. */ 221 | static void test_perform_operation_null_intermediate_values(void **state) { 222 | const OperatorFunction operator_functions[] = { 223 | {"+", binary_operator}, 224 | }; 225 | char *args[] = { 226 | "1", "+", "2", "*", "4" 227 | }; 228 | int number_of_intermediate_values; 229 | int error_occurred; 230 | expect_assert_failure(perform_operation( 231 | array_length(args), args, array_length(operator_functions), 232 | operator_functions, &number_of_intermediate_values, NULL, 233 | &error_occurred)); 234 | } 235 | 236 | // Ensure perform_operation() returns 0 when no arguments are specified. 237 | void test_perform_operation_no_arguments(void **state) { 238 | int number_of_intermediate_values; 239 | int *intermediate_values; 240 | int error_occurred; 241 | assert_int_equal(perform_operation( 242 | 0, NULL, 0, NULL, &number_of_intermediate_values, &intermediate_values, 243 | &error_occurred), 0); 244 | assert_int_equal(error_occurred, 0); 245 | } 246 | 247 | /* Ensure perform_operation() returns an error if the first argument isn't 248 | * an integer string. */ 249 | static void test_perform_operation_first_arg_not_integer(void **state) { 250 | const OperatorFunction operator_functions[] = { 251 | {"+", binary_operator}, 252 | }; 253 | char *args[] = { 254 | "test", "+", "2", "*", "4" 255 | }; 256 | int number_of_intermediate_values; 257 | int *intermediate_values; 258 | int error_occurred; 259 | 260 | expect_string(example_test_fprintf, temporary_buffer, 261 | "Unable to parse integer from argument test\n"); 262 | 263 | assert_int_equal(perform_operation( 264 | array_length(args), args, array_length(operator_functions), 265 | operator_functions, &number_of_intermediate_values, 266 | &intermediate_values, &error_occurred), 0); 267 | assert_int_equal(error_occurred, 1); 268 | } 269 | 270 | /* Ensure perform_operation() returns an error when parsing an unknown 271 | * operator. */ 272 | static void test_perform_operation_unknown_operator(void **state) { 273 | const OperatorFunction operator_functions[] = { 274 | {"+", binary_operator}, 275 | }; 276 | char *args[] = { 277 | "1", "*", "2", "*", "4" 278 | }; 279 | int number_of_intermediate_values; 280 | int *intermediate_values; 281 | int error_occurred; 282 | 283 | expect_string(example_test_fprintf, temporary_buffer, 284 | "Unknown operator *, argument 1\n"); 285 | 286 | assert_int_equal(perform_operation( 287 | array_length(args), args, array_length(operator_functions), 288 | operator_functions, &number_of_intermediate_values, 289 | &intermediate_values, &error_occurred), 0); 290 | assert_int_equal(error_occurred, 1); 291 | } 292 | 293 | /* Ensure perform_operation() returns an error when nothing follows an 294 | * operator. */ 295 | static void test_perform_operation_missing_argument(void **state) { 296 | const OperatorFunction operator_functions[] = { 297 | {"+", binary_operator}, 298 | }; 299 | char *args[] = { 300 | "1", "+", 301 | }; 302 | int number_of_intermediate_values; 303 | int *intermediate_values; 304 | int error_occurred; 305 | 306 | expect_string(example_test_fprintf, temporary_buffer, 307 | "Binary operator + missing argument\n"); 308 | 309 | assert_int_equal(perform_operation( 310 | array_length(args), args, array_length(operator_functions), 311 | operator_functions, &number_of_intermediate_values, 312 | &intermediate_values, &error_occurred), 0); 313 | assert_int_equal(error_occurred, 1); 314 | } 315 | 316 | /* Ensure perform_operation() returns an error when an integer doesn't follow 317 | * an operator. */ 318 | static void test_perform_operation_no_integer_after_operator(void **state) { 319 | const OperatorFunction operator_functions[] = { 320 | {"+", binary_operator}, 321 | }; 322 | char *args[] = { 323 | "1", "+", "test", 324 | }; 325 | int number_of_intermediate_values; 326 | int *intermediate_values; 327 | int error_occurred; 328 | 329 | expect_string(example_test_fprintf, temporary_buffer, 330 | "Unable to parse integer test of argument 2\n"); 331 | 332 | assert_int_equal(perform_operation( 333 | array_length(args), args, array_length(operator_functions), 334 | operator_functions, &number_of_intermediate_values, 335 | &intermediate_values, &error_occurred), 0); 336 | assert_int_equal(error_occurred, 1); 337 | } 338 | 339 | 340 | // Ensure perform_operation() succeeds given valid input parameters. 341 | static void test_perform_operation(void **state) { 342 | const OperatorFunction operator_functions[] = { 343 | {"+", binary_operator}, 344 | {"*", binary_operator}, 345 | }; 346 | char *args[] = { 347 | "1", "+", "3", "*", "10", 348 | }; 349 | int number_of_intermediate_values; 350 | int *intermediate_values; 351 | int error_occurred; 352 | 353 | // Setup return values of mock operator functions. 354 | // Addition. 355 | expect_value(binary_operator, a, 1); 356 | expect_value(binary_operator, b, 3); 357 | will_return(binary_operator, 4); 358 | 359 | // Multiplication. 360 | expect_value(binary_operator, a, 4); 361 | expect_value(binary_operator, b, 10); 362 | will_return(binary_operator, 40); 363 | 364 | assert_int_equal(perform_operation( 365 | array_length(args), args, array_length(operator_functions), 366 | operator_functions, &number_of_intermediate_values, 367 | &intermediate_values, &error_occurred), 40); 368 | assert_int_equal(error_occurred, 0); 369 | 370 | assert_true(intermediate_values); 371 | assert_int_equal(intermediate_values[0], 4); 372 | assert_int_equal(intermediate_values[1], 40); 373 | test_free(intermediate_values); 374 | } 375 | 376 | 377 | // Ensure main() in example.c succeeds given no arguments. 378 | static void test_example_main_no_args(void **state) { 379 | char *args[] = { 380 | "example", 381 | }; 382 | assert_int_equal(example_main(array_length(args), args), 0); 383 | } 384 | 385 | 386 | 387 | // Ensure main() in example.c succeeds given valid input arguments. 388 | static void test_example_main(void **state) { 389 | char *args[] = { 390 | "example", "1", "+", "3", "*", "10", 391 | }; 392 | 393 | expect_string(example_test_printf, temporary_buffer, "1\n"); 394 | expect_string(example_test_printf, temporary_buffer, " + 3 = 4\n"); 395 | expect_string(example_test_printf, temporary_buffer, " * 10 = 40\n"); 396 | expect_string(example_test_printf, temporary_buffer, "= 40\n"); 397 | 398 | assert_int_equal(example_main(array_length(args), args), 0); 399 | } 400 | 401 | 402 | int main(int argc, char* argv[]) { 403 | UnitTest tests[] = { 404 | unit_test(test_add), 405 | unit_test(test_subtract), 406 | unit_test(test_multiply), 407 | unit_test(test_divide), 408 | unit_test(test_divide_by_zero), 409 | unit_test(test_find_operator_function_by_string_null_functions), 410 | unit_test(test_find_operator_function_by_string_null_string), 411 | unit_test(test_find_operator_function_by_string_valid_null_functions), 412 | unit_test(test_find_operator_function_by_string_not_found), 413 | unit_test(test_find_operator_function_by_string_found), 414 | unit_test(test_perform_operation_null_args), 415 | unit_test(test_perform_operation_null_operator_functions), 416 | unit_test(test_perform_operation_null_number_of_intermediate_values), 417 | unit_test(test_perform_operation_null_intermediate_values), 418 | unit_test(test_perform_operation_no_arguments), 419 | unit_test(test_perform_operation_first_arg_not_integer), 420 | unit_test(test_perform_operation_unknown_operator), 421 | unit_test(test_perform_operation_missing_argument), 422 | unit_test(test_perform_operation_no_integer_after_operator), 423 | unit_test(test_perform_operation), 424 | unit_test(test_example_main_no_args), 425 | unit_test(test_example_main), 426 | }; 427 | return run_tests(tests, "calculator"); 428 | } 429 | -------------------------------------------------------------------------------- /src/example/customer_database.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #ifdef _WIN32 21 | #define snprintf _snprintf 22 | #endif // _WIN32 23 | 24 | DatabaseConnection* connect_to_customer_database(void); 25 | unsigned int get_customer_id_by_name( 26 | DatabaseConnection * const connection, 27 | const char * const customer_name); 28 | 29 | // Connect to the database containing customer information. 30 | DatabaseConnection* connect_to_customer_database(void) { 31 | return connect_to_database("customers.abcd.org", 321); 32 | } 33 | 34 | /* Find the ID of a customer by his/her name returning a value > 0 if 35 | * successful, 0 otherwise. */ 36 | unsigned int get_customer_id_by_name( 37 | DatabaseConnection * const connection, 38 | const char * const customer_name) { 39 | char query_string[256]; 40 | int number_of_results; 41 | void **results; 42 | snprintf(query_string, sizeof(query_string), 43 | "SELECT ID FROM CUSTOMERS WHERE NAME = %s", customer_name); 44 | number_of_results = connection->query_database(connection, query_string, 45 | &results); 46 | if (number_of_results != 1) { 47 | return -1; 48 | } 49 | return ((unsigned int *)results)[0]; 50 | } 51 | -------------------------------------------------------------------------------- /src/example/customer_database_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | extern DatabaseConnection* connect_to_customer_database(); 24 | extern unsigned int get_customer_id_by_name( 25 | DatabaseConnection * const connection, const char * const customer_name); 26 | 27 | // Mock query database function. 28 | static unsigned int mock_query_database( 29 | DatabaseConnection* const connection, const char * const query_string, 30 | void *** const results) { 31 | *results = (void**)((uintptr_t)mock()); 32 | return (unsigned int)mock(); 33 | } 34 | 35 | // Mock of the connect to database function. 36 | DatabaseConnection* connect_to_database(const char * const database_url, 37 | const unsigned int port) { 38 | return (DatabaseConnection*)((uintptr_t)mock()); 39 | } 40 | 41 | static void test_connect_to_customer_database(void **state) { 42 | will_return(connect_to_database, 0x0DA7ABA53); 43 | assert_int_equal((uintptr_t)connect_to_customer_database(), 0x0DA7ABA53); 44 | } 45 | 46 | /* This test fails as the mock function connect_to_database() will have no 47 | * value to return. */ 48 | static void test_fail_connect_to_customer_database(void **state) { 49 | assert_true(connect_to_customer_database() == 50 | (DatabaseConnection*)0x0DA7ABA53); 51 | } 52 | 53 | static void test_get_customer_id_by_name(void **state) { 54 | DatabaseConnection connection = { 55 | "somedatabase.somewhere.com", 12345678, mock_query_database 56 | }; 57 | // Return a single customer ID when mock_query_database() is called. 58 | int customer_ids = 543; 59 | will_return(mock_query_database, &customer_ids); 60 | will_return(mock_query_database, 1); 61 | assert_int_equal(get_customer_id_by_name(&connection, "john doe"), 543); 62 | } 63 | 64 | int main(void) { 65 | const UnitTest tests[] = { 66 | unit_test(test_connect_to_customer_database), 67 | unit_test(test_get_customer_id_by_name), 68 | unit_test_expect_failure(test_fail_connect_to_customer_database), 69 | }; 70 | return run_tests(tests, "customer_database"); 71 | } 72 | -------------------------------------------------------------------------------- /src/example/database.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | typedef struct DatabaseConnection DatabaseConnection; 17 | 18 | /* Function that takes an SQL query string and sets results to an array of 19 | * pointers with the result of the query. The value returned specifies the 20 | * number of items in the returned array of results. The returned array of 21 | * results are statically allocated and should not be deallocated using free() 22 | */ 23 | typedef unsigned int (*QueryDatabase)( 24 | DatabaseConnection* const connection, const char * const query_string, 25 | void *** const results); 26 | 27 | // Connection to a database. 28 | struct DatabaseConnection { 29 | const char *url; 30 | unsigned int port; 31 | QueryDatabase query_database; 32 | }; 33 | 34 | // Connect to a database. 35 | DatabaseConnection* connect_to_database(const char * const url, 36 | const unsigned int port); 37 | 38 | -------------------------------------------------------------------------------- /src/example/game.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | struct game_event; 5 | 6 | void run_game(void (*event_handler)(struct game_event *event), struct game_event *events[], int num_events) 7 | { 8 | int i = rand() % num_events; 9 | event_handler(events[i]); 10 | } /* run_game */ 11 | -------------------------------------------------------------------------------- /src/example/game_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct game_event { 10 | int id; 11 | const char *message; 12 | }; 13 | 14 | extern void run_game(void (*event_handler)(struct game_event *), struct game_event *events[], int num_events); 15 | 16 | /* Our version of "expect_string()". It only compares as much of the message as given by the check-string length. */ 17 | static int check_event_message(const uintmax_t value, const uintmax_t check_value_data) 18 | { 19 | const char *message = (const char *)value; 20 | const char *check = (const char *)check_value_data; 21 | assert_non_null(message); 22 | assert_non_null(check); 23 | 24 | /* Compare only the first part of the message determined by the check-string. */ 25 | return( memcmp(message, check, strlen(check)) == 0 ); 26 | } /* check_event_message */ 27 | 28 | static void my_event_handler1(struct game_event *event) 29 | { 30 | check_expected(event->id); 31 | } /* my_event_handler1 */ 32 | 33 | static void my_event_handler2(struct game_event *event) 34 | { 35 | check_expected(event->message); 36 | } /* my_event_handler1 */ 37 | 38 | static void test_run_game1(void **state) 39 | { 40 | int i; 41 | uintmax_t event_ids[5] = { 0, 1, 2, 3, 4 }; 42 | 43 | struct game_event game_events[5] = { 44 | { 3, "Event 3" }, 45 | { 1, "Event 1" }, 46 | { 4, "Event 4" }, 47 | { 2, "Event 2" }, 48 | { 0, "Event 0" }, 49 | }; 50 | 51 | struct game_event *events[5]; 52 | 53 | /* Populate the event list. */ 54 | for (i = 0; i < 5; i++) events[i] = &game_events[i]; 55 | 56 | expect_in_set(my_event_handler1, event->id, event_ids); 57 | run_game(my_event_handler1, events, 5); 58 | } /* test_run_game */ 59 | 60 | static void test_run_game2(void **state) 61 | { 62 | int i; 63 | 64 | struct game_event game_events[5] = { 65 | { 3, "Event: BANG" }, 66 | { 1, "Event: BONG" }, 67 | { 4, "Event: PING" }, 68 | { 2, "Event: ZOOM" }, 69 | { 0, "Event: POP" }, 70 | }; 71 | 72 | struct game_event *events[5]; 73 | 74 | /* Populate the event list. */ 75 | for (i = 0; i < 5; i++) events[i] = &game_events[i]; 76 | 77 | expect_check(my_event_handler2, event->message, check_event_message, "Event: "); 78 | run_game(my_event_handler2, events, 5); 79 | } /* test_run_game2 */ 80 | 81 | int main(void) { 82 | const UnitTest tests[] = { 83 | unit_test(test_run_game1), 84 | unit_test(test_run_game2), 85 | }; 86 | return run_tests(tests, "game"); 87 | } 88 | -------------------------------------------------------------------------------- /src/example/key_value.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | 20 | #include "key_value.h" 21 | 22 | static KeyValue *key_values = NULL; 23 | static unsigned int number_of_key_values = 0; 24 | 25 | void set_key_values(KeyValue * const new_key_values, 26 | const unsigned int new_number_of_key_values) { 27 | key_values = new_key_values; 28 | number_of_key_values = new_number_of_key_values; 29 | } 30 | 31 | // Compare two key members of KeyValue structures. 32 | static int key_value_compare_keys(const void *a, const void *b) { 33 | return (int)((KeyValue*)a)->key - (int)((KeyValue*)b)->key; 34 | } 35 | 36 | // Search an array of key value pairs for the item with the specified value. 37 | KeyValue* find_item_by_value(const char * const value) { 38 | unsigned int i; 39 | for (i = 0; i < number_of_key_values; i++) { 40 | if (strcmp(key_values[i].value, value) == 0) { 41 | return &key_values[i]; 42 | } 43 | } 44 | return NULL; 45 | } 46 | 47 | // Sort an array of key value pairs by key. 48 | void sort_items_by_key(void) { 49 | qsort(key_values, number_of_key_values, sizeof(*key_values), 50 | key_value_compare_keys); 51 | } 52 | -------------------------------------------------------------------------------- /src/example/key_value.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | typedef struct KeyValue { 18 | unsigned int key; 19 | const char* value; 20 | } KeyValue; 21 | 22 | void set_key_values(KeyValue * const new_key_values, 23 | const unsigned int new_number_of_key_values); 24 | 25 | KeyValue* find_item_by_value(const char * const value); 26 | 27 | void sort_items_by_key(void); 28 | -------------------------------------------------------------------------------- /src/example/key_value_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "key_value.h" 24 | 25 | static KeyValue key_values[] = { 26 | { 10, "this" }, 27 | { 52, "test" }, 28 | { 20, "a" }, 29 | { 13, "is" }, 30 | }; 31 | 32 | static void create_key_values(void **state) { 33 | KeyValue * const items = (KeyValue*)test_malloc(sizeof(key_values)); 34 | memcpy(items, key_values, sizeof(key_values)); 35 | *state = (void*)items; 36 | set_key_values(items, sizeof(key_values) / sizeof(key_values[0])); 37 | } 38 | 39 | static void destroy_key_values(void **state) { 40 | test_free(*state); 41 | set_key_values(NULL, 0); 42 | } 43 | 44 | static void test_find_item_by_value(void **state) { 45 | unsigned int i; 46 | for (i = 0; i < sizeof(key_values) / sizeof(key_values[0]); i++) { 47 | KeyValue * const found = find_item_by_value(key_values[i].value); 48 | assert_true(found != NULL); 49 | assert_int_equal(found->key, key_values[i].key); 50 | assert_string_equal(found->value, key_values[i].value); 51 | } 52 | } 53 | 54 | static void test_sort_items_by_key(void **state) { 55 | unsigned int i; 56 | KeyValue * const kv = *state; 57 | sort_items_by_key(); 58 | for (i = 1; i < sizeof(key_values) / sizeof(key_values[0]); i++) { 59 | assert_true(kv[i - 1].key < kv[i].key); 60 | } 61 | } 62 | 63 | int main(void) { 64 | const UnitTest tests[] = { 65 | unit_test_setup_teardown(test_find_item_by_value, create_key_values, 66 | destroy_key_values), 67 | unit_test_setup_teardown(test_sort_items_by_key, create_key_values, 68 | destroy_key_values), 69 | }; 70 | return run_tests(tests, "key_value"); 71 | } 72 | -------------------------------------------------------------------------------- /src/example/mem_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Luis Pabon, Jr. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | typedef struct { 24 | uintmax_t max; 25 | char c; 26 | void *v; 27 | } test_struct_t; 28 | 29 | static void 30 | test_struct_expect_memory_check( test_struct_t *some_struct ) 31 | { 32 | check_expected(some_struct); 33 | } 34 | 35 | static void 36 | test_expect_memory_check( void *some_pointer ) 37 | { 38 | check_expected(some_pointer); 39 | } 40 | 41 | static void test_expect_memory(void **state) { 42 | unsigned char some_data[32]; 43 | 44 | memset(some_data, 0xA5, sizeof(some_data)); 45 | 46 | // Check the memory is the same 47 | expect_memory(test_expect_memory_check, 48 | some_pointer, 49 | some_data, sizeof(some_data)); 50 | 51 | test_expect_memory_check(some_data); 52 | } 53 | 54 | static void test_expect_not_memory(void **state) { 55 | unsigned char some_data[32]; 56 | unsigned char zero_data[32]; 57 | 58 | memset(some_data, 0xA5, sizeof(some_data)); 59 | memset(zero_data, 0, sizeof(zero_data)); 60 | 61 | // Check the memory is not the same 62 | expect_not_memory(test_expect_memory_check, 63 | some_pointer, 64 | some_data, sizeof(some_data)); 65 | test_expect_memory_check(zero_data); 66 | } 67 | 68 | static void test_expect_memory_fail(void **state) { 69 | unsigned char some_data[32]; 70 | unsigned char zero_data[32]; 71 | 72 | memset(some_data, 0xA5, sizeof(some_data)); 73 | memset(zero_data, 0, sizeof(zero_data)); 74 | 75 | // Check the memory is the same 76 | expect_memory(test_expect_memory_check, 77 | some_pointer, 78 | some_data, sizeof(some_data)); 79 | 80 | test_expect_memory_check(zero_data); 81 | } 82 | 83 | static void test_expect_not_memory_fail(void **state) { 84 | unsigned char some_data[32]; 85 | 86 | memset(some_data, 0xA5, sizeof(some_data)); 87 | 88 | // Check the memory is not the same 89 | expect_not_memory(test_expect_memory_check, 90 | some_pointer, 91 | some_data, sizeof(some_data)); 92 | test_expect_memory_check(some_data); 93 | } 94 | 95 | static void test_struct_expect_memory(void **state) { 96 | test_struct_t *some_data; 97 | unsigned char *c; 98 | 99 | 100 | some_data = (test_struct_t *)calloc(1, sizeof(test_struct_t)); 101 | c = (unsigned char *)&(some_data->max); 102 | *c = 1; 103 | some_data->c = 2; 104 | some_data->v = test_malloc(10); 105 | 106 | // Check the memory is the same 107 | expect_memory(test_struct_expect_memory_check, 108 | some_struct, 109 | some_data, sizeof(test_struct_t)); 110 | 111 | test_struct_expect_memory_check(some_data); 112 | 113 | test_free(some_data->v); 114 | test_free(some_data); 115 | } 116 | 117 | int main(void) { 118 | const UnitTest tests[] = { 119 | unit_test(test_expect_memory), 120 | unit_test(test_expect_not_memory), 121 | unit_test_expect_failure(test_expect_memory_fail), 122 | unit_test_expect_failure(test_expect_not_memory_fail), 123 | unit_test(test_struct_expect_memory), 124 | }; 125 | 126 | return run_tests(tests, "mem_tests"); 127 | } 128 | -------------------------------------------------------------------------------- /src/example/product_database.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | DatabaseConnection* connect_to_product_database(void); 19 | 20 | // Connect to the database containing customer information. 21 | DatabaseConnection* connect_to_product_database(void) { 22 | return connect_to_database("products.abcd.org", 322); 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/example/product_database_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | extern DatabaseConnection* connect_to_product_database(void); 24 | 25 | /* Mock connect to database function. 26 | * NOTE: This mock function is very general could be shared between tests 27 | * that use the imaginary database.h module. */ 28 | DatabaseConnection* connect_to_database(const char * const url, 29 | const unsigned int port) { 30 | check_expected(url); 31 | check_expected(port); 32 | return (DatabaseConnection*)((uintptr_t)mock()); 33 | } 34 | 35 | static void test_connect_to_product_database(void **state) { 36 | expect_string(connect_to_database, url, "products.abcd.org"); 37 | expect_value(connect_to_database, port, 322); 38 | will_return(connect_to_database, 0xDA7ABA53); 39 | assert_int_equal((uintptr_t)connect_to_product_database(), 0xDA7ABA53); 40 | } 41 | 42 | /* This test will fail since the expected URL is different to the URL that is 43 | * passed to connect_to_database() by connect_to_product_database(). */ 44 | static void test_connect_to_product_database_bad_url(void **state) { 45 | expect_string(connect_to_database, url, "products.abcd.com"); 46 | expect_value(connect_to_database, port, 322); 47 | will_return(connect_to_database, 0xDA7ABA53); 48 | assert_int_equal((uintptr_t)connect_to_product_database(), 0xDA7ABA53); 49 | } 50 | 51 | /* This test will fail since the mock connect_to_database() will attempt to 52 | * retrieve a value for the parameter port which isn't specified by this 53 | * test function. */ 54 | static void test_connect_to_product_database_missing_parameter(void **state) { 55 | expect_string(connect_to_database, url, "products.abcd.org"); 56 | will_return(connect_to_database, 0xDA7ABA53); 57 | assert_int_equal((uintptr_t)connect_to_product_database(), 0xDA7ABA53); 58 | } 59 | 60 | int main(void) { 61 | const UnitTest tests[] = { 62 | unit_test(test_connect_to_product_database), 63 | unit_test_expect_failure(test_connect_to_product_database_bad_url), 64 | unit_test_expect_failure(test_connect_to_product_database_missing_parameter), 65 | }; 66 | return run_tests(tests, "product_database"); 67 | } 68 | -------------------------------------------------------------------------------- /src/example/realloc_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Luis Pabon, Jr. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | // A test case that does nothing and succeeds. 24 | static void realloc_tests(void **state) { 25 | 26 | typedef struct { 27 | int a; 28 | int b; 29 | char str[128]; 30 | } some_data_t; 31 | 32 | void *q; 33 | some_data_t *some_data; 34 | 35 | // Like a malloc 36 | q = test_realloc(NULL, 256); 37 | assert_non_null(q); 38 | 39 | // Like a free 40 | q = test_realloc(q, 0); 41 | assert_null(q); 42 | 43 | // Write some data 44 | some_data = (some_data_t *)test_malloc(sizeof(some_data_t)); 45 | assert_non_null(some_data); 46 | some_data->a = 1; 47 | some_data->b = 2; 48 | strcpy(some_data->str, "Hello World"); 49 | 50 | // Now realloc 51 | some_data = (some_data_t *)test_realloc(some_data, sizeof(some_data_t)*2); 52 | assert_int_equal(some_data->a, 1); 53 | assert_int_equal(some_data->a, 1); 54 | assert_string_equal(some_data->str, "Hello World"); 55 | 56 | // Now write some data to the next allocated chunk 57 | some_data[1].a = 3; 58 | some_data[1].b = 4; 59 | strcpy(some_data[1].str, "Hello Again"); 60 | 61 | // This call should not complain that we overwrote data 62 | test_free(some_data); 63 | } 64 | 65 | int main(void) { 66 | const UnitTest tests[] = { 67 | unit_test(realloc_tests), 68 | }; 69 | 70 | return run_tests(tests, "realloc"); 71 | } 72 | -------------------------------------------------------------------------------- /src/example/run_tests.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | // A test case that does nothing and succeeds. 23 | static void null_test_success(void **state) { 24 | (void) state; 25 | } 26 | 27 | int main(void) { 28 | const UnitTest tests[] = { 29 | unit_test(null_test_success), 30 | }; 31 | 32 | return run_tests(tests, "run"); 33 | } 34 | -------------------------------------------------------------------------------- /windows/makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2008 Google Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | # Microsoft Windows namke file which builds the cmockery library and example 17 | # applications. 18 | # 19 | # To use this makefile... 20 | # Select Start->Run and run "cmd.exe" to open the command line. 21 | # Run "vsvars.bat" located in Microsoft Visual Studio's directory. 22 | # Run "nmake" to build the cmockery library and example applications. 23 | # Run "nmake clean" to delete all files built by this makefile. 24 | 25 | # Target directories. 26 | !IFNDEF EXECUTABLE_DIR 27 | EXECUTABLE_DIR=. 28 | !ENDIF # EXECUTABLE_DIR 29 | 30 | !IFNDEF LIBRARY_DIR 31 | LIBRARY_DIR=. 32 | !ENDIF # LIBRARY_DIR 33 | 34 | !IFNDEF OBJECT_DIR 35 | OBJECT_DIR=. 36 | !ENDIF # OBJECT_DIR 37 | 38 | # Tools 39 | !IFNDEF LIBTOOL 40 | LIBTOOL=lib.exe 41 | !ENDIF # LIBTOOL 42 | 43 | !IFNDEF LINK 44 | LINK=link.exe 45 | !ENDIF # LINK 46 | 47 | # Source directories. 48 | !IFNDEF LIBRARY_SOURCE_DIRECTORY 49 | LIBRARY_SOURCE_DIRECTORY=..\src 50 | !ENDIF # LIBRARY_SOURCE_DIRECTORY 51 | !IFNDEF EXAMPLE_SOURCE_DIRECTORY 52 | EXAMPLE_SOURCE_DIRECTORY=..\src\example 53 | !ENDIF # EXAMPLE_SOURCE_DIRECTORY 54 | 55 | # Compiler flags and commands. 56 | CC_COMMAND=$(CC) /nologo /c /D_WIN32_WINNT=0x501 /DHAVE_MALLOC_H \ 57 | /I$(LIBRARY_SOURCE_DIRECTORY)\google $(CFLAGS) $(**) /Fo$(@) 58 | CC_COMMAND_UNIT_TEST=$(CC_COMMAND) /DUNIT_TESTING=1 \ 59 | /I$(EXAMPLE_SOURCE_DIRECTORY) 60 | 61 | # If debugging is enabled compile with symbols and stop on exceptions. 62 | !IFDEF UNIT_TESTING_DEBUG 63 | CC_COMMAND=$(CC_COMMAND) /DUNIT_TESTING_DEBUG=1 /Zi /Od 64 | LFLAGS=$(LFLAGS) /DEBUG 65 | !ENDIF # UNIT_TESTING_DEBUG 66 | 67 | LIBLINKFLAGS=/NOLOGO 68 | 69 | # Library archiver flags and command. 70 | LIB_COMMAND=$(LIBTOOL) $(LIBLINKFLAGS) $(LIBFLAGS) $(**) /OUT:$(@) 71 | 72 | # Linker flags and command. 73 | LINK_COMMAND=$(LINK) $(LIBLINKFLAGS) /SUBSYSTEM:console \ 74 | libcmt.lib kernel32.lib /NODEFAULTLIB:libc.lib \ 75 | $(LFLAGS) $(**) /OUT:$(@) 76 | 77 | .SUFFIXES: .exe .lib .obj .c 78 | 79 | all: $(EXECUTABLE_DIR) $(LIBRARY_DIR) $(OBJECT_DIR) \ 80 | $(LIBRARY_DIR)\cmockery.lib examples 81 | 82 | $(EXECUTABLE_DIR): 83 | mkdir $@ 84 | 85 | !IF "$(LIBRARY_DIR)" != "$(EXECUTABLE_DIR)" 86 | $(LIBRARY_DIR): 87 | mkdir $* 88 | !ENDIF 89 | 90 | !IF "$(OBJECT_DIR)" != "$(LIBRARY_DIR)" && \ 91 | "$(OBJECT_DIR)" != "$(EXECUTABLE_DIR)" 92 | $(OBJECT_DIR): 93 | mkdir $@ 94 | !ENDIF 95 | 96 | examples: \ 97 | $(EXECUTABLE_DIR)\calculator.exe \ 98 | $(EXECUTABLE_DIR)\calculator_test.exe \ 99 | $(EXECUTABLE_DIR)\allocate_module_test.exe \ 100 | $(EXECUTABLE_DIR)\assert_macro_test.exe \ 101 | $(EXECUTABLE_DIR)\customer_database_test.exe \ 102 | $(EXECUTABLE_DIR)\key_value_test.exe \ 103 | $(EXECUTABLE_DIR)\product_database_test.exe \ 104 | $(EXECUTABLE_DIR)\run_tests.exe 105 | 106 | clean: 107 | -cmd /c "@for %A in (\ 108 | $(LIBRARY_DIR)\cmockery.lib \ 109 | $(OBJECT_DIR)\cmockery.obj \ 110 | $(EXECUTABLE_DIR)\calculator.exe \ 111 | $(OBJECT_DIR)\calculator.obj \ 112 | $(EXECUTABLE_DIR)\calculator_test.exe \ 113 | $(OBJECT_DIR)\calculator_test.obj \ 114 | $(OBJECT_DIR)\calculator_test-calculator.obj \ 115 | $(EXECUTABLE_DIR)\allocate_module_test.exe \ 116 | $(OBJECT_DIR)\allocate_module_test.obj \ 117 | $(OBJECT_DIR)\allocate_module.obj \ 118 | $(EXECUTABLE_DIR)\assert_macro_test.exe \ 119 | $(OBJECT_DIR)\assert_macro_test.obj \ 120 | $(OBJECT_DIR)\assert_macro.obj \ 121 | $(EXECUTABLE_DIR)\customer_database_test.exe \ 122 | $(OBJECT_DIR)\customer_database_test.obj \ 123 | $(OBJECT_DIR)\customer_database.obj \ 124 | $(EXECUTABLE_DIR)\key_value_test.exe \ 125 | $(OBJECT_DIR)\key_value_test.obj \ 126 | $(OBJECT_DIR)\key_value.obj \ 127 | $(EXECUTABLE_DIR)\product_database_test.exe \ 128 | $(OBJECT_DIR)\product_database_test.obj \ 129 | $(OBJECT_DIR)\product_database.obj \ 130 | $(EXECUTABLE_DIR)\run_tests.exe \ 131 | $(OBJECT_DIR)\run_tests.obj) do @del %A 2>NUL" 132 | -rmdir $(EXECUTABLE_DIR) $(OBJECT_DIR) $(LIBRARY_DIR) 2>NUL 133 | 134 | # Rules for the cmockery library. 135 | $(LIBRARY_DIR)\cmockery.lib: $(OBJECT_DIR)\cmockery.obj 136 | $(OBJECT_DIR)\cmockery.obj: $(LIBRARY_SOURCE_DIRECTORY)\cmockery.c 137 | 138 | # Rules for the calculator application. 139 | $(EXECUTABLE_DIR)\calculator.exe: $(OBJECT_DIR)\calculator.obj 140 | 141 | $(OBJECT_DIR)\calculator.obj: $(EXAMPLE_SOURCE_DIRECTORY)\calculator.c 142 | $(CC_COMMAND) 143 | 144 | # Rules for the calculator test application. 145 | $(EXECUTABLE_DIR)\calculator_test.exe: \ 146 | $(OBJECT_DIR)\calculator_test.obj \ 147 | $(OBJECT_DIR)\calculator_test-calculator.obj \ 148 | $(LIBRARY_DIR)\cmockery.lib 149 | $(LINK_COMMAND) 150 | 151 | $(OBJECT_DIR)\calculator_test.obj: \ 152 | $(EXAMPLE_SOURCE_DIRECTORY)\calculator_test.c 153 | 154 | $(OBJECT_DIR)\calculator_test-calculator.obj: \ 155 | $(EXAMPLE_SOURCE_DIRECTORY)\calculator.c 156 | $(CC_COMMAND_UNIT_TEST) 157 | 158 | # Sample code applications. 159 | $(EXECUTABLE_DIR)\allocate_module_test.exe: \ 160 | $(OBJECT_DIR)\allocate_module_test.obj \ 161 | $(OBJECT_DIR)\allocate_module.obj \ 162 | $(LIBRARY_DIR)\cmockery.lib 163 | $(LINK_COMMAND) 164 | 165 | $(OBJECT_DIR)\allocate_module_test.obj: \ 166 | $(EXAMPLE_SOURCE_DIRECTORY)\allocate_module_test.c 167 | $(OBJECT_DIR)\allocate_module.obj: \ 168 | $(EXAMPLE_SOURCE_DIRECTORY)\allocate_module.c 169 | 170 | $(EXECUTABLE_DIR)\assert_macro_test.exe: \ 171 | $(OBJECT_DIR)\assert_macro_test.obj \ 172 | $(OBJECT_DIR)\assert_macro.obj \ 173 | $(LIBRARY_DIR)\cmockery.lib 174 | $(LINK_COMMAND) 175 | 176 | $(OBJECT_DIR)\assert_macro_test.obj: \ 177 | $(EXAMPLE_SOURCE_DIRECTORY)\assert_macro_test.c 178 | $(OBJECT_DIR)\assert_macro.obj: $(EXAMPLE_SOURCE_DIRECTORY)\assert_macro.c 179 | 180 | $(EXECUTABLE_DIR)\customer_database_test.exe: \ 181 | $(OBJECT_DIR)\customer_database_test.obj \ 182 | $(OBJECT_DIR)\customer_database.obj \ 183 | $(LIBRARY_DIR)\cmockery.lib 184 | $(LINK_COMMAND) 185 | 186 | $(OBJECT_DIR)\customer_database_test.obj: \ 187 | $(EXAMPLE_SOURCE_DIRECTORY)\customer_database_test.c 188 | $(OBJECT_DIR)\customer_database.obj: \ 189 | $(EXAMPLE_SOURCE_DIRECTORY)\customer_database.c 190 | 191 | $(EXECUTABLE_DIR)\key_value_test.exe: \ 192 | $(OBJECT_DIR)\key_value_test.obj \ 193 | $(OBJECT_DIR)\key_value.obj \ 194 | $(LIBRARY_DIR)\cmockery.lib 195 | $(LINK_COMMAND) 196 | 197 | $(OBJECT_DIR)\key_value_test.obj: $(EXAMPLE_SOURCE_DIRECTORY)\key_value_test.c 198 | $(OBJECT_DIR)\key_value.obj: $(EXAMPLE_SOURCE_DIRECTORY)\key_value.c 199 | 200 | $(EXECUTABLE_DIR)\product_database_test.exe: \ 201 | $(OBJECT_DIR)\product_database_test.obj \ 202 | $(OBJECT_DIR)\product_database.obj \ 203 | $(LIBRARY_DIR)\cmockery.lib 204 | $(LINK_COMMAND) 205 | 206 | $(OBJECT_DIR)\product_database_test.obj: \ 207 | $(EXAMPLE_SOURCE_DIRECTORY)\product_database_test.c 208 | $(OBJECT_DIR)\product_database.obj: \ 209 | $(EXAMPLE_SOURCE_DIRECTORY)\product_database.c 210 | 211 | $(EXECUTABLE_DIR)\run_tests.exe: \ 212 | $(OBJECT_DIR)\run_tests.obj $(LIBRARY_DIR)\cmockery.lib 213 | $(LINK_COMMAND) 214 | 215 | $(OBJECT_DIR)\run_tests.obj: $(EXAMPLE_SOURCE_DIRECTORY)\run_tests.c 216 | 217 | # Inference rules. 218 | {$(OBJECT_DIR)\}.obj{$(EXECUTABLE_DIR)\}.exe: 219 | $(LINK_COMMAND) 220 | 221 | {$(OBJECT_DIR)\}.obj{$(LIBRARY_DIR)\}.lib: 222 | $(LIB_COMMAND) 223 | 224 | {$(LIBRARY_SOURCE_DIRECTORY)\}.c{$(OBJECT_DIR)\}.obj: 225 | $(CC_COMMAND) 226 | 227 | {$(EXAMPLE_SOURCE_DIRECTORY)\}.c{$(OBJECT_DIR)\}.obj: 228 | $(CC_COMMAND_UNIT_TEST) 229 | --------------------------------------------------------------------------------