|
From: <tho...@us...> - 2014-04-06 16:56:10
|
Revision: 540
http://sourceforge.net/p/cgreen/code/540
Author: thomasnilsson
Date: 2014-04-06 16:55:59 +0000 (Sun, 06 Apr 2014)
Log Message:
-----------
Added description of strict, loose and learning mocks
Modified Paths:
--------------
trunk/cgreen/doc/CMakeLists.txt
trunk/cgreen/doc/README
trunk/cgreen/doc/cgreen-guide-en.asciidoc
Property Changed:
----------------
trunk/cgreen/
Index: trunk/cgreen
===================================================================
--- trunk/cgreen 2014-04-04 21:58:09 UTC (rev 539)
+++ trunk/cgreen 2014-04-06 16:55:59 UTC (rev 540)
Property changes on: trunk/cgreen
___________________________________________________________________
Modified: svn:ignore
## -1 +1 ##
-*.a
+build
Modified: trunk/cgreen/doc/CMakeLists.txt
===================================================================
--- trunk/cgreen/doc/CMakeLists.txt 2014-04-04 21:58:09 UTC (rev 539)
+++ trunk/cgreen/doc/CMakeLists.txt 2014-04-06 16:55:59 UTC (rev 540)
@@ -1,63 +1,63 @@
-
-FIND_PACKAGE(Asciidoc)
-
-SET(ASCIIDOC_CONFFILE "${CMAKE_SOURCE_DIR}/doc/cgreen_asciidoc.conf")
-SET(A2X_ICONS_DIR "${CMAKE_SOURCE_DIR}/images/icons")
-
-OPTION(WITH_HTML "with HTML output" FALSE)
-OPTION(WITH_PDF "with PDF output" FALSE)
-
-IF(ASCIIDOC_FOUND AND WITH_HTML)
- FILE(GLOB _docfiles *.asciidoc)
- FOREACH(_file ${_docfiles})
- GET_FILENAME_COMPONENT(_file_we ${_file} NAME_WE)
- SET(_in "${_file_we}")
- SET(_out "${_file_we}.html")
- IF (NOT "${_in}" STREQUAL "CMakeLists")
- ADD_CUSTOM_COMMAND(
- OUTPUT "${_out}-html"
- COMMAND ${ASCIIDOC_EXECUTABLE} -f ${ASCIIDOC_CONFFILE}
- -a toc
- -a docinfo -o ${_out} ${_file}
- DEPENDS ${_file}
- COMMENT "Asciidoc ${_in}"
- )
- ADD_CUSTOM_TARGET(${_in}-html ALL echo
- DEPENDS "${_out}-html"
- )
- ENDIF (NOT "${_in}" STREQUAL "CMakeLists")
- ENDFOREACH(_file)
-ENDIF(ASCIIDOC_FOUND AND WITH_HTML)
-
-IF(A2X_FOUND AND WITH_PDF)
- FILE(GLOB _docfiles *.asciidoc)
- FOREACH(_file ${_docfiles})
- GET_FILENAME_COMPONENT(_file_we ${_file} NAME_WE)
- SET(_in "${_file_we}")
- SET(_out "${_file_we}.html")
-
- IF("${_in}" MATCHES "pt_BR")
- SET(LANG "pt_BR")
- ELSE("${_in}" MATCHES "pt_BR")
- SET(LANG "en_US")
- ENDIF("${_in}" MATCHES "pt_BR")
-
- IF (NOT "${_in}" STREQUAL "CMakeLists")
- ADD_CUSTOM_COMMAND(
- OUTPUT "${_out}-pdf"
- COMMAND ${A2X_EXECUTABLE} -L -f pdf -a toc --fop -d book
- --icons-dir ${A2X_ICONS_DIR}
- -a lang=${LANG}
- -a docinfo
- -a toclevels=3
- -v
- --destination-dir ${CMAKE_BINARY_DIR}/doc ${_file}
- DEPENDS ${_file}
- COMMENT "a2x ${_in}"
- )
- ADD_CUSTOM_TARGET(${_in}-pdf ALL echo
- DEPENDS "${_out}-pdf"
- )
- ENDIF (NOT "${_in}" STREQUAL "CMakeLists")
- ENDFOREACH(_file)
-ENDIF(A2X_FOUND AND WITH_PDF)
+
+FIND_PACKAGE(Asciidoc)
+
+SET(ASCIIDOC_CONFFILE "${CMAKE_SOURCE_DIR}/doc/cgreen_asciidoc.conf")
+SET(A2X_ICONS_DIR "${CMAKE_SOURCE_DIR}/images/icons")
+
+OPTION(WITH_HTML "with HTML output" FALSE)
+OPTION(WITH_PDF "with PDF output" FALSE)
+
+IF(ASCIIDOC_FOUND AND WITH_HTML)
+ FILE(GLOB _docfiles *.asciidoc)
+ FOREACH(_file ${_docfiles})
+ GET_FILENAME_COMPONENT(_file_we ${_file} NAME_WE)
+ SET(_in "${_file_we}")
+ SET(_out "${_file_we}.html")
+ IF (NOT "${_in}" STREQUAL "CMakeLists")
+ ADD_CUSTOM_COMMAND(
+ OUTPUT "${_out}-html"
+ COMMAND ${ASCIIDOC_EXECUTABLE} -f ${ASCIIDOC_CONFFILE}
+ -a toc
+ -a docinfo -o ${_out} ${_file}
+ DEPENDS ${_file}
+ COMMENT "Asciidoc ${_in}"
+ )
+ ADD_CUSTOM_TARGET(${_in}-html ALL echo
+ DEPENDS "${_out}-html"
+ )
+ ENDIF (NOT "${_in}" STREQUAL "CMakeLists")
+ ENDFOREACH(_file)
+ENDIF(ASCIIDOC_FOUND AND WITH_HTML)
+
+IF(A2X_FOUND AND WITH_PDF)
+ FILE(GLOB _docfiles *.asciidoc)
+ FOREACH(_file ${_docfiles})
+ GET_FILENAME_COMPONENT(_file_we ${_file} NAME_WE)
+ SET(_in "${_file_we}")
+ SET(_out "${_file_we}.html")
+
+ IF("${_in}" MATCHES "pt_BR")
+ SET(LANG "pt_BR")
+ ELSE("${_in}" MATCHES "pt_BR")
+ SET(LANG "en_US")
+ ENDIF("${_in}" MATCHES "pt_BR")
+
+ IF (NOT "${_in}" STREQUAL "CMakeLists")
+ ADD_CUSTOM_COMMAND(
+ OUTPUT "${_out}-pdf"
+ COMMAND ${A2X_EXECUTABLE} -L -f pdf -a toc --fop -d book
+ --icons-dir ${A2X_ICONS_DIR}
+ -a lang=${LANG}
+ -a docinfo
+ -a toclevels=3
+ -v
+ --destination-dir ${CMAKE_BINARY_DIR}/doc ${_file}
+ DEPENDS ${_file}
+ COMMENT "a2x ${_in}"
+ )
+ ADD_CUSTOM_TARGET(${_in}-pdf ALL echo
+ DEPENDS "${_out}-pdf"
+ )
+ ENDIF (NOT "${_in}" STREQUAL "CMakeLists")
+ ENDFOREACH(_file)
+ENDIF(A2X_FOUND AND WITH_PDF)
Modified: trunk/cgreen/doc/README
===================================================================
--- trunk/cgreen/doc/README 2014-04-04 21:58:09 UTC (rev 539)
+++ trunk/cgreen/doc/README 2014-04-06 16:55:59 UTC (rev 540)
@@ -1,10 +1,13 @@
-HOW-TO: Compiling the Cgreen Guide
-======================================
-
-The Cgreen Guide Book is written using Asciidoc tool.
-
-Please visit http://www.methods.co.nz/asciidoc/.
-
-Asciidoc is a wonderful way to write textual docs using Docbook as backend.
-
-You also need source-highlight (http://www.gnu.org/software/src-highlite/source-highlight.html).
+HOW-TO: Compiling the Cgreen Guide
+======================================
+
+The Cgreen Guide Book is written using Asciidoc tool. Asciidoc is a
+wonderful way to write textual docs using Docbook as backend. Please
+visit http://www.asciidoc.org for more information.
+
+You also need source-highlight (http://www.gnu.org/software/src-highlite/source-highlight.html).
+
+NOTE that on cygwin the PDF generation does not work due to some error
+in the cygwin port of 'fop' (Apache's Formatting Object
+Processor). You can use Apache's binary distribution and use the
+Windows fop.bat for the fop-step manually. thoni56/2014-04-06
Modified: trunk/cgreen/doc/cgreen-guide-en.asciidoc
===================================================================
--- trunk/cgreen/doc/cgreen-guide-en.asciidoc 2014-04-04 21:58:09 UTC (rev 539)
+++ trunk/cgreen/doc/cgreen-guide-en.asciidoc 2014-04-06 16:55:59 UTC (rev 540)
@@ -1,4 +1,4 @@
-Cgreen Unit Test for C language
+Cgreen - Unit Tests for C and C++
===============================
Cgreen Quickstart Guide
@@ -125,8 +125,9 @@
This is a very unexciting test. It just creates an empty test suite
and runs it. It's usually easier to proceed in small steps, though,
and this is the smallest one I could think of. The only complication
-is the +cgreen.h+ header file. Here I am assuming we have the *Cgreen*
-folder in the path to ensure compilation works.
+is the +cgreen.h+ header file. Here I am assuming we have the
+*Cgreen* folder in the include search path to ensure compilation
+works, otherwise you'll need to add that in the compilation command.
Building this test is, of course, trivial...
@@ -251,17 +252,20 @@
*Cgreen* has two ways of running tests. The default is to run all
tests in their own protected processes. This is what happens if you
-invoke 'run_test_suite()'. All tests then independent since they run
-in separate processes, preventing a single run-away test from bringing
-the whole program down with it.
+invoke 'run_test_suite()'. All tests are then completely independent
+since they run in separate processes, preventing a single run-away
+test from bringing the whole program down with it. It also ensures
+that one test cannot leave any state to the next, thus forcing you to
+setup the prerequisites for each test correctly and clearly.
But if you want to debug any of your tests the constant 'fork()ing'
can make that difficult or impossible. To make debugging simpler,
*Cgreen* does not fork() when only a single test is run by name with
the function 'run_single_test()'. And if you want to debug, you can
-obviously set a breakpoint at that function. But since *Cgreen* does
-some book-keeping before actually getting to the test, a better
-function is the one simply called 'run()'.
+obviously set a breakpoint at that test (but note that its actual name
+might have been mangled) . But since *Cgreen* does some book-keeping
+before actually getting to the test, a better function is the one
+simply called 'run()'.
Building this scaffolding...
@@ -651,6 +655,7 @@
mistakes very obvious. It's taken me far longer to write these
paragraphs than it has to write the code.
+
Building Cgreen test suites
---------------------------
@@ -1976,6 +1981,108 @@
All done.
+=== Mocks Are...
+
+Using mocks is a very handy way to isolate a unit and catch and
+control calls to external units. Depending on your style of coding two
+schools of thinking have emerged. And of course *Cgreen* supports
+both!
+
+
+==== Strict or Loose Mocks ====
+
+The two schools are thinking a bit differently about what mock
+expectations means. Does it mean that all external calls must be
+declared and expected? What happens if a call was made to a mock that
+wasn't expected? And vice versa, if an expected call was not made?
+
+Actually, the thinking is not only a school of thought, but you might
+want to switch from one to the other. So *Cgreen* allows for that too.
+
+By default *Cgreen* mocks are ''strict'', which means that a call to
+an non-expected mock will be considered a failure. So will an expected
+call that was not fullfilled. You might consider this a way to define
+a unit through all its exact behaviours towards its neighbours.
+
+On the other hand, ''loose'' mocks are looser. They allow both
+unfullfilled expectations and try to handle unexpected calls in a
+reasonable way.
+
+You can use both with in the same suite of tests using the call
+'cgreen_mocks_are(strict_mocks);' and 'cgreen_mocks_are(loose_mocks);'
+respectively.
+
+
+==== Learning Mocks ====
+
+Working with legacy code and trying to apply TDD, BDD or even simply
+add some unit tests is not easy. You're working with unknown code that
+does unknown things with unknown counterparts.
+
+So the first step would be to isolate the unit. We won't go into
+details on how to do that here, but basically you would replace the
+interface to other units with mocks. This is a somewhat tedious manual
+labor, but will result in an isolated unit where you can start
+applying your unit tests.
+
+Once you have your unit isolated in a harness of mocks, we need to
+figure out which calls it does to other units, now replaced by mocks,
+in the specific case we are trying to test.
+
+This might be complicated, so *Cgreen* makes that a bit simpler. There
+is a third ''mode'' of the *Cgreen* mocks, the learning mocks.
+
+If you temporarily add the call 'cgreen_mocks_are(learning_mocks);' at
+the beginning of your unit test, the mocks will record all calls and
+present a list of those calls in order, including the actual parameter
+values, on the standard output.
+
+So let's look at the following example from the *Cgreen* unit
+tests. It's a bit contorted since the test actually call the mocked
+functions directly, but I believe it will serve as an example.
+
+[source,c]
+-----
+static char *string_out(int p1) {
+ return (char *)mock(p1);
+}
+
+static int integer_out() {
+ return (int)mock();
+}
+
+Ensure(Mocks, learning_mocks_emit_pastable_code) {
+ cgreen_mocks_are(learning_mocks);
+ string_out(1);
+ string_out(2);
+ integer_out();
+ integer_out();
+ string_out(3);
+ integer_out();
+}
+-----
+
+We can see the call to 'cgreen_mocks_are()' starting the test and
+setting the mocks into learning mode.
+
+If we run this, just as we usually run tests, the following will show
+up in our terminal:
+
+[source,c]
+----
+learning_mocks_emit_pastable_code: learned mocks:
+ expect(string_out, when(p1, is_equal_to(1)));
+ expect(string_out, when(p1, is_equal_to(2)));
+ expect(integer_out);
+ expect(integer_out);
+ expect(string_out, when(p1, is_equal_to(3)));
+ expect(integer_out);
+----
+
+If this were a real test we could just copy this and paste it in place
+of the call to 'cgreen_mocks_are()' and we're done.
+
+
BDD Style Cgreen
----------------
@@ -2748,7 +2855,7 @@
well take a lot of brain power.
So, it comes as no big surprise, that sometimes you write your test
-you forget to add it to the suite. When we run it it appears that it
+and then forget to add it to the suite. When we run it it appears that it
passed on the first try! Although this *should* really make you
suspicious, sometimes you get so happy that you just continue with
churning out more tests and more code. It's not until some (possibly
@@ -2859,17 +2966,7 @@
In both these cases you need to resort to the standard, programatic,
way of invoking your tests. But, who knows...
-[appendix]
-Revision History
-----------------
-.Revisions
-[options="header"]
-|=======================
-|Revision|Description |Responsible
-|1 |Initial |JF
-|=======================
-
[appendix]
GNU Free Documentation License
------------------------------
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|