mirror of
https://github.com/ThrowTheSwitch/CMock
synced 2025-05-16 01:39:33 -04:00
* split :args_only feature from :ignore plugin to be its own :expect_any_args plugin
* made :expect_any_args work with intermixed expects the way you would think it should work.
This commit is contained in:
parent
6bfe7ce784
commit
86594eea25
@ -1,82 +1,82 @@
|
||||
[All code is copyright © 2007-2010 Cmock Project
|
||||
by Mike Karlesky, Mark VanderVoord, and Greg Williams.
|
||||
|
||||
This Documentation Is Released Under a Creative Commons 3.0
|
||||
Attribution Share-Alike License]
|
||||
This Documentation Is Released Under a Creative Commons 3.0
|
||||
Attribution Share-Alike License]
|
||||
|
||||
|
||||
What the What?
|
||||
==============
|
||||
|
||||
CMock is a nice little tool which takes your header files and creates
|
||||
a Mock interface for it so that you can more easily Unit test modules
|
||||
that touch other modules. For each function prototype in your
|
||||
header, like this one:
|
||||
CMock is a nice little tool which takes your header files and creates
|
||||
a Mock interface for it so that you can more easily Unit test modules
|
||||
that touch other modules. For each function prototype in your
|
||||
header, like this one:
|
||||
|
||||
int DoesSomething(int a, int b);
|
||||
|
||||
|
||||
...you get an automatically generated DoesSomething function
|
||||
that you can link to instead of your real DoesSomething function.
|
||||
By using this Mocked version, you can then verify that it receives
|
||||
the data you want, and make it return whatever data you desire,
|
||||
make it throw errors when you want, and more... Create these for
|
||||
everything your latest real module touches, and you're suddenly
|
||||
in a position of power: You can control and verify every detail
|
||||
of your latest creation.
|
||||
|
||||
To make that easier, CMock also gives you a bunch of functions
|
||||
like the ones below, so you can tell that generated DoesSomething
|
||||
function how to behave for each test:
|
||||
...you get an automatically generated DoesSomething function
|
||||
that you can link to instead of your real DoesSomething function.
|
||||
By using this Mocked version, you can then verify that it receives
|
||||
the data you want, and make it return whatever data you desire,
|
||||
make it throw errors when you want, and more... Create these for
|
||||
everything your latest real module touches, and you're suddenly
|
||||
in a position of power: You can control and verify every detail
|
||||
of your latest creation.
|
||||
|
||||
To make that easier, CMock also gives you a bunch of functions
|
||||
like the ones below, so you can tell that generated DoesSomething
|
||||
function how to behave for each test:
|
||||
|
||||
void DoesSomething_ExpectAndReturn(int a, int b, int toReturn);
|
||||
void DoesSomething_ExpectAndThrow(int a, int b, EXCEPTION_T error);
|
||||
void DoesSomething_StubWithCallback(CMOCK_DoesSomething_CALLBACK YourCallback);
|
||||
void DoesSomething_IgnoreAndReturn(int toReturn);
|
||||
|
||||
|
||||
You can pile a bunch of these back to back, and it remembers what
|
||||
you wanted to pass when, like so:
|
||||
|
||||
You can pile a bunch of these back to back, and it remembers what
|
||||
you wanted to pass when, like so:
|
||||
|
||||
test_CallsDoesSomething_ShouldDoJustThat(void)
|
||||
{
|
||||
DoesSomething_ExpectAndReturn(1,2,3);
|
||||
DoesSomething_ExpectAndReturn(4,5,6);
|
||||
DoesSomething_ExpectAndThrow(7,8, STATUS_ERROR_OOPS);
|
||||
|
||||
|
||||
CallsDoesSomething( );
|
||||
}
|
||||
|
||||
|
||||
This test will call CallsDoesSomething, which is the function
|
||||
we are testing. We are expecting that function to call DoesSomething
|
||||
three times. The first time, we check to make sure it's called
|
||||
as DoesSomething(1, 2) and we'll magically return a 3. The second
|
||||
time we check for DoesSomething(4, 5) and we'll return a 6. The
|
||||
third time we verify DoesSomething(7, 8) and we'll throw an error
|
||||
instead of returning anything. If CallsDoesSomething gets
|
||||
any of this wrong, it fails the test. It will fail if you didn't
|
||||
call DoesSomething enough, or too much, or with the wrong arguments,
|
||||
or in the wrong order.
|
||||
|
||||
CMock is based on Unity, which it uses for all internal testing.
|
||||
It uses Ruby to do all the main work (versions 1.8.6 through 1.9.2).
|
||||
This test will call CallsDoesSomething, which is the function
|
||||
we are testing. We are expecting that function to call DoesSomething
|
||||
three times. The first time, we check to make sure it's called
|
||||
as DoesSomething(1, 2) and we'll magically return a 3. The second
|
||||
time we check for DoesSomething(4, 5) and we'll return a 6. The
|
||||
third time we verify DoesSomething(7, 8) and we'll throw an error
|
||||
instead of returning anything. If CallsDoesSomething gets
|
||||
any of this wrong, it fails the test. It will fail if you didn't
|
||||
call DoesSomething enough, or too much, or with the wrong arguments,
|
||||
or in the wrong order.
|
||||
|
||||
CMock is based on Unity, which it uses for all internal testing.
|
||||
It uses Ruby to do all the main work (versions 1.8.6 through 1.9.2).
|
||||
|
||||
|
||||
Generated Mock Module Summary
|
||||
=============================
|
||||
|
||||
In addition to the mocks themselves, CMock will generate the
|
||||
following functions for use in your tests. The expect functions
|
||||
are always generated. The other functions are only generated
|
||||
if those plugins are enabled:
|
||||
In addition to the mocks themselves, CMock will generate the
|
||||
following functions for use in your tests. The expect functions
|
||||
are always generated. The other functions are only generated
|
||||
if those plugins are enabled:
|
||||
|
||||
|
||||
Expect:
|
||||
-------
|
||||
|
||||
Your basic staple Expects which will be used for most of your day
|
||||
to day CMock work.
|
||||
Your basic staple Expects which will be used for most of your day
|
||||
to day CMock work.
|
||||
|
||||
* `void func(void)` => `void func_Expect(void)`
|
||||
* `void func(params)` => `void func_Expect(expected_params)`
|
||||
@ -87,9 +87,9 @@ to day CMock work.
|
||||
Array:
|
||||
------
|
||||
|
||||
An ExpectWithArray will check as many elements as you specify.
|
||||
If you specify zero elements, it will check just the pointer if
|
||||
`:smart` mode is configured or fail if `:compare_data` is set.
|
||||
An ExpectWithArray will check as many elements as you specify.
|
||||
If you specify zero elements, it will check just the pointer if
|
||||
`:smart` mode is configured or fail if `:compare_data` is set.
|
||||
|
||||
* `void func(void)` => (nothing. In fact, an additional function is only generated if the params list contains pointers)
|
||||
* `void func(ptr * param, other)` => `void func_ExpectWithArray(ptr* param, int param_depth, other)`
|
||||
@ -100,11 +100,11 @@ If you specify zero elements, it will check just the pointer if
|
||||
Callback:
|
||||
---------
|
||||
|
||||
As soon as you stub a callback in a test, it will call the callback
|
||||
whenever the mock is encountered and return the retval returned
|
||||
from the callback (if any) instead of performing the usual expect
|
||||
checks. It can be configured to check the arguments first (like
|
||||
expects) or just jump directly to the callback.
|
||||
As soon as you stub a callback in a test, it will call the callback
|
||||
whenever the mock is encountered and return the retval returned
|
||||
from the callback (if any) instead of performing the usual expect
|
||||
checks. It can be configured to check the arguments first (like
|
||||
expects) or just jump directly to the callback.
|
||||
|
||||
* `void func(void)` => `void func_StubWithCallback(CMOCK_func_CALLBACK callback)`
|
||||
where `CMOCK_func_CALLBACK` looks like: `void func(int NumCalls)`
|
||||
@ -119,10 +119,10 @@ where `CMOCK_func_CALLBACK` looks like: `retval func(params, int NumCalls)`
|
||||
Cexception:
|
||||
-----------
|
||||
|
||||
If you are using Cexception for error handling, you can use this
|
||||
to throw errors from inside mocks. Like Expects, it remembers
|
||||
which call was supposed to throw the error, and it still checks
|
||||
parameters.
|
||||
If you are using Cexception for error handling, you can use this
|
||||
to throw errors from inside mocks. Like Expects, it remembers
|
||||
which call was supposed to throw the error, and it still checks
|
||||
parameters.
|
||||
|
||||
* `void func(void)` => `void func_ExpectAndThrow(value_to_throw)`
|
||||
* `void func(params)` => `void func_ExpectAndThrow(expected_params, value_to_throw)`
|
||||
@ -133,10 +133,10 @@ parameters.
|
||||
Ignore:
|
||||
-------
|
||||
|
||||
This plugin supports two modes. You can use it to force CMock to
|
||||
ignore calls to specific functions or to just ignore the arguments
|
||||
passed to those functions. Either way you can specify multiple
|
||||
returns or a single value to always return, whichever you prefer.
|
||||
This plugin supports two modes. You can use it to force CMock to
|
||||
ignore calls to specific functions or to just ignore the arguments
|
||||
passed to those functions. Either way you can specify multiple
|
||||
returns or a single value to always return, whichever you prefer.
|
||||
|
||||
* `void func(void)` => `void func_Ignore(void)`
|
||||
* `void func(params)` => `void func_Ignore(void)`
|
||||
@ -147,59 +147,59 @@ returns or a single value to always return, whichever you prefer.
|
||||
Running CMock
|
||||
=============
|
||||
|
||||
CMock is a Ruby script and class. You can therefore use it directly
|
||||
from the command line, or include it in your own scripts or rakefiles.
|
||||
CMock is a Ruby script and class. You can therefore use it directly
|
||||
from the command line, or include it in your own scripts or rakefiles.
|
||||
|
||||
Mocking from the Command Line
|
||||
-----------------------------
|
||||
|
||||
After unpacking CMock, you will find CMock.rb in the 'lib' directory.
|
||||
This is the file that you want to run. It takes a list of header files
|
||||
to be mocked, as well as an optional yaml file for a more detailed
|
||||
configuration (see config options below).
|
||||
After unpacking CMock, you will find CMock.rb in the 'lib' directory.
|
||||
This is the file that you want to run. It takes a list of header files
|
||||
to be mocked, as well as an optional yaml file for a more detailed
|
||||
configuration (see config options below).
|
||||
|
||||
For example, this will create three mocks using the configuration
|
||||
specified in MyConfig.yml:
|
||||
For example, this will create three mocks using the configuration
|
||||
specified in MyConfig.yml:
|
||||
|
||||
ruby cmock.rb -oMyConfig.yml super.h duper.h awesome.h
|
||||
|
||||
And this will create two mocks using the default configuration:
|
||||
And this will create two mocks using the default configuration:
|
||||
|
||||
ruby cmock.rb ../mocking/stuff/is/fun.h ../try/it/yourself.h
|
||||
|
||||
Mocking From Scripts or Rake
|
||||
----------------------------
|
||||
|
||||
CMock can be used directly from your own scripts or from a rakefile.
|
||||
Start by including cmock.rb, then create an instance of CMock.
|
||||
When you create your instance, you may initialize it in one of
|
||||
three ways.
|
||||
CMock can be used directly from your own scripts or from a rakefile.
|
||||
Start by including cmock.rb, then create an instance of CMock.
|
||||
When you create your instance, you may initialize it in one of
|
||||
three ways.
|
||||
|
||||
You may specify nothing, allowing it to run with default settings:
|
||||
You may specify nothing, allowing it to run with default settings:
|
||||
|
||||
cmock = CMock.new
|
||||
|
||||
You may specify a YAML file containing the configuration options
|
||||
you desire:
|
||||
You may specify a YAML file containing the configuration options
|
||||
you desire:
|
||||
|
||||
cmock = CMock.new('../MyConfig.yml')
|
||||
|
||||
You may specify the options explicitly:
|
||||
You may specify the options explicitly:
|
||||
|
||||
cmock = Cmock.new(:plugins => [:cexception, :ignore], :mock_path => 'my/mocks/')
|
||||
|
||||
Config Options:
|
||||
Config Options:
|
||||
|
||||
The following configuration options can be specified in the
|
||||
yaml file or directly when instantiating.
|
||||
The following configuration options can be specified in the
|
||||
yaml file or directly when instantiating.
|
||||
|
||||
Passed as Ruby, they look like this:
|
||||
Passed as Ruby, they look like this:
|
||||
|
||||
{ :attributes => [“__funky”, “__intrinsic”], :when_ptr => :compare }
|
||||
|
||||
Defined in the yaml file, they look more like this:
|
||||
Defined in the yaml file, they look more like this:
|
||||
|
||||
:cmock:
|
||||
:cmock:
|
||||
:attributes:
|
||||
- __funky
|
||||
- __intrinsic
|
||||
@ -238,11 +238,6 @@ Defined in the yaml file, they look more like this:
|
||||
unity test frameworks (or if you write one for us), they'll get added
|
||||
here.
|
||||
|
||||
* `:ignore`:
|
||||
Tell `:ignore` plugin to ignore `:args_only` or `:args_and_calls`
|
||||
(default) where it doesn't even care how many times the mock was
|
||||
called
|
||||
|
||||
* `:includes`:
|
||||
An array of additional include files which should be added to the
|
||||
mocks. Useful for global types and definitions used in your project.
|
||||
@ -320,37 +315,37 @@ Defined in the yaml file, they look more like this:
|
||||
Compiled Options:
|
||||
-----------------
|
||||
|
||||
A number of #defines also exist for customizing the cmock experience.
|
||||
A number of #defines also exist for customizing the cmock experience.
|
||||
|
||||
CMOCK_MEM_STATIC or CMOCK_MEM_DYNAMIC
|
||||
CMOCK_MEM_STATIC or CMOCK_MEM_DYNAMIC
|
||||
|
||||
Define one of these to determine if you want to dynamically add
|
||||
memory during tests as required from the heap. If static, you
|
||||
can control the total footprint of Cmock. If dynamic, you will
|
||||
need to make sure you make some heap space available for Cmock.
|
||||
Define one of these to determine if you want to dynamically add
|
||||
memory during tests as required from the heap. If static, you
|
||||
can control the total footprint of Cmock. If dynamic, you will
|
||||
need to make sure you make some heap space available for Cmock.
|
||||
|
||||
CMOCK_MEM_SIZE
|
||||
CMOCK_MEM_SIZE
|
||||
|
||||
In static mode this is the total amount of memory you are allocating
|
||||
to Cmock. In Dynamic mode this is the size of each chunk allocated
|
||||
at once (larger numbers grab more memory but require less mallocs).
|
||||
In static mode this is the total amount of memory you are allocating
|
||||
to Cmock. In Dynamic mode this is the size of each chunk allocated
|
||||
at once (larger numbers grab more memory but require less mallocs).
|
||||
|
||||
CMOCK_MEM_ALIGN
|
||||
CMOCK_MEM_ALIGN
|
||||
|
||||
The way to align your data to. Not everything is as flexible as
|
||||
a PC, as most embedded designers know. This defaults to 2, meaning
|
||||
align to the closest 2^2 -> 4 bytes (32 bits). You can turn off alignment
|
||||
by setting 0, force alignment to the closest uint16 with 1 or even
|
||||
to the closest uint64 with 3.
|
||||
The way to align your data to. Not everything is as flexible as
|
||||
a PC, as most embedded designers know. This defaults to 2, meaning
|
||||
align to the closest 2^2 -> 4 bytes (32 bits). You can turn off alignment
|
||||
by setting 0, force alignment to the closest uint16 with 1 or even
|
||||
to the closest uint64 with 3.
|
||||
|
||||
CMOCK_MEM_PTR_AS_INT
|
||||
CMOCK_MEM_PTR_AS_INT
|
||||
|
||||
This is used internally to hold pointers... it needs to be big
|
||||
enough. On most processors a pointer is the same as an unsigned
|
||||
long... but maybe that's not true for yours?
|
||||
This is used internally to hold pointers... it needs to be big
|
||||
enough. On most processors a pointer is the same as an unsigned
|
||||
long... but maybe that's not true for yours?
|
||||
|
||||
CMOCK_MEM_INDEX_TYPE
|
||||
CMOCK_MEM_INDEX_TYPE
|
||||
|
||||
This needs to be something big enough to point anywhere in Cmock's
|
||||
memory space... usually it's an unsigned int.
|
||||
This needs to be something big enough to point anywhere in Cmock's
|
||||
memory space... usually it's an unsigned int.
|
||||
|
||||
|
@ -2,11 +2,11 @@
|
||||
# CMock Project - Automatic Mock Generation for C
|
||||
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
|
||||
# [Released under MIT License. Please refer to license.txt for details]
|
||||
# ==========================================
|
||||
# ==========================================
|
||||
|
||||
class CMockConfig
|
||||
|
||||
CMockDefaultOptions =
|
||||
|
||||
CMockDefaultOptions =
|
||||
{
|
||||
:framework => :unity,
|
||||
:mock_path => 'mocks',
|
||||
@ -24,24 +24,23 @@ class CMockConfig
|
||||
:when_ptr => :compare_data, #the options being :compare_ptr, :compare_data, or :smart
|
||||
:verbosity => 2, #the options being 0 errors only, 1 warnings and errors, 2 normal info, 3 verbose
|
||||
:treat_externs => :exclude, #the options being :include or :exclude
|
||||
:ignore => :args_and_calls, #the options being :args_and_calls or :args_only
|
||||
:callback_include_count => true,
|
||||
:callback_after_arg_check => false,
|
||||
:includes => nil,
|
||||
:includes_h_pre_orig_header => nil,
|
||||
:includes_h_post_orig_header => nil,
|
||||
:includes_c_pre_header => nil,
|
||||
:includes => nil,
|
||||
:includes_h_pre_orig_header => nil,
|
||||
:includes_h_post_orig_header => nil,
|
||||
:includes_c_pre_header => nil,
|
||||
:includes_c_post_header => nil
|
||||
}
|
||||
|
||||
|
||||
def initialize(options=nil)
|
||||
case(options)
|
||||
when NilClass then options = CMockDefaultOptions.clone
|
||||
when NilClass then options = CMockDefaultOptions.clone
|
||||
when String then options = CMockDefaultOptions.clone.merge(load_config_file_from_yaml(options))
|
||||
when Hash then options = CMockDefaultOptions.clone.merge(options)
|
||||
else raise "If you specify arguments, it should be a filename or a hash of options"
|
||||
end
|
||||
|
||||
|
||||
#do some quick type verification
|
||||
[:plugins, :attributes, :treat_as_void].each do |opt|
|
||||
unless (options[opt].class == Array)
|
||||
@ -59,30 +58,30 @@ class CMockConfig
|
||||
options[:plugins].compact!
|
||||
options[:plugins].map! {|p| p.to_sym}
|
||||
@options = options
|
||||
|
||||
|
||||
treat_as_map = standard_treat_as_map()#.clone
|
||||
treat_as_map.merge!(@options[:treat_as])
|
||||
@options[:treat_as] = treat_as_map
|
||||
|
||||
|
||||
@options.each_key { |key| eval("def #{key.to_s}() return @options[:#{key.to_s}] end") }
|
||||
end
|
||||
|
||||
|
||||
def load_config_file_from_yaml yaml_filename
|
||||
require 'yaml'
|
||||
require 'fileutils'
|
||||
YAML.load_file(yaml_filename)[:cmock]
|
||||
end
|
||||
|
||||
|
||||
def set_path(path)
|
||||
@src_path = path
|
||||
end
|
||||
|
||||
|
||||
def load_unity_helper
|
||||
return File.new(@options[:unity_helper_path]).read if (@options[:unity_helper_path])
|
||||
return nil
|
||||
end
|
||||
|
||||
def standard_treat_as_map
|
||||
def standard_treat_as_map
|
||||
{
|
||||
'int' => 'INT',
|
||||
'char' => 'INT8',
|
||||
|
67
lib/cmock_generator_plugin_expect_any_args.rb
Normal file
67
lib/cmock_generator_plugin_expect_any_args.rb
Normal file
@ -0,0 +1,67 @@
|
||||
# ==========================================
|
||||
# CMock Project - Automatic Mock Generation for C
|
||||
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
|
||||
# [Released under MIT License. Please refer to license.txt for details]
|
||||
# ==========================================
|
||||
|
||||
class CMockGeneratorPluginExpectAnyArgs
|
||||
|
||||
attr_reader :priority
|
||||
attr_reader :config, :utils
|
||||
|
||||
def initialize(config, utils)
|
||||
@config = config
|
||||
@utils = utils
|
||||
@priority = 3
|
||||
end
|
||||
|
||||
def instance_structure(function)
|
||||
if (function[:return][:void?]) || (@config.plugins.include? :ignore)
|
||||
""
|
||||
else
|
||||
" #{function[:return][:type]} #{function[:name]}_FinalReturn;\n"
|
||||
end
|
||||
end
|
||||
|
||||
def instance_typedefs(function)
|
||||
" CMOCK_ARG_MODE IgnoreMode;\n"
|
||||
end
|
||||
|
||||
def mock_function_declarations(function)
|
||||
|
||||
if (function[:return][:void?])
|
||||
return "#define #{function[:name]}_ExpectAnyArgs() #{function[:name]}_CMockExpectAnyArgs(__LINE__)\n" +
|
||||
"void #{function[:name]}_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line);\n"
|
||||
else
|
||||
return "#define #{function[:name]}_ExpectAnyArgsAndReturn(cmock_retval) #{function[:name]}_CMockExpectAnyArgsAndReturn(__LINE__, cmock_retval)\n" +
|
||||
"void #{function[:name]}_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n"
|
||||
end
|
||||
end
|
||||
|
||||
def mock_implementation(function)
|
||||
lines = " if (cmock_call_instance->IgnoreMode == CMOCK_ARG_NONE)\n {\n"
|
||||
if (function[:return][:void?])
|
||||
lines << " return;\n }\n"
|
||||
else
|
||||
retval = function[:return].merge( { :name => "cmock_call_instance->ReturnVal"} )
|
||||
lines << " " + @utils.code_assign_argument_quickly("Mock.#{function[:name]}_FinalReturn", retval) unless (retval[:void?])
|
||||
lines << " return cmock_call_instance->ReturnVal;\n }\n"
|
||||
end
|
||||
lines
|
||||
end
|
||||
|
||||
def mock_interfaces(function)
|
||||
lines = ""
|
||||
if (function[:return][:void?])
|
||||
lines << "void #{function[:name]}_CMockExpectAnyArgs(UNITY_LINE_TYPE cmock_line)\n{\n"
|
||||
else
|
||||
lines << "void #{function[:name]}_CMockExpectAnyArgsAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n"
|
||||
end
|
||||
lines << @utils.code_add_base_expectation(function[:name], true)
|
||||
unless (function[:return][:void?])
|
||||
lines << " cmock_call_instance->ReturnVal = cmock_to_return;\n"
|
||||
end
|
||||
lines << " cmock_call_instance->IgnoreMode = CMOCK_ARG_NONE;\n"
|
||||
lines << "}\n\n"
|
||||
end
|
||||
end
|
@ -2,28 +2,19 @@
|
||||
# CMock Project - Automatic Mock Generation for C
|
||||
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
|
||||
# [Released under MIT License. Please refer to license.txt for details]
|
||||
# ==========================================
|
||||
# ==========================================
|
||||
|
||||
class CMockGeneratorPluginIgnore
|
||||
|
||||
attr_reader :priority
|
||||
attr_reader :config, :utils
|
||||
|
||||
|
||||
def initialize(config, utils)
|
||||
@config = config
|
||||
if (@config.ignore == :args_and_calls)
|
||||
alias :mock_implementation_precheck :mock_implementation_for_ignores
|
||||
alias :mock_implementation :nothing
|
||||
alias :mock_verify :mock_conditionally_verify_counts
|
||||
else
|
||||
alias :mock_implementation :mock_implementation_for_ignores
|
||||
alias :mock_implementation_precheck :nothing
|
||||
alias :mock_verify :nothing
|
||||
end
|
||||
@utils = utils
|
||||
@priority = 2
|
||||
end
|
||||
|
||||
|
||||
def instance_structure(function)
|
||||
if (function[:return][:void?])
|
||||
" int #{function[:name]}_IgnoreBool;\n"
|
||||
@ -31,24 +22,19 @@ class CMockGeneratorPluginIgnore
|
||||
" int #{function[:name]}_IgnoreBool;\n #{function[:return][:type]} #{function[:name]}_FinalReturn;\n"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def mock_function_declarations(function)
|
||||
if (function[:return][:void?])
|
||||
if (@config.ignore == :args_only)
|
||||
return "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore(__LINE__)\n" +
|
||||
"void #{function[:name]}_CMockIgnore(UNITY_LINE_TYPE cmock_line);\n"
|
||||
else
|
||||
return "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore()\n" +
|
||||
"void #{function[:name]}_CMockIgnore(void);\n"
|
||||
end
|
||||
else
|
||||
return "#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore()\n" +
|
||||
"void #{function[:name]}_CMockIgnore(void);\n"
|
||||
else
|
||||
return "#define #{function[:name]}_IgnoreAndReturn(cmock_retval) #{function[:name]}_CMockIgnoreAndReturn(__LINE__, cmock_retval)\n" +
|
||||
"void #{function[:name]}_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]});\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def mock_implementation_for_ignores(function)
|
||||
lines = " if (Mock.#{function[:name]}_IgnoreBool)\n {\n"
|
||||
|
||||
def mock_implementation_precheck(function)
|
||||
lines = " if (Mock.#{function[:name]}_IgnoreBool)\n {\n"
|
||||
if (function[:return][:void?])
|
||||
lines << " return;\n }\n"
|
||||
else
|
||||
@ -59,22 +45,15 @@ class CMockGeneratorPluginIgnore
|
||||
end
|
||||
lines
|
||||
end
|
||||
|
||||
|
||||
def mock_interfaces(function)
|
||||
lines = ""
|
||||
args_only = (@config.ignore == :args_only)
|
||||
if (function[:return][:void?])
|
||||
if (args_only)
|
||||
lines << "void #{function[:name]}_CMockIgnore(UNITY_LINE_TYPE cmock_line)\n{\n"
|
||||
else
|
||||
lines << "void #{function[:name]}_CMockIgnore(void)\n{\n"
|
||||
end
|
||||
lines << "void #{function[:name]}_CMockIgnore(void)\n{\n"
|
||||
else
|
||||
lines << "void #{function[:name]}_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, #{function[:return][:str]})\n{\n"
|
||||
end
|
||||
if (args_only)
|
||||
lines << @utils.code_add_base_expectation(function[:name], true)
|
||||
elsif (!function[:return][:void?])
|
||||
if (!function[:return][:void?])
|
||||
lines << @utils.code_add_base_expectation(function[:name], false)
|
||||
end
|
||||
unless (function[:return][:void?])
|
||||
@ -84,12 +63,8 @@ class CMockGeneratorPluginIgnore
|
||||
lines << "}\n\n"
|
||||
end
|
||||
|
||||
def mock_conditionally_verify_counts(function)
|
||||
def mock_conditionally_verify(function)
|
||||
func_name = function[:name]
|
||||
" if (Mock.#{func_name}_IgnoreBool)\n Mock.#{func_name}_CallInstance = CMOCK_GUTS_NONE;\n"
|
||||
end
|
||||
|
||||
def nothing(function)
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
@ -2,7 +2,7 @@
|
||||
# CMock Project - Automatic Mock Generation for C
|
||||
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
|
||||
# [Released under MIT License. Please refer to license.txt for details]
|
||||
# ==========================================
|
||||
# ==========================================
|
||||
|
||||
class CMockGeneratorUtils
|
||||
|
||||
@ -14,22 +14,23 @@ class CMockGeneratorUtils
|
||||
@ordered = @config.enforce_strict_ordering
|
||||
@arrays = @config.plugins.include? :array
|
||||
@cexception = @config.plugins.include? :cexception
|
||||
@expect_any = @config.plugins.include? :expect_any_args
|
||||
@return_thru_ptr = @config.plugins.include? :return_thru_ptr
|
||||
@ignore_arg = @config.plugins.include? :ignore_arg
|
||||
@treat_as = @config.treat_as
|
||||
@helpers = helpers
|
||||
|
||||
|
||||
if (@arrays)
|
||||
case(@ptr_handling)
|
||||
when :smart then alias :code_verify_an_arg_expectation :code_verify_an_arg_expectation_with_smart_arrays
|
||||
when :compare_data then alias :code_verify_an_arg_expectation :code_verify_an_arg_expectation_with_normal_arrays
|
||||
when :smart then alias :code_verify_an_arg_expectation :code_verify_an_arg_expectation_with_smart_arrays
|
||||
when :compare_data then alias :code_verify_an_arg_expectation :code_verify_an_arg_expectation_with_normal_arrays
|
||||
when :compare_ptr then raise "ERROR: the array plugin doesn't enjoy working with :compare_ptr only. Disable one option."
|
||||
end
|
||||
else
|
||||
alias :code_verify_an_arg_expectation :code_verify_an_arg_expectation_with_no_arrays
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def code_add_base_expectation(func_name, global_ordering_supported=true)
|
||||
lines = " CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_#{func_name}_CALL_INSTANCE));\n"
|
||||
lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = (CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);\n"
|
||||
@ -38,37 +39,38 @@ class CMockGeneratorUtils
|
||||
lines << " cmock_call_instance->LineNumber = cmock_line;\n"
|
||||
lines << " cmock_call_instance->CallOrder = ++GlobalExpectCount;\n" if (@ordered and global_ordering_supported)
|
||||
lines << " cmock_call_instance->ExceptionToThrow = CEXCEPTION_NONE;\n" if (@cexception)
|
||||
lines << " cmock_call_instance->IgnoreMode = CMOCK_ARG_ALL;\n" if (@expect_any)
|
||||
lines
|
||||
end
|
||||
|
||||
def code_add_an_arg_expectation(arg, depth=1)
|
||||
|
||||
def code_add_an_arg_expectation(arg, depth=1)
|
||||
lines = code_assign_argument_quickly("cmock_call_instance->Expected_#{arg[:name]}", arg)
|
||||
lines << " cmock_call_instance->Expected_#{arg[:name]}_Depth = #{arg[:name]}_Depth;\n" if (@arrays and (depth.class == String))
|
||||
lines << " cmock_call_instance->IgnoreArg_#{arg[:name]} = 0;\n" if (@ignore_arg)
|
||||
lines << " cmock_call_instance->ReturnThruPtr_#{arg[:name]}_Used = 0;\n" if (@return_thru_ptr and ptr_or_str?(arg[:type]) and not arg[:const?])
|
||||
lines
|
||||
end
|
||||
|
||||
def code_assign_argument_quickly(dest, arg)
|
||||
|
||||
def code_assign_argument_quickly(dest, arg)
|
||||
if (arg[:ptr?] or @treat_as.include?(arg[:type]))
|
||||
" #{dest} = #{arg[:const?] ? "(#{arg[:type]})" : ''}#{arg[:name]};\n"
|
||||
else
|
||||
" memcpy(&#{dest}, &#{arg[:name]}, sizeof(#{arg[:type]}));\n"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def code_add_argument_loader(function)
|
||||
if (function[:args_string] != "void")
|
||||
if (@arrays)
|
||||
args_string = function[:args].map do |m|
|
||||
args_string = function[:args].map do |m|
|
||||
const_str = m[ :const? ] ? 'const ' : ''
|
||||
m[:ptr?] ? "#{const_str}#{m[:type]} #{m[:name]}, int #{m[:name]}_Depth" : "#{const_str}#{m[:type]} #{m[:name]}"
|
||||
end.join(', ')
|
||||
"void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{args_string})\n{\n" +
|
||||
"void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{args_string})\n{\n" +
|
||||
function[:args].inject("") { |all, arg| all + code_add_an_arg_expectation(arg, (arg[:ptr?] ? "#{arg[:name]}_Depth" : 1) ) } +
|
||||
"}\n\n"
|
||||
else
|
||||
"void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{function[:args_string]})\n{\n" +
|
||||
"void CMockExpectParameters_#{function[:name]}(CMOCK_#{function[:name]}_CALL_INSTANCE* cmock_call_instance, #{function[:args_string]})\n{\n" +
|
||||
function[:args].inject("") { |all, arg| all + code_add_an_arg_expectation(arg) } +
|
||||
"}\n\n"
|
||||
end
|
||||
@ -76,25 +78,25 @@ class CMockGeneratorUtils
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def code_call_argument_loader(function)
|
||||
if (function[:args_string] != "void")
|
||||
args = function[:args].map do |m|
|
||||
(@arrays and m[:ptr?]) ? "#{m[:name]}, 1" : m[:name]
|
||||
end
|
||||
" CMockExpectParameters_#{function[:name]}(cmock_call_instance, #{args.join(', ')});\n"
|
||||
" CMockExpectParameters_#{function[:name]}(cmock_call_instance, #{args.join(', ')});\n"
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def ptr_or_str?(arg_type)
|
||||
return (arg_type.include? '*' or
|
||||
@treat_as.fetch(arg_type, "").include? '*')
|
||||
end
|
||||
|
||||
#private ######################
|
||||
|
||||
|
||||
def lookup_expect_type(function, arg)
|
||||
c_type = arg[:type]
|
||||
arg_name = arg[:name]
|
||||
@ -108,7 +110,7 @@ class CMockGeneratorUtils
|
||||
unity_msg = "Function '#{function[:name]}' called with unexpected value for argument '#{arg_name}'."
|
||||
return c_type, arg_name, expected, ignore, unity_func[0], unity_func[1], unity_msg
|
||||
end
|
||||
|
||||
|
||||
def code_verify_an_arg_expectation_with_no_arrays(function, arg)
|
||||
c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
|
||||
lines = ""
|
||||
@ -129,12 +131,12 @@ class CMockGeneratorUtils
|
||||
lines << " else\n"
|
||||
lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, 1, cmock_line, \"#{unity_msg}\"); }\n"
|
||||
else
|
||||
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
|
||||
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
|
||||
end
|
||||
lines << " }\n"
|
||||
lines
|
||||
end
|
||||
|
||||
|
||||
def code_verify_an_arg_expectation_with_normal_arrays(function, arg)
|
||||
c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
|
||||
depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
|
||||
@ -160,12 +162,12 @@ class CMockGeneratorUtils
|
||||
lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"
|
||||
end
|
||||
else
|
||||
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
|
||||
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
|
||||
end
|
||||
lines << " }\n"
|
||||
lines
|
||||
end
|
||||
|
||||
|
||||
def code_verify_an_arg_expectation_with_smart_arrays(function, arg)
|
||||
c_type, arg_name, expected, ignore, unity_func, pre, unity_msg = lookup_expect_type(function, arg)
|
||||
depth_name = (arg[:ptr?]) ? "cmock_call_instance->Expected_#{arg_name}_Depth" : 1
|
||||
@ -193,10 +195,10 @@ class CMockGeneratorUtils
|
||||
lines << " { #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, #{depth_name}, cmock_line, \"#{unity_msg}\"); }\n"
|
||||
end
|
||||
else
|
||||
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
|
||||
lines << " #{unity_func}(#{pre}#{expected}, #{pre}#{arg_name}, cmock_line, \"#{unity_msg}\");\n"
|
||||
end
|
||||
lines << " }\n"
|
||||
lines
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
@ -14,6 +14,10 @@
|
||||
|
||||
#define CMOCK_GUTS_NONE (0)
|
||||
|
||||
#define CMOCK_ARG_MODE CMOCK_MEM_INDEX_TYPE
|
||||
#define CMOCK_ARG_ALL 0
|
||||
#define CMOCK_ARG_NONE ((CMOCK_MEM_INDEX_TYPE)(~0))
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Memory API
|
||||
//-------------------------------------------------------
|
||||
|
54
targets/gcc_64.yml
Normal file
54
targets/gcc_64.yml
Normal file
@ -0,0 +1,54 @@
|
||||
---
|
||||
compiler:
|
||||
path: gcc
|
||||
source_path: &systest_generated_path 'test/system/generated/'
|
||||
unit_tests_path: &unit_tests_path 'examples/test/'
|
||||
mocks_path: &systest_mocks_path 'test/system/generated/'
|
||||
build_path: &systest_build_path 'test/system/build/'
|
||||
options:
|
||||
- '-c'
|
||||
- '-m64'
|
||||
- '-Wall'
|
||||
- '-Wunused-parameter'
|
||||
- '-Wno-address'
|
||||
- '-std=c99'
|
||||
- '-pedantic'
|
||||
includes:
|
||||
prefix: '-I'
|
||||
items:
|
||||
- *systest_generated_path
|
||||
- *unit_tests_path
|
||||
- *systest_mocks_path
|
||||
- 'src/'
|
||||
- 'vendor/unity/src/'
|
||||
- 'vendor/c_exception/lib/'
|
||||
- 'test/system/test_compilation/'
|
||||
- 'test/'
|
||||
defines:
|
||||
prefix: '-D'
|
||||
items:
|
||||
- 'UNITY_SUPPORT_64'
|
||||
object_files:
|
||||
prefix: '-o'
|
||||
extension: '.o'
|
||||
destination: *systest_build_path
|
||||
|
||||
linker:
|
||||
path: gcc
|
||||
options:
|
||||
- -lm
|
||||
- '-m64'
|
||||
includes:
|
||||
prefix: '-I'
|
||||
object_files:
|
||||
path: *systest_build_path
|
||||
extension: '.o'
|
||||
bin_files:
|
||||
prefix: '-o'
|
||||
extension: '.exe'
|
||||
destination: *systest_build_path
|
||||
|
||||
unsupported:
|
||||
- callingconv
|
||||
|
||||
colour: true
|
@ -3,12 +3,12 @@
|
||||
:cmock:
|
||||
:enforce_strict_ordering: 1
|
||||
:treat_externs: :include
|
||||
:ignore: :args_only
|
||||
:plugins:
|
||||
- :array
|
||||
- :cexception
|
||||
- :ignore
|
||||
- :callback
|
||||
- :expect_any_args
|
||||
|
||||
:systest:
|
||||
:types: |
|
||||
@ -28,9 +28,9 @@
|
||||
int mixed(int a, int* b, int c);
|
||||
void no_args(void);
|
||||
|
||||
:source:
|
||||
:header: |
|
||||
#include "CException.h"
|
||||
:source:
|
||||
:header: |
|
||||
#include "CException.h"
|
||||
void function_a(void);
|
||||
void function_b(void);
|
||||
void function_c(void);
|
||||
@ -38,40 +38,40 @@
|
||||
void function_e(void);
|
||||
|
||||
:code: |
|
||||
void function_a(void)
|
||||
void function_a(void)
|
||||
{
|
||||
foo(bar());
|
||||
}
|
||||
}
|
||||
|
||||
void function_b(void) {
|
||||
fooa(bar());
|
||||
}
|
||||
|
||||
|
||||
void function_c(void) {
|
||||
CEXCEPTION_T e;
|
||||
Try {
|
||||
foos(bars());
|
||||
} Catch(e) { foos("err"); }
|
||||
}
|
||||
|
||||
|
||||
int function_d(void) {
|
||||
int test_list[] = { 1, 2, 3, 4, 5 };
|
||||
no_pointers(1, "silly");
|
||||
return mixed(6, test_list, 7);
|
||||
}
|
||||
|
||||
|
||||
void function_e(void) {
|
||||
foos("Hello");
|
||||
foos("Tuna");
|
||||
foos("Oranges");
|
||||
}
|
||||
|
||||
|
||||
:tests:
|
||||
:common: |
|
||||
#include "CException.h"
|
||||
void setUp(void) {}
|
||||
void tearDown(void) {}
|
||||
|
||||
|
||||
:units:
|
||||
- :pass: TRUE
|
||||
:should: 'handle the situation where we pass nulls to pointers'
|
||||
@ -80,10 +80,10 @@
|
||||
{
|
||||
bar_ExpectAndReturn(NULL);
|
||||
foo_Expect(NULL);
|
||||
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we expected nulls to pointers but did not get that'
|
||||
:code: |
|
||||
@ -92,10 +92,10 @@
|
||||
POINT_T pt = {1, 2};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
foo_Expect(NULL);
|
||||
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we did not expect nulls to pointers but got null'
|
||||
:code: |
|
||||
@ -104,10 +104,10 @@
|
||||
POINT_T ex = {1, 2};
|
||||
bar_ExpectAndReturn(NULL);
|
||||
foo_Expect(&ex);
|
||||
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we pass single object with expect and it is wrong'
|
||||
:code: |
|
||||
@ -117,10 +117,10 @@
|
||||
POINT_T ex = {1, 3};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
foo_Expect(&ex);
|
||||
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle the situation where we pass single object with expect and use array handler'
|
||||
:code: |
|
||||
@ -130,10 +130,10 @@
|
||||
POINT_T ex = {1, 2};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
foo_ExpectWithArray(&ex, 1);
|
||||
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we pass single object with expect and use array handler and it is wrong'
|
||||
:code: |
|
||||
@ -143,10 +143,10 @@
|
||||
POINT_T ex = {1, 3};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
foo_ExpectWithArray(&ex, 1);
|
||||
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'handle the situation where we pass multiple objects with expect and use array handler'
|
||||
:code: |
|
||||
@ -156,10 +156,10 @@
|
||||
POINT_T ex[] = {{1, 2}, {3, 4}, {5, 6}};
|
||||
bar_ExpectAndReturn(pt);
|
||||
foo_ExpectWithArray(ex, 3);
|
||||
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle the situation where we pass multiple objects with expect and use array handler and it is wrong at end'
|
||||
:code: |
|
||||
@ -169,7 +169,7 @@
|
||||
POINT_T ex[] = {{1, 2}, {3, 4}, {5, 9}};
|
||||
bar_ExpectAndReturn(pt);
|
||||
foo_ExpectWithArray(ex, 3);
|
||||
|
||||
|
||||
function_a();
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@
|
||||
POINT_T ex = {1, 2};
|
||||
bar_ExpectAndReturn(&pt);
|
||||
fooa_Expect(&ex);
|
||||
|
||||
|
||||
function_b();
|
||||
}
|
||||
|
||||
@ -193,10 +193,10 @@
|
||||
{
|
||||
bars_ExpectAndReturn("This is a\0 silly string");
|
||||
foos_Expect("This is a\0 wacky string");
|
||||
|
||||
|
||||
function_c();
|
||||
}
|
||||
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'handle standard c string as null terminated and not do crappy memory compares of a byte, finding failures'
|
||||
:code: |
|
||||
@ -204,7 +204,7 @@
|
||||
{
|
||||
bars_ExpectAndReturn("This is a silly string");
|
||||
foos_Expect("This is a wacky string");
|
||||
|
||||
|
||||
function_c();
|
||||
}
|
||||
|
||||
@ -216,7 +216,7 @@
|
||||
int expect_list[] = { 1, 9 };
|
||||
no_pointers_Expect(1, "silly");
|
||||
mixed_ExpectAndReturn(6, expect_list, 7, 13);
|
||||
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_d());
|
||||
}
|
||||
|
||||
@ -228,7 +228,7 @@
|
||||
int expect_list[] = { 9, 1 };
|
||||
no_pointers_Expect(1, "silly");
|
||||
mixed_ExpectAndReturn(6, expect_list, 7, 13);
|
||||
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_d());
|
||||
}
|
||||
|
||||
@ -240,7 +240,7 @@
|
||||
int expect_list[] = { 1, 2, 3, 4, 6 };
|
||||
no_pointers_Expect(1, "silly");
|
||||
mixed_ExpectWithArrayAndReturn(6, expect_list, 4, 7, 13);
|
||||
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_d());
|
||||
}
|
||||
|
||||
@ -252,7 +252,7 @@
|
||||
int expect_list[] = { 1, 2, 3, 4, 6 };
|
||||
no_pointers_Expect(1, "silly");
|
||||
mixed_ExpectWithArrayAndReturn(6, expect_list, 5, 7, 13);
|
||||
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_d());
|
||||
}
|
||||
|
||||
@ -264,7 +264,7 @@
|
||||
bars_ExpectAndReturn("This is a\0 silly string");
|
||||
foos_ExpectAndThrow("This is a\0 wacky string", 55);
|
||||
foos_Expect("err");
|
||||
|
||||
|
||||
function_c();
|
||||
}
|
||||
|
||||
@ -276,7 +276,7 @@
|
||||
bars_ExpectAndReturn("This is a\0 silly string");
|
||||
foos_ExpectAndThrow("This is a\0 wacky string", 55);
|
||||
foos_Expect("wrong error");
|
||||
|
||||
|
||||
function_c();
|
||||
}
|
||||
|
||||
@ -288,53 +288,53 @@
|
||||
int expect_list[] = { 1, 2, 3, 4, 6 };
|
||||
mixed_ExpectWithArrayAndReturn(6, expect_list, 4, 7, 13);
|
||||
no_pointers_Expect(1, "silly");
|
||||
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_d());
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'properly ignore first function but the other will work properly'
|
||||
:should: 'properly ExpectAnyArgs first function but the other will work properly'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
int expect_list[] = { 1, 2, 3, 4, 6 };
|
||||
no_pointers_Ignore();
|
||||
no_pointers_ExpectAnyArgs();
|
||||
mixed_ExpectWithArrayAndReturn(6, expect_list, 4, 7, 13);
|
||||
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_d());
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'properly ignore last function but the other will work properly'
|
||||
:should: 'properly ExpectAnyArgs last function but the other will work properly'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
no_pointers_Expect(1, "silly");
|
||||
mixed_IgnoreAndReturn(13);
|
||||
|
||||
mixed_ExpectAnyArgsAndReturn(13);
|
||||
|
||||
TEST_ASSERT_EQUAL(13, function_d());
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'be ok if we ignore a call each because we are counting calls'
|
||||
:should: 'be ok if we ExpectAnyArgs a call each because we are counting calls'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
foos_Ignore();
|
||||
foos_Ignore();
|
||||
foos_Ignore();
|
||||
|
||||
foos_ExpectAnyArgs();
|
||||
foos_ExpectAnyArgs();
|
||||
foos_ExpectAnyArgs();
|
||||
|
||||
function_e();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'fail if we do not ignore a call once because we are counting calls'
|
||||
:should: 'fail if we do not ExpectAnyArgs a call once because we are counting calls'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
foos_Ignore();
|
||||
foos_Ignore();
|
||||
|
||||
foos_ExpectAnyArgs();
|
||||
foos_ExpectAnyArgs();
|
||||
|
||||
function_e();
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
---
|
||||
:cmock:
|
||||
:plugins:
|
||||
- 'ignore'
|
||||
:ignore: :args_only
|
||||
- 'expect_any_args'
|
||||
|
||||
:systest:
|
||||
:types: |
|
||||
@ -14,12 +13,17 @@
|
||||
:source:
|
||||
:header: |
|
||||
int function(int a, int b, int c);
|
||||
void func_b(int a);
|
||||
:code: |
|
||||
int function(int a, int b, int c)
|
||||
{
|
||||
bar(b);
|
||||
return foo(a) + foo(b) + foo(c);
|
||||
}
|
||||
void func_b(int a)
|
||||
{
|
||||
bar(a);
|
||||
}
|
||||
|
||||
:tests:
|
||||
:common: |
|
||||
@ -39,50 +43,50 @@
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'ignore foo() calls'
|
||||
:should: 'ignore foo() call details'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Expect(4);
|
||||
foo_IgnoreAndReturn(10);
|
||||
foo_IgnoreAndReturn(40);
|
||||
foo_IgnoreAndReturn(80);
|
||||
foo_ExpectAnyArgsAndReturn(10);
|
||||
foo_ExpectAnyArgsAndReturn(40);
|
||||
foo_ExpectAnyArgsAndReturn(80);
|
||||
TEST_ASSERT_EQUAL(130, function(3, 4, 3));
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'ignore foo() calls and notice if we called foo() more times than expected'
|
||||
:should: 'ignore foo() call details and notice if we called foo() more times than expected'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Expect(4);
|
||||
foo_IgnoreAndReturn(20);
|
||||
foo_IgnoreAndReturn(30);
|
||||
foo_ExpectAnyArgsAndReturn(20);
|
||||
foo_ExpectAnyArgsAndReturn(30);
|
||||
TEST_ASSERT_EQUAL(50, function(3, 4, 9));
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'ignore foo() calls and notice if we called foo() less times than expected'
|
||||
:should: 'ignore foo() call details and notice if we called foo() less times than expected'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Expect(4);
|
||||
foo_IgnoreAndReturn(20);
|
||||
foo_IgnoreAndReturn(10);
|
||||
foo_IgnoreAndReturn(50);
|
||||
foo_IgnoreAndReturn(60);
|
||||
foo_ExpectAnyArgsAndReturn(20);
|
||||
foo_ExpectAnyArgsAndReturn(10);
|
||||
foo_ExpectAnyArgsAndReturn(50);
|
||||
foo_ExpectAnyArgsAndReturn(60);
|
||||
TEST_ASSERT_EQUAL(70, function(3, 4, 9));
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'ignore bar() and foo() calls'
|
||||
:should: 'ignore bar() and foo() call details'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
foo_IgnoreAndReturn(50);
|
||||
foo_IgnoreAndReturn(50);
|
||||
foo_IgnoreAndReturn(50);
|
||||
bar_ExpectAnyArgs();
|
||||
foo_ExpectAnyArgsAndReturn(50);
|
||||
foo_ExpectAnyArgsAndReturn(50);
|
||||
foo_ExpectAnyArgsAndReturn(50);
|
||||
TEST_ASSERT_EQUAL(150, function(0, 0, 0));
|
||||
}
|
||||
|
||||
@ -91,9 +95,9 @@
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
foo_IgnoreAndReturn(50);
|
||||
foo_IgnoreAndReturn(50);
|
||||
bar_ExpectAnyArgs();
|
||||
foo_ExpectAnyArgsAndReturn(50);
|
||||
foo_ExpectAnyArgsAndReturn(50);
|
||||
foo_ExpectAndReturn(3, 50);
|
||||
TEST_ASSERT_EQUAL(150, function(1, 2, 3));
|
||||
}
|
||||
@ -103,10 +107,10 @@
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
bar_ExpectAnyArgs();
|
||||
foo_ExpectAndReturn(1, 50);
|
||||
foo_IgnoreAndReturn(50);
|
||||
foo_IgnoreAndReturn(50);
|
||||
foo_ExpectAnyArgsAndReturn(50);
|
||||
foo_ExpectAnyArgsAndReturn(50);
|
||||
TEST_ASSERT_EQUAL(150, function(1, 2, 3));
|
||||
}
|
||||
|
||||
@ -115,52 +119,76 @@
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
bar_ExpectAnyArgs();
|
||||
foo_ExpectAndReturn(1, 50);
|
||||
foo_IgnoreAndReturn(50);
|
||||
foo_ExpectAnyArgsAndReturn(50);
|
||||
foo_ExpectAndReturn(3, 50);
|
||||
TEST_ASSERT_EQUAL(150, function(1, 2, 3));
|
||||
}
|
||||
|
||||
# TODO: THIS IS WHAT PEOPLE EXPECT, BUT IS NOT BEING MET YET.
|
||||
- :pass: FALSE
|
||||
:should: 'be able to detect problems with an expect even when using ignores'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
bar_ExpectAnyArgs();
|
||||
foo_ExpectAndReturn(1, 50);
|
||||
foo_IgnoreAndReturn(50);
|
||||
foo_ExpectAnyArgsAndReturn(50);
|
||||
foo_ExpectAndReturn(4, 50);
|
||||
TEST_ASSERT_EQUAL(150, function(1, 2, 3));
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'be able to handle a lone ExpectAnyArg call'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_ExpectAnyArgs();
|
||||
func_b(1);
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'be able to handle a lone ExpectAnyArg call that does not get called'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_ExpectAnyArgs();
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'be able to handle a missing ExpectAnyArg call'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
func_b(1);
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'ignore foo() calls over multiple mock calls'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
foo_IgnoreAndReturn(50);
|
||||
foo_IgnoreAndReturn(60);
|
||||
foo_IgnoreAndReturn(70);
|
||||
bar_ExpectAnyArgs();
|
||||
foo_ExpectAnyArgsAndReturn(50);
|
||||
foo_ExpectAnyArgsAndReturn(60);
|
||||
foo_ExpectAnyArgsAndReturn(70);
|
||||
TEST_ASSERT_EQUAL(180, function(0, 0, 0));
|
||||
|
||||
bar_Ignore();
|
||||
foo_IgnoreAndReturn(30);
|
||||
foo_IgnoreAndReturn(80);
|
||||
foo_IgnoreAndReturn(10);
|
||||
bar_ExpectAnyArgs();
|
||||
foo_ExpectAnyArgsAndReturn(30);
|
||||
foo_ExpectAnyArgsAndReturn(80);
|
||||
foo_ExpectAnyArgsAndReturn(10);
|
||||
TEST_ASSERT_EQUAL(120, function(0, 0, 0));
|
||||
|
||||
bar_Ignore();
|
||||
foo_IgnoreAndReturn(70);
|
||||
foo_IgnoreAndReturn(20);
|
||||
foo_IgnoreAndReturn(20);
|
||||
bar_ExpectAnyArgs();
|
||||
foo_ExpectAnyArgsAndReturn(70);
|
||||
foo_ExpectAnyArgsAndReturn(20);
|
||||
foo_ExpectAnyArgsAndReturn(20);
|
||||
TEST_ASSERT_EQUAL(110, function(0, 0, 0));
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'multiple cycles of expects still pass when ignores enabled'
|
||||
:should: 'have multiple cycles of expects still pass when this plugin enabled'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
@ -184,7 +212,7 @@
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'multiple cycles of expects still fail when ignores enabled'
|
||||
:should: 'have multiple cycles of expects still fail when this plugin enabled'
|
||||
:code: |
|
||||
test()
|
||||
{
|
Loading…
x
Reference in New Issue
Block a user