mirror of
https://github.com/ThrowTheSwitch/CMock.git
synced 2026-06-23 14:00:33 +00:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3eccb8e3d4 | |||
| 1f939c9005 | |||
| 9e1c6c068d | |||
| 4ae268dbbe | |||
| d847e6777c | |||
| dcde998087 | |||
| 38d6dccc8e | |||
| 03acc531bf | |||
| 45920ed724 | |||
| c4842fad0c | |||
| 9f3cee70cd | |||
| 4dd557f2df | |||
| af1818a652 | |||
| e352bb8c3b | |||
| 63f5e2f962 | |||
| 5eec2510b1 | |||
| f5984f44e8 | |||
| 9c1c6a05dc | |||
| 70d5750659 | |||
| 72f1c9e2b8 | |||
| 334f46781a | |||
| ea061bbb50 | |||
| 21d181380f | |||
| 72b356b97d | |||
| 22a7228bbc | |||
| afa294982e | |||
| 44f126878b | |||
| 1987138e81 | |||
| baa946a05f | |||
| d304ff273a | |||
| 56faeb935f | |||
| 61ed5cc7f8 | |||
| 496cabff10 | |||
| 94ca645061 | |||
| d36662da2a | |||
| b735d09603 | |||
| 5f8ec6da7f | |||
| 3e28a5412d | |||
| 5f8e90b82a | |||
| 541e7034ad | |||
| eeecc49ce8 | |||
| 175a834574 | |||
| ec6fa2c516 | |||
| 7ee27d6891 | |||
| 2568a3657f |
@@ -0,0 +1,41 @@
|
||||
---
|
||||
# Continuous Integration Workflow: Test case suite run + validation build check
|
||||
name: CI
|
||||
|
||||
# Controls when the action will run.
|
||||
# Triggers the workflow on push or pull request events but only for the master branch
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
# Job: Unit test suite
|
||||
unit-tests:
|
||||
name: "Unit Tests"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Install Multilib
|
||||
- name: Install Multilib
|
||||
run: |
|
||||
sudo apt-get install --assume-yes --quiet gcc-multilib
|
||||
|
||||
# Checks out repository under $GITHUB_WORKSPACE
|
||||
- name: Checkout Latest Repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
# Install Ruby Testing Tools
|
||||
- name: Setup Ruby Testing Tools
|
||||
run: |
|
||||
sudo gem install bundler
|
||||
sudo gem install rspec
|
||||
sudo gem install rubocop -v 0.57.2
|
||||
bundle install
|
||||
|
||||
# Run Tests
|
||||
- name: Run All Unit Tests
|
||||
run: |
|
||||
cd test && rake ci
|
||||
@@ -1,6 +1,7 @@
|
||||
test/system/build
|
||||
test/system/generated
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
Gemfile.lock
|
||||
.rake_t_cache
|
||||
.DS_Store
|
||||
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
sudo: required
|
||||
language: ruby c
|
||||
|
||||
matrix:
|
||||
include:
|
||||
#- os: osx
|
||||
# compiler: clang
|
||||
# osx_image: xcode7.3
|
||||
- os: linux
|
||||
dist: trusty
|
||||
rvm: "2.4"
|
||||
compiler: gcc
|
||||
- os: linux
|
||||
dist: xenial
|
||||
rvm: "2.7"
|
||||
compiler: clang
|
||||
|
||||
before_install:
|
||||
- sudo apt-get install --assume-yes --quiet gcc-multilib
|
||||
|
||||
install:
|
||||
- gem install bundler
|
||||
- bundle install
|
||||
- gem install rspec
|
||||
- gem install rubocop -v 0.57.2
|
||||
|
||||
script:
|
||||
- cd test && rake ci
|
||||
@@ -1,7 +1,12 @@
|
||||
CMock - Mock/stub generator for C
|
||||
=================================
|
||||
CMock 
|
||||
=====
|
||||
CMock is a mock and stub generator and runtime for unit testing C. It's been designed
|
||||
to work smoothly with Unity Test, another of the embedded-software testing tools
|
||||
developed by ThrowTheSwitch.org. CMock automagically parses your C headers and creates
|
||||
useful and usable mock interfaces for unit testing. Give it a try!
|
||||
|
||||
[](https://travis-ci.org/ThrowTheSwitch/CMock)
|
||||
If you don't care to manage unit testing builds yourself, consider checking out Ceedling,
|
||||
a test-centered build manager for unit testing C code.
|
||||
|
||||
Getting Started
|
||||
================
|
||||
|
||||
+19
-1
@@ -174,6 +174,23 @@ handle the call to a function.
|
||||
* `retval func(void)` => `void func_StopIgnore(void)`
|
||||
* `retval func(params)` => `void func_StopIgnore(void)`
|
||||
|
||||
IgnoreStateless:
|
||||
----------------
|
||||
|
||||
This plugin is similar to the Ignore plugin, but the IgnoreAndReturn functions are
|
||||
stateless. So the Ignored function will always return the last specified return value
|
||||
and does not queue the return values as the IgnoreAndReturn of the default plugin will.
|
||||
|
||||
To stop ignoring a function you can call StopIgnore or simply overwrite the Ignore
|
||||
(resp. IgnoreAndReturn) with an Expect (resp. ExpectAndReturn). Note that calling
|
||||
Ignore (resp IgnoreAndReturn) will clear your previous called Expect
|
||||
(resp. ExpectAndReturn), so they are not restored after StopIgnore is called.
|
||||
|
||||
You can use this plugin by using `:ignore_stateless` instead of `:ignore` in your
|
||||
CMock configuration file.
|
||||
|
||||
The generated functions are the same as **Ignore** and **StopIgnore** above.
|
||||
|
||||
Ignore Arg:
|
||||
------------
|
||||
|
||||
@@ -440,6 +457,7 @@ from the defaults. We've tried to specify what the defaults are below.
|
||||
available currently:
|
||||
|
||||
* `:ignore`
|
||||
* `:ignore_stateless`
|
||||
* `:ignore_arg`
|
||||
* `:expect_any_args`
|
||||
* `:array`
|
||||
@@ -457,7 +475,7 @@ from the defaults. We've tried to specify what the defaults are below.
|
||||
to prevent a function `functionName` from being mocked. By default, it
|
||||
is ignoring all gcc attribute extensions.
|
||||
|
||||
* default: ['(?:__attribute__\s*\(+.*?\)+)']
|
||||
* default: `['(?:__attribute__\s*\(+.*?\)+)']`
|
||||
|
||||
* `:subdir`:
|
||||
This is a relative subdirectory for your mocks. Set this to e.g. "sys" in
|
||||
|
||||
+16
-9
@@ -18,16 +18,18 @@ class CMock
|
||||
cm_config = CMockConfig.new(options)
|
||||
cm_unityhelper = CMockUnityHelperParser.new(cm_config)
|
||||
cm_writer = CMockFileWriter.new(cm_config)
|
||||
cm_gen_utils = CMockGeneratorUtils.new(cm_config, :unity_helper => cm_unityhelper)
|
||||
cm_gen_utils = CMockGeneratorUtils.new(cm_config,
|
||||
:unity_helper => cm_unityhelper)
|
||||
cm_gen_plugins = CMockPluginManager.new(cm_config, cm_gen_utils)
|
||||
@cm_parser = CMockHeaderParser.new(cm_config)
|
||||
@cm_generator = CMockGenerator.new(cm_config, cm_writer, cm_gen_utils, cm_gen_plugins)
|
||||
@cm_generator = CMockGenerator.new(cm_config, cm_writer, cm_gen_utils,
|
||||
cm_gen_plugins)
|
||||
@silent = (cm_config.verbosity < 2)
|
||||
end
|
||||
|
||||
def setup_mocks(files)
|
||||
def setup_mocks(files, folder = nil)
|
||||
[files].flatten.each do |src|
|
||||
generate_mock src
|
||||
generate_mock(src, folder)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -39,11 +41,11 @@ class CMock
|
||||
|
||||
private ###############################
|
||||
|
||||
def generate_mock(src)
|
||||
def generate_mock(src, folder)
|
||||
name = File.basename(src, '.*')
|
||||
ext = File.extname(src)
|
||||
puts "Creating mock for #{name}..." unless @silent
|
||||
@cm_generator.create_mock(name, @cm_parser.parse(name, File.read(src)), ext)
|
||||
@cm_generator.create_mock(name, @cm_parser.parse(name, File.read(src)), ext, folder)
|
||||
end
|
||||
|
||||
def generate_skeleton(src)
|
||||
@@ -85,12 +87,17 @@ if $0 == __FILE__
|
||||
options = {}
|
||||
filelist = []
|
||||
ARGV.each do |arg|
|
||||
if arg =~ /^-o\"?([a-zA-Z0-9._\\\/:\s]+)\"?/
|
||||
if arg =~ /^-o\"?([a-zA-Z0-9@._\\\/:\s]+)\"?/
|
||||
options.merge! CMockConfig.load_config_file_from_yaml(arg.gsub(/^-o/, ''))
|
||||
elsif arg == '--skeleton'
|
||||
options[:skeleton] = true
|
||||
elsif arg =~ /^--([a-zA-Z0-9._\\\/:\s]+)=\"?([a-zA-Z0-9._\-\\\/:\s\;]+)\"?/
|
||||
options = option_maker(options, Regexp.last_match(1), Regexp.last_match(2))
|
||||
elsif arg =~ /^--strippables=\"?(.*)\"?/
|
||||
# --strippables are dealt with separately since the user is allowed to
|
||||
# enter any valid regular expression as argument
|
||||
options = option_maker(options, 'strippables', Regexp.last_match(1))
|
||||
elsif arg =~ /^--([a-zA-Z0-9._\\\/:\s]+)=\"?([a-zA-Z0-9._\-\\\/:\s\;]*)\"?/x
|
||||
options = option_maker(options, Regexp.last_match(1),
|
||||
Regexp.last_match(2))
|
||||
else
|
||||
filelist << arg
|
||||
end
|
||||
|
||||
+20
-7
@@ -21,6 +21,7 @@ class CMockGenerator
|
||||
@fail_on_unexpected_calls = @config.fail_on_unexpected_calls
|
||||
|
||||
@subdir = @config.subdir
|
||||
@folder = nil
|
||||
|
||||
@includes_h_pre_orig_header = (@config.includes || @config.includes_h_pre_orig_header || []).map { |h| h =~ /</ ? h : "\"#{h}\"" }
|
||||
@includes_h_post_orig_header = (@config.includes_h_post_orig_header || []).map { |h| h =~ /</ ? h : "\"#{h}\"" }
|
||||
@@ -44,12 +45,24 @@ class CMockGenerator
|
||||
end
|
||||
end
|
||||
|
||||
def create_mock(module_name, parsed_stuff, module_ext = nil)
|
||||
def create_mock(module_name, parsed_stuff, module_ext = nil, folder = nil)
|
||||
@module_name = module_name
|
||||
@module_ext = module_ext || '.h'
|
||||
@mock_name = @prefix + @module_name + @suffix
|
||||
@clean_mock_name = TypeSanitizer.sanitize_c_identifier(@mock_name)
|
||||
|
||||
@folder = if folder && @subdir
|
||||
File.join(@subdir, folder)
|
||||
elsif @subdir
|
||||
@subdir
|
||||
else
|
||||
folder
|
||||
end
|
||||
# adds a trailing slash to the folder output
|
||||
@folder = File.join(@folder, '') if @folder
|
||||
|
||||
create_mock_subdir
|
||||
|
||||
create_mock_header_file(parsed_stuff)
|
||||
create_mock_source_file(parsed_stuff)
|
||||
end
|
||||
@@ -62,7 +75,7 @@ class CMockGenerator
|
||||
private if $ThisIsOnlyATest.nil? ##############################
|
||||
|
||||
def create_mock_subdir
|
||||
@file_writer.create_subdir(@subdir)
|
||||
@file_writer.create_subdir(@folder)
|
||||
end
|
||||
|
||||
def create_using_statement(file, function)
|
||||
@@ -71,12 +84,12 @@ class CMockGenerator
|
||||
|
||||
def create_mock_header_file(parsed_stuff)
|
||||
if @include_inline == :include
|
||||
@file_writer.create_file(@module_name + (@module_ext || '.h'), @subdir) do |file, _filename|
|
||||
@file_writer.create_file(@module_name + (@module_ext || '.h'), @folder) do |file, _filename|
|
||||
file << parsed_stuff[:normalized_source]
|
||||
end
|
||||
end
|
||||
|
||||
@file_writer.create_file(@mock_name + (@module_ext || '.h'), @subdir) do |file, filename|
|
||||
@file_writer.create_file(@mock_name + (@module_ext || '.h'), @folder) do |file, filename|
|
||||
create_mock_header_header(file, filename)
|
||||
create_mock_header_service_call_declarations(file)
|
||||
create_typedefs(file, parsed_stuff[:typedefs])
|
||||
@@ -89,7 +102,7 @@ class CMockGenerator
|
||||
end
|
||||
|
||||
def create_mock_source_file(parsed_stuff)
|
||||
@file_writer.create_file(@mock_name + '.c', @subdir) do |file, filename|
|
||||
@file_writer.create_file(@mock_name + '.c', @folder) do |file, filename|
|
||||
create_source_header_section(file, filename, parsed_stuff[:functions])
|
||||
create_instance_structure(file, parsed_stuff[:functions])
|
||||
create_extern_declarations(file)
|
||||
@@ -116,7 +129,7 @@ class CMockGenerator
|
||||
|
||||
def create_mock_header_header(file, _filename)
|
||||
define_name = @clean_mock_name.upcase
|
||||
orig_filename = (@subdir ? @subdir + '/' : '') + @module_name + (@module_ext || '.h')
|
||||
orig_filename = (@folder || '') + @module_name + (@module_ext || '.h')
|
||||
file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n"
|
||||
file << "#ifndef _#{define_name}_H\n"
|
||||
file << "#define _#{define_name}_H\n\n"
|
||||
@@ -165,7 +178,7 @@ class CMockGenerator
|
||||
end
|
||||
|
||||
def create_source_header_section(file, filename, functions)
|
||||
header_file = (@subdir ? @subdir + '/' : '') + filename.gsub('.c', (@module_ext || '.h'))
|
||||
header_file = (@folder || '') + filename.gsub('.c', (@module_ext || '.h'))
|
||||
file << "/* AUTOGENERATED FILE. DO NOT EDIT. */\n" unless functions.empty?
|
||||
file << "#include <string.h>\n"
|
||||
file << "#include <stdlib.h>\n"
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
# ==========================================
|
||||
# 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 CMockGeneratorPluginIgnoreStateless
|
||||
attr_reader :priority
|
||||
attr_reader :config, :utils
|
||||
|
||||
def initialize(config, utils)
|
||||
@config = config
|
||||
@utils = utils
|
||||
@priority = 2
|
||||
end
|
||||
|
||||
def instance_structure(function)
|
||||
if function[:return][:void?]
|
||||
" char #{function[:name]}_IgnoreBool;\n"
|
||||
else
|
||||
" char #{function[:name]}_IgnoreBool;\n #{function[:return][:type]} #{function[:name]}_FinalReturn;\n"
|
||||
end
|
||||
end
|
||||
|
||||
def mock_function_declarations(function)
|
||||
lines = if function[:return][:void?]
|
||||
"#define #{function[:name]}_Ignore() #{function[:name]}_CMockIgnore()\n" \
|
||||
"void #{function[:name]}_CMockIgnore(void);\n"
|
||||
else
|
||||
"#define #{function[:name]}_IgnoreAndReturn(cmock_retval) #{function[:name]}_CMockIgnoreAndReturn(cmock_retval)\n" \
|
||||
"void #{function[:name]}_CMockIgnoreAndReturn(#{function[:return][:str]});\n"
|
||||
end
|
||||
|
||||
# Add stop ignore function. it does not matter if there are any args
|
||||
lines << "#define #{function[:name]}_StopIgnore() #{function[:name]}_CMockStopIgnore()\n" \
|
||||
"void #{function[:name]}_CMockStopIgnore(void);\n"
|
||||
lines
|
||||
end
|
||||
|
||||
def mock_implementation_precheck(function)
|
||||
lines = " if (Mock.#{function[:name]}_IgnoreBool)\n {\n"
|
||||
lines << " UNITY_CLR_DETAILS();\n"
|
||||
if function[:return][:void?]
|
||||
lines << " return;\n }\n"
|
||||
else
|
||||
retval = function[:return].merge(:name => 'cmock_call_instance->ReturnVal')
|
||||
lines << " if (cmock_call_instance == NULL)\n return Mock.#{function[:name]}_FinalReturn;\n"
|
||||
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
|
||||
|
||||
# this function is adjusted
|
||||
def mock_interfaces(function)
|
||||
lines = ''
|
||||
lines << if function[:return][:void?]
|
||||
"void #{function[:name]}_CMockIgnore(void)\n{\n"
|
||||
else
|
||||
"void #{function[:name]}_CMockIgnoreAndReturn(#{function[:return][:str]})\n{\n"
|
||||
end
|
||||
unless function[:return][:void?]
|
||||
lines << " Mock.#{function[:name]}_CallInstance = CMOCK_GUTS_NONE;\n"
|
||||
lines << " Mock.#{function[:name]}_FinalReturn = cmock_to_return;\n"
|
||||
end
|
||||
lines << " Mock.#{function[:name]}_IgnoreBool = (char)1;\n"
|
||||
lines << "}\n\n"
|
||||
|
||||
# Add stop ignore function. it does not matter if there are any args
|
||||
lines << "void #{function[:name]}_CMockStopIgnore(void)\n{\n"
|
||||
lines << " Mock.#{function[:name]}_IgnoreBool = (char)0;\n"
|
||||
lines << "}\n\n"
|
||||
|
||||
lines
|
||||
end
|
||||
|
||||
def mock_ignore(function)
|
||||
" Mock.#{function[:name]}_IgnoreBool = (char)1;\n"
|
||||
end
|
||||
|
||||
def mock_verify(function)
|
||||
func_name = function[:name]
|
||||
" if (Mock.#{func_name}_IgnoreBool)\n call_instance = CMOCK_GUTS_NONE;\n"
|
||||
end
|
||||
end
|
||||
@@ -14,7 +14,7 @@ class CMockGeneratorPluginReturnThruPtr
|
||||
|
||||
lines << " char ReturnThruPtr_#{arg[:name]}_Used;\n"
|
||||
lines << " #{arg[:type]} ReturnThruPtr_#{arg[:name]}_Val;\n"
|
||||
lines << " int ReturnThruPtr_#{arg[:name]}_Size;\n"
|
||||
lines << " size_t ReturnThruPtr_#{arg[:name]}_Size;\n"
|
||||
end
|
||||
lines
|
||||
end
|
||||
@@ -33,10 +33,10 @@ class CMockGeneratorPluginReturnThruPtr
|
||||
" #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, sizeof(*#{arg[:name]}))\n"
|
||||
end
|
||||
lines << "#define #{function[:name]}_ReturnArrayThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_len)"
|
||||
lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, (int)(cmock_len * (int)sizeof(*#{arg[:name]})))\n"
|
||||
lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, cmock_len * sizeof(*#{arg[:name]}))\n"
|
||||
lines << "#define #{function[:name]}_ReturnMemThruPtr_#{arg[:name]}(#{arg[:name]}, cmock_size)"
|
||||
lines << " #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(__LINE__, #{arg[:name]}, cmock_size)\n"
|
||||
lines << "void #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg[:name]}, int cmock_size);\n"
|
||||
lines << "void #{function[:name]}_CMockReturnMemThruPtr_#{arg[:name]}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg[:name]}, size_t cmock_size);\n"
|
||||
end
|
||||
lines
|
||||
end
|
||||
@@ -48,7 +48,7 @@ class CMockGeneratorPluginReturnThruPtr
|
||||
arg_name = arg[:name]
|
||||
next unless @utils.ptr_or_str?(arg[:type]) && !(arg[:const?])
|
||||
|
||||
lines << "void #{func_name}_CMockReturnMemThruPtr_#{arg_name}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg_name}, int cmock_size)\n"
|
||||
lines << "void #{func_name}_CMockReturnMemThruPtr_#{arg_name}(UNITY_LINE_TYPE cmock_line, #{arg[:type]} #{arg_name}, size_t cmock_size)\n"
|
||||
lines << "{\n"
|
||||
lines << " CMOCK_#{func_name}_CALL_INSTANCE* cmock_call_instance = " \
|
||||
"(CMOCK_#{func_name}_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.#{func_name}_CallInstance));\n"
|
||||
|
||||
@@ -17,6 +17,7 @@ class CMockGeneratorUtils
|
||||
@return_thru_ptr = @config.plugins.include? :return_thru_ptr
|
||||
@ignore_arg = @config.plugins.include? :ignore_arg
|
||||
@ignore = @config.plugins.include? :ignore
|
||||
@ignore_stateless = @config.plugins.include? :ignore_stateless
|
||||
@treat_as = @config.treat_as
|
||||
@helpers = helpers
|
||||
end
|
||||
@@ -52,7 +53,7 @@ class CMockGeneratorUtils
|
||||
lines << " UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory);\n"
|
||||
lines << " memset(cmock_call_instance, 0, sizeof(*cmock_call_instance));\n"
|
||||
lines << " Mock.#{func_name}_CallInstance = CMock_Guts_MemChain(Mock.#{func_name}_CallInstance, cmock_guts_index);\n"
|
||||
lines << " Mock.#{func_name}_IgnoreBool = (char)0;\n" if @ignore
|
||||
lines << " Mock.#{func_name}_IgnoreBool = (char)0;\n" if @ignore || @ignore_stateless
|
||||
lines << " cmock_call_instance->LineNumber = cmock_line;\n"
|
||||
lines << " cmock_call_instance->CallOrder = ++GlobalExpectCount;\n" if @ordered && global_ordering_supported
|
||||
lines << " cmock_call_instance->ExceptionToThrow = CEXCEPTION_NONE;\n" if @cexception
|
||||
@@ -86,11 +87,13 @@ class CMockGeneratorUtils
|
||||
type = arg_type_with_const(m)
|
||||
m[:ptr?] ? "#{type} #{m[:name]}, int #{m[:name]}_Depth" : "#{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" \
|
||||
"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" \
|
||||
"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
|
||||
|
||||
+40
-14
@@ -61,6 +61,15 @@ class CMockHeaderParser
|
||||
|
||||
private if $ThisIsOnlyATest.nil? ################
|
||||
|
||||
# Remove C/C++ comments from a string
|
||||
# +source+:: String which will have the comments removed
|
||||
def remove_comments_from_source(source)
|
||||
# remove comments (block and line, in three steps to ensure correct precedence)
|
||||
source.gsub!(/(?<!\*)\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks
|
||||
source.gsub!(/\/\*.*?\*\//m, '') # remove block comments
|
||||
source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain)
|
||||
end
|
||||
|
||||
def remove_nested_pairs_of_braces(source)
|
||||
# remove nested pairs of braces because no function declarations will be inside of them (leave outer pair for function definition detection)
|
||||
if RUBY_VERSION.split('.')[0].to_i > 1
|
||||
@@ -119,6 +128,9 @@ class CMockHeaderParser
|
||||
# let's clean up the encoding in case they've done anything weird with the characters we might find
|
||||
source = source.force_encoding('ISO-8859-1').encode('utf-8', :replace => nil)
|
||||
|
||||
# Comments can contain words that will trigger the parser (static|inline|<user_defined_static_keyword>)
|
||||
remove_comments_from_source(source)
|
||||
|
||||
# smush multiline macros into single line (checking for continuation character at end of line '\')
|
||||
# If the user uses a macro to declare an inline function,
|
||||
# smushing the macros makes it easier to recognize them as a macro and if required,
|
||||
@@ -138,11 +150,18 @@ class CMockHeaderParser
|
||||
# - Copy everything after the inline function implementation and start the parsing of the next inline function
|
||||
# There are ofcourse some special cases (inline macro declarations, inline function declarations, ...) which are handled and explained below
|
||||
inline_function_regex_formats.each do |format|
|
||||
inspected_source = ''
|
||||
regex_matched = false
|
||||
loop do
|
||||
inline_function_match = source.match(/#{format}/) # Search for inline function declaration
|
||||
|
||||
break if inline_function_match.nil? # No inline functions so nothing to do
|
||||
if inline_function_match.nil? # No inline functions so nothing to do
|
||||
# Join pre and post match stripped parts for the next inline function detection regex
|
||||
source = inspected_source + source if regex_matched == true
|
||||
break
|
||||
end
|
||||
|
||||
regex_matched = true
|
||||
# 1. Determine if we are dealing with a user defined macro to declare inline functions
|
||||
# If the end of the pre-match string is a macro-declaration-like string,
|
||||
# we are dealing with a user defined macro to declare inline functions
|
||||
@@ -150,7 +169,8 @@ class CMockHeaderParser
|
||||
# Remove the macro from the source
|
||||
stripped_pre_match = inline_function_match.pre_match.sub(/(#define\s*)\z/, '')
|
||||
stripped_post_match = inline_function_match.post_match.sub(/\A(.*[\n]?)/, '')
|
||||
source = stripped_pre_match + stripped_post_match
|
||||
inspected_source += stripped_pre_match
|
||||
source = stripped_post_match
|
||||
next
|
||||
end
|
||||
|
||||
@@ -159,23 +179,32 @@ class CMockHeaderParser
|
||||
# we are dealing with a inline function declaration
|
||||
if /\A#{@function_declaration_parse_base_match}\s*;/m =~ inline_function_match.post_match
|
||||
# Only remove the inline part from the function declaration, leaving the function declaration won't do any harm
|
||||
source = inline_function_match.pre_match + inline_function_match.post_match
|
||||
inspected_source += inline_function_match.pre_match
|
||||
source = inline_function_match.post_match
|
||||
next
|
||||
end
|
||||
|
||||
# 3. If we get here, we found an inline function declaration AND inline function body.
|
||||
# Remove the function body to transform it into a 'normal' function.
|
||||
total_pairs_to_remove = count_number_of_pairs_of_braces_in_function(inline_function_match.post_match)
|
||||
# Remove the function body to transform it into a 'normal' function declaration.
|
||||
if /\A#{@function_declaration_parse_base_match}\s*\{/m =~ inline_function_match.post_match
|
||||
total_pairs_to_remove = count_number_of_pairs_of_braces_in_function(inline_function_match.post_match)
|
||||
|
||||
break if total_pairs_to_remove == 0 # Bad source?
|
||||
break if total_pairs_to_remove == 0 # Bad source?
|
||||
|
||||
inline_function_stripped = inline_function_match.post_match
|
||||
inline_function_stripped = inline_function_match.post_match
|
||||
|
||||
total_pairs_to_remove.times do
|
||||
inline_function_stripped.sub!(/\s*#{square_bracket_pair_regex_format}/, ';') # Remove inline implementation (+ some whitespace because it's prettier)
|
||||
total_pairs_to_remove.times do
|
||||
inline_function_stripped.sub!(/\s*#{square_bracket_pair_regex_format}/, ';') # Remove inline implementation (+ some whitespace because it's prettier)
|
||||
end
|
||||
inspected_source += inline_function_match.pre_match
|
||||
source = inline_function_stripped
|
||||
next
|
||||
end
|
||||
|
||||
source = inline_function_match.pre_match + inline_function_stripped # Make new source with the inline function removed and move on to the next
|
||||
# 4. If we get here, it means the regex match, but it is not related to the function (ex. static variable in header)
|
||||
# Leave this code as it is.
|
||||
inspected_source += inline_function_match.pre_match + inline_function_match[0]
|
||||
source = inline_function_match.post_match
|
||||
end
|
||||
end
|
||||
|
||||
@@ -205,10 +234,7 @@ class CMockHeaderParser
|
||||
# smush multiline macros into single line (checking for continuation character at end of line '\')
|
||||
source.gsub!(/\s*\\\s*/m, ' ')
|
||||
|
||||
# remove comments (block and line, in three steps to ensure correct precedence)
|
||||
source.gsub!(/(?<!\*)\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks
|
||||
source.gsub!(/\/\*.*?\*\//m, '') # remove block comments
|
||||
source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain)
|
||||
remove_comments_from_source(source)
|
||||
|
||||
# remove assembler pragma sections
|
||||
source.gsub!(/^\s*#\s*pragma\s+asm\s+.*?#\s*pragma\s+endasm/m, '')
|
||||
|
||||
+1
-37
@@ -8,46 +8,10 @@ project('cmock', 'c',
|
||||
license: 'MIT',
|
||||
meson_version: '>=0.53.0',
|
||||
subproject_dir : 'vendor',
|
||||
default_options: ['layout=flat', 'warning_level=3', 'werror=true', 'c_std=c11']
|
||||
default_options: ['werror=true', 'c_std=c11']
|
||||
)
|
||||
lang = 'c'
|
||||
cc = meson.get_compiler(lang)
|
||||
|
||||
|
||||
#
|
||||
# Meson: Add compiler flags
|
||||
#
|
||||
if cc.get_id() == 'clang'
|
||||
add_project_arguments(cc.get_supported_arguments(
|
||||
[
|
||||
'-Wexit-time-destructors',
|
||||
'-Wglobal-constructors',
|
||||
'-Wmissing-prototypes',
|
||||
'-Wmissing-noreturn',
|
||||
'-Wno-missing-braces',
|
||||
'-Wold-style-cast', '-Wpointer-arith', '-Wweak-vtables',
|
||||
'-Wcast-align', '-Wconversion', '-Wcast-qual', '-Wshadow'
|
||||
]
|
||||
), language: lang)
|
||||
endif
|
||||
|
||||
if cc.get_argument_syntax() == 'gcc'
|
||||
add_project_arguments(cc.get_supported_arguments(
|
||||
[
|
||||
'-Wformat', '-Waddress', '-Winit-self', '-Wno-multichar',
|
||||
'-Wpointer-arith' , '-Wwrite-strings' ,
|
||||
'-Wno-parentheses' , '-Wno-type-limits' ,
|
||||
'-Wformat-security' , '-Wunreachable-code' ,
|
||||
'-Waggregate-return' , '-Wformat-nonliteral' ,
|
||||
'-Wmissing-declarations', '-Wmissing-include-dirs' ,
|
||||
'-Wno-unused-parameter'
|
||||
]
|
||||
), language: lang)
|
||||
endif
|
||||
|
||||
unity_dep = dependency('unity', fallback: ['unity', 'unity_dep'])
|
||||
|
||||
#
|
||||
# Sub directory to project source code
|
||||
subdir('src')
|
||||
cmock_dep = declare_dependency(link_with: cmock_lib, include_directories: cmock_dir)
|
||||
|
||||
+12
-6
@@ -22,19 +22,25 @@
|
||||
|
||||
#define CMOCK_GUTS_NONE (0)
|
||||
|
||||
#if defined __GNUC__
|
||||
# define CMOCK_FUNCTION_ATTR(a) __attribute__((a))
|
||||
#else
|
||||
# define CMOCK_FUNCTION_ATTR(a) /* ignore */
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------
|
||||
* Memory API
|
||||
*-------------------------------------------------------*/
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size);
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_MEM_INDEX_TYPE obj_index);
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index);
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index);
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index) CMOCK_FUNCTION_ATTR(pure);
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index) CMOCK_FUNCTION_ATTR(pure);
|
||||
|
||||
void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index);
|
||||
void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index) CMOCK_FUNCTION_ATTR(pure);
|
||||
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void);
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void);
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void);
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesCapacity(void) CMOCK_FUNCTION_ATTR(const);
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void) CMOCK_FUNCTION_ATTR(pure);
|
||||
CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void) CMOCK_FUNCTION_ATTR(pure);
|
||||
void CMock_Guts_MemFreeAll(void);
|
||||
void CMock_Guts_MemFreeFinal(void);
|
||||
|
||||
|
||||
+1
-1
@@ -7,6 +7,6 @@
|
||||
cmock_dir = include_directories('.')
|
||||
|
||||
cmock_lib = static_library(meson.project_name(),
|
||||
sources: ['cmock.c'],
|
||||
files('cmock.c'),
|
||||
dependencies: [unity_dep],
|
||||
include_directories: cmock_dir)
|
||||
|
||||
@@ -0,0 +1,325 @@
|
||||
---
|
||||
:cmock:
|
||||
:plugins:
|
||||
- 'ignore_stateless'
|
||||
|
||||
:systest:
|
||||
:types: |
|
||||
|
||||
:mockable: |
|
||||
int foo(int a);
|
||||
void bar(int b);
|
||||
|
||||
:source:
|
||||
:header: |
|
||||
int function(int a, int b, int c);
|
||||
:code: |
|
||||
int function(int a, int b, int c)
|
||||
{
|
||||
bar(b);
|
||||
return foo(a) + foo(b) + foo(c);
|
||||
}
|
||||
|
||||
:tests:
|
||||
:common: |
|
||||
void setUp(void) {}
|
||||
void tearDown(void) {}
|
||||
|
||||
:units:
|
||||
- :pass: TRUE
|
||||
:should: 'successfully exercise simple ExpectAndReturn mock calls'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Expect(2);
|
||||
foo_ExpectAndReturn(1, 10);
|
||||
foo_ExpectAndReturn(2, 20);
|
||||
foo_ExpectAndReturn(3, 30);
|
||||
TEST_ASSERT_EQUAL(60, function(1, 2, 3));
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'ignore foo() calls'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Expect(4);
|
||||
foo_IgnoreAndReturn(40);
|
||||
TEST_ASSERT_EQUAL(120, function(3, 4, 3));
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'ignore the situation where foo() is not called even though we explicitly ignored it'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
foo_IgnoreAndReturn(20);
|
||||
//notice we do not call foo
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'ignore foo() calls and always return last item'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Expect(4);
|
||||
foo_IgnoreAndReturn(20);
|
||||
foo_IgnoreAndReturn(30);
|
||||
TEST_ASSERT_EQUAL(90, function(3, 4, 9));
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'ignore bar() and foo() calls'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
foo_IgnoreAndReturn(50);
|
||||
TEST_ASSERT_EQUAL(150, function(0, 0, 0));
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'multiple cycles of expects still pass when ignores enabled'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Expect(2);
|
||||
foo_ExpectAndReturn(1, 50);
|
||||
foo_ExpectAndReturn(2, 60);
|
||||
foo_ExpectAndReturn(3, 70);
|
||||
TEST_ASSERT_EQUAL(180, function(1, 2, 3));
|
||||
|
||||
bar_Expect(5);
|
||||
foo_ExpectAndReturn(4, 30);
|
||||
foo_ExpectAndReturn(5, 80);
|
||||
foo_ExpectAndReturn(6, 10);
|
||||
TEST_ASSERT_EQUAL(120, function(4, 5, 6));
|
||||
|
||||
bar_Expect(8);
|
||||
foo_ExpectAndReturn(7, 70);
|
||||
foo_ExpectAndReturn(8, 20);
|
||||
foo_ExpectAndReturn(9, 20);
|
||||
TEST_ASSERT_EQUAL(110, function(7, 8, 9));
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'multiple cycles of expects still fail when ignores enabled'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Expect(2);
|
||||
foo_ExpectAndReturn(1, 50);
|
||||
foo_ExpectAndReturn(2, 60);
|
||||
foo_ExpectAndReturn(3, 70);
|
||||
TEST_ASSERT_EQUAL(180, function(1, 2, 3));
|
||||
|
||||
bar_Expect(5);
|
||||
foo_ExpectAndReturn(4, 30);
|
||||
foo_ExpectAndReturn(5, 80);
|
||||
foo_ExpectAndReturn(6, 10);
|
||||
TEST_ASSERT_EQUAL(120, function(4, 5, 6));
|
||||
|
||||
bar_Expect(8);
|
||||
foo_ExpectAndReturn(7, 70);
|
||||
foo_ExpectAndReturn(8, 20);
|
||||
foo_ExpectAndReturn(9, 20);
|
||||
TEST_ASSERT_EQUAL(110, function(0, 8, 9));
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'With "fail_on_unexpected_calls" enabled, Expect/Ignore/... of bar is required and test fails.'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
function(1, 2, 3);
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'we can override an ignore with an expect and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
|
||||
bar_Expect(2);
|
||||
foo_ExpectAndReturn(1, 50);
|
||||
foo_ExpectAndReturn(2, 60);
|
||||
foo_ExpectAndReturn(3, 70);
|
||||
TEST_ASSERT_EQUAL(180, function(1, 2, 3));
|
||||
|
||||
bar_Expect(5);
|
||||
foo_ExpectAndReturn(4, 30);
|
||||
foo_ExpectAndReturn(5, 80);
|
||||
foo_ExpectAndReturn(6, 10);
|
||||
TEST_ASSERT_EQUAL(120, function(4, 5, 6));
|
||||
|
||||
bar_Expect(8);
|
||||
foo_ExpectAndReturn(7, 70);
|
||||
foo_ExpectAndReturn(8, 20);
|
||||
foo_ExpectAndReturn(9, 20);
|
||||
TEST_ASSERT_EQUAL(110, function(7, 8, 9));
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'we can override an ignore with an expect and fail'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
|
||||
bar_Expect(2);
|
||||
foo_ExpectAndReturn(1, 50);
|
||||
foo_ExpectAndReturn(2, 60);
|
||||
foo_ExpectAndReturn(3, 70);
|
||||
TEST_ASSERT_EQUAL(180, function(1, 2, 3));
|
||||
|
||||
bar_Expect(5);
|
||||
foo_ExpectAndReturn(4, 30);
|
||||
foo_ExpectAndReturn(5, 80);
|
||||
foo_ExpectAndReturn(6, 10);
|
||||
TEST_ASSERT_EQUAL(120, function(4, 5, 6));
|
||||
|
||||
bar_Expect(9);
|
||||
foo_ExpectAndReturn(7, 70);
|
||||
foo_ExpectAndReturn(8, 20);
|
||||
foo_ExpectAndReturn(9, 20);
|
||||
TEST_ASSERT_EQUAL(110, function(7, 8, 9));
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'we can override an ignore and return with an expect and pass'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
foo_IgnoreAndReturn(30);
|
||||
TEST_ASSERT_EQUAL(90, function(1, 2, 3));
|
||||
|
||||
bar_Expect(5);
|
||||
foo_ExpectAndReturn(4, 30);
|
||||
foo_ExpectAndReturn(5, 80);
|
||||
foo_ExpectAndReturn(6, 10);
|
||||
TEST_ASSERT_EQUAL(120, function(4, 5, 6));
|
||||
|
||||
bar_Expect(8);
|
||||
foo_ExpectAndReturn(7, 70);
|
||||
foo_ExpectAndReturn(8, 20);
|
||||
foo_ExpectAndReturn(9, 20);
|
||||
TEST_ASSERT_EQUAL(110, function(7, 8, 9));
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'we can override an ignore and return with an expect and fail'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
foo_IgnoreAndReturn(0);
|
||||
TEST_ASSERT_EQUAL(0, function(1, 2, 3));
|
||||
|
||||
bar_Expect(5);
|
||||
foo_ExpectAndReturn(4, 30);
|
||||
foo_ExpectAndReturn(5, 80);
|
||||
foo_ExpectAndReturn(6, 10);
|
||||
TEST_ASSERT_EQUAL(120, function(4, 5, 6));
|
||||
|
||||
bar_Expect(9);
|
||||
foo_ExpectAndReturn(7, 70);
|
||||
foo_ExpectAndReturn(8, 20);
|
||||
foo_ExpectAndReturn(9, 20);
|
||||
TEST_ASSERT_EQUAL(110, function(7, 8, 9));
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'we can override an expect with an ignore'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Expect(5);
|
||||
bar_Ignore();
|
||||
foo_ExpectAndReturn(1, 50);
|
||||
foo_ExpectAndReturn(2, 60);
|
||||
foo_ExpectAndReturn(3, 70);
|
||||
TEST_ASSERT_EQUAL(180, function(1, 2, 3));
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'we can override an expect with an ignore and return and fail after'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Expect(5);
|
||||
foo_ExpectAndReturn(4, 30);
|
||||
foo_ExpectAndReturn(5, 50);
|
||||
foo_IgnoreAndReturn(20);
|
||||
TEST_ASSERT_EQUAL(100, function(4, 5, 6));
|
||||
|
||||
bar_Expect(5);
|
||||
foo_ExpectAndReturn(9, 30); //THIS ONE WILL FAIL
|
||||
foo_ExpectAndReturn(2, 80);
|
||||
foo_ExpectAndReturn(3, 60);
|
||||
TEST_ASSERT_EQUAL(170, function(1, 2, 3));
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'we can override an expect with an ignore and return and only the ignore and return is acknowledged'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Expect(5);
|
||||
foo_ExpectAndReturn(2, 30); //NOTE THIS WOULD NORMALLY FAIL
|
||||
foo_ExpectAndReturn(5, 50);
|
||||
foo_IgnoreAndReturn(20); //BUT WE SAID WE NO LONGER CARE
|
||||
TEST_ASSERT_EQUAL(60, function(4, 5, 6));
|
||||
}
|
||||
|
||||
# StopIgnore
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'fail when function is called after ignore is stopped'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
foo_IgnoreAndReturn(10);
|
||||
function(0, 0, 0);
|
||||
bar_StopIgnore();
|
||||
function(0, 0, 0);
|
||||
}
|
||||
|
||||
- :pass: FALSE
|
||||
:should: 'delete expect after ignore is stopped'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
foo_ExpectAndReturn(0, 40);
|
||||
foo_ExpectAndReturn(0, 30);
|
||||
foo_ExpectAndReturn(0, 40);
|
||||
|
||||
foo_IgnoreAndReturn(20);
|
||||
foo_StopIgnore();
|
||||
|
||||
TEST_ASSERT_EQUAL(110, function(0, 0, 0)); // THIS SHOULD FAIL
|
||||
}
|
||||
|
||||
- :pass: TRUE
|
||||
:should: 'delete expected return values after ignore is stopped'
|
||||
:code: |
|
||||
test()
|
||||
{
|
||||
bar_Ignore();
|
||||
foo_ExpectAndReturn(0, 40);
|
||||
foo_ExpectAndReturn(0, 30);
|
||||
foo_ExpectAndReturn(0, 40);
|
||||
|
||||
foo_IgnoreAndReturn(20);
|
||||
foo_StopIgnore();
|
||||
|
||||
foo_ExpectAndReturn(0, 50);
|
||||
foo_ExpectAndReturn(0, 30);
|
||||
foo_ExpectAndReturn(0, 40);
|
||||
TEST_ASSERT_EQUAL(120, function(0, 0, 0));
|
||||
}
|
||||
|
||||
...
|
||||
@@ -0,0 +1,116 @@
|
||||
# ==========================================
|
||||
# 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]
|
||||
# ==========================================
|
||||
|
||||
require File.expand_path(File.dirname(__FILE__)) + "/../test_helper"
|
||||
require File.expand_path(File.dirname(__FILE__)) + '/../../lib/cmock_generator_plugin_ignore_stateless'
|
||||
|
||||
describe CMockGeneratorPluginIgnoreStateless, "Verify CMockGeneratorPluginIgnoreStateless Module" do
|
||||
|
||||
before do
|
||||
create_mocks :config, :utils
|
||||
@config = create_stub(:respond_to? => true)
|
||||
@cmock_generator_plugin_ignore_stateless = CMockGeneratorPluginIgnoreStateless.new(@config, @utils)
|
||||
end
|
||||
|
||||
after do
|
||||
end
|
||||
|
||||
it "have set up internal priority" do
|
||||
assert_equal(2, @cmock_generator_plugin_ignore_stateless.priority)
|
||||
end
|
||||
|
||||
it "not have any additional include file requirements" do
|
||||
assert(!@cmock_generator_plugin_ignore_stateless.respond_to?(:include_files))
|
||||
end
|
||||
|
||||
it "add a required variable to the instance structure" do
|
||||
function = {:name => "Grass", :args => [], :return => test_return[:void]}
|
||||
expected = " char Grass_IgnoreBool;\n"
|
||||
returned = @cmock_generator_plugin_ignore_stateless.instance_structure(function)
|
||||
assert_equal(expected, returned)
|
||||
end
|
||||
|
||||
it "handle function declarations for functions without return values" do
|
||||
function = {:name => "Mold", :args_string => "void", :return => test_return[:void]}
|
||||
expected = "#define Mold_Ignore() Mold_CMockIgnore()\nvoid Mold_CMockIgnore(void);\n" +
|
||||
"#define Mold_StopIgnore() Mold_CMockStopIgnore()\nvoid Mold_CMockStopIgnore(void);\n"
|
||||
returned = @cmock_generator_plugin_ignore_stateless.mock_function_declarations(function)
|
||||
assert_equal(expected, returned)
|
||||
end
|
||||
|
||||
it "handle function declarations for functions that returns something" do
|
||||
function = {:name => "Fungus", :args_string => "void", :return => test_return[:string]}
|
||||
expected = "#define Fungus_IgnoreAndReturn(cmock_retval) Fungus_CMockIgnoreAndReturn(cmock_retval)\n"+
|
||||
"void Fungus_CMockIgnoreAndReturn(const char* cmock_to_return);\n" +
|
||||
"#define Fungus_StopIgnore() Fungus_CMockStopIgnore()\n"+
|
||||
"void Fungus_CMockStopIgnore(void);\n"
|
||||
returned = @cmock_generator_plugin_ignore_stateless.mock_function_declarations(function)
|
||||
assert_equal(expected, returned)
|
||||
end
|
||||
|
||||
it "add required code to implementation precheck with void function" do
|
||||
function = {:name => "Mold", :args_string => "void", :return => test_return[:void]}
|
||||
expected = [" if (Mock.Mold_IgnoreBool)\n",
|
||||
" {\n",
|
||||
" UNITY_CLR_DETAILS();\n",
|
||||
" return;\n",
|
||||
" }\n"
|
||||
].join
|
||||
returned = @cmock_generator_plugin_ignore_stateless.mock_implementation_precheck(function)
|
||||
assert_equal(expected, returned)
|
||||
end
|
||||
|
||||
it "add required code to implementation precheck with return functions" do
|
||||
function = {:name => "Fungus", :args_string => "void", :return => test_return[:int]}
|
||||
retval = test_return[:int].merge({ :name => "cmock_call_instance->ReturnVal"})
|
||||
@utils.expect :code_assign_argument_quickly, ' mock_retval_0', ["Mock.Fungus_FinalReturn", retval]
|
||||
expected = [" if (Mock.Fungus_IgnoreBool)\n",
|
||||
" {\n",
|
||||
" UNITY_CLR_DETAILS();\n",
|
||||
" if (cmock_call_instance == NULL)\n",
|
||||
" return Mock.Fungus_FinalReturn;\n",
|
||||
" mock_retval_0",
|
||||
" return cmock_call_instance->ReturnVal;\n",
|
||||
" }\n"
|
||||
].join
|
||||
returned = @cmock_generator_plugin_ignore_stateless.mock_implementation_precheck(function)
|
||||
assert_equal(expected, returned)
|
||||
end
|
||||
|
||||
it "add a new mock interface for ignoring when function had no return value" do
|
||||
function = {:name => "Slime", :args => [], :args_string => "void", :return => test_return[:void]}
|
||||
expected = ["void Slime_CMockIgnore(void)\n",
|
||||
"{\n",
|
||||
" Mock.Slime_IgnoreBool = (char)1;\n",
|
||||
"}\n\n",
|
||||
"void Slime_CMockStopIgnore(void)\n",
|
||||
"{\n",
|
||||
" Mock.Slime_IgnoreBool = (char)0;\n",
|
||||
"}\n\n"
|
||||
].join
|
||||
returned = @cmock_generator_plugin_ignore_stateless.mock_interfaces(function)
|
||||
assert_equal(expected, returned)
|
||||
end
|
||||
|
||||
it "add a new mock interface for ignoring when function has return value" do
|
||||
function = {:name => "Slime", :args => [], :args_string => "void", :return => test_return[:int]}
|
||||
@utils.expect :code_add_base_expectation, "mock_return_1", ["Slime", false]
|
||||
expected = ["void Slime_CMockIgnoreAndReturn(int cmock_to_return)\n",
|
||||
"{\n",
|
||||
" Mock.Slime_CallInstance = CMOCK_GUTS_NONE;\n",
|
||||
" Mock.Slime_FinalReturn = cmock_to_return;\n",
|
||||
" Mock.Slime_IgnoreBool = (char)1;\n",
|
||||
"}\n\n",
|
||||
"void Slime_CMockStopIgnore(void)\n",
|
||||
"{\n",
|
||||
" Mock.Slime_IgnoreBool = (char)0;\n",
|
||||
"}\n\n"
|
||||
].join
|
||||
returned = @cmock_generator_plugin_ignore_stateless.mock_interfaces(function)
|
||||
assert_equal(expected, returned)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -73,7 +73,7 @@ describe CMockGeneratorPluginReturnThruPtr, "Verify CMockGeneratorPluginReturnTh
|
||||
complex_func_expect()
|
||||
expected = " char ReturnThruPtr_tofu_Used;\n" +
|
||||
" int* ReturnThruPtr_tofu_Val;\n" +
|
||||
" int ReturnThruPtr_tofu_Size;\n"
|
||||
" size_t ReturnThruPtr_tofu_Size;\n"
|
||||
returned = @cmock_generator_plugin_return_thru_ptr.instance_typedefs(@complex_func)
|
||||
assert_equal(expected, returned)
|
||||
end
|
||||
@@ -91,10 +91,10 @@ describe CMockGeneratorPluginReturnThruPtr, "Verify CMockGeneratorPluginReturnTh
|
||||
"#define Pine_ReturnThruPtr_tofu(tofu)" +
|
||||
" Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, sizeof(int))\n" +
|
||||
"#define Pine_ReturnArrayThruPtr_tofu(tofu, cmock_len)" +
|
||||
" Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, (int)(cmock_len * (int)sizeof(*tofu)))\n" +
|
||||
" Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, cmock_len * sizeof(*tofu))\n" +
|
||||
"#define Pine_ReturnMemThruPtr_tofu(tofu, cmock_size)" +
|
||||
" Pine_CMockReturnMemThruPtr_tofu(__LINE__, tofu, cmock_size)\n" +
|
||||
"void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, int cmock_size);\n"
|
||||
"void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, size_t cmock_size);\n"
|
||||
|
||||
returned = @cmock_generator_plugin_return_thru_ptr.mock_function_declarations(@complex_func)
|
||||
assert_equal(expected, returned)
|
||||
@@ -104,7 +104,7 @@ describe CMockGeneratorPluginReturnThruPtr, "Verify CMockGeneratorPluginReturnTh
|
||||
complex_func_expect();
|
||||
|
||||
expected =
|
||||
"void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, int cmock_size)\n" +
|
||||
"void Pine_CMockReturnMemThruPtr_tofu(UNITY_LINE_TYPE cmock_line, int* tofu, size_t cmock_size)\n" +
|
||||
"{\n" +
|
||||
" CMOCK_Pine_CALL_INSTANCE* cmock_call_instance = " +
|
||||
"(CMOCK_Pine_CALL_INSTANCE*)CMock_Guts_GetAddressFor(CMock_Guts_MemEndOfChain(Mock.Pine_CallInstance));\n" +
|
||||
|
||||
@@ -20,17 +20,19 @@ describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do
|
||||
@config.expect :plugins, []
|
||||
@config.expect :plugins, []
|
||||
@config.expect :plugins, []
|
||||
@config.expect :plugins, []
|
||||
@config.expect :treat_as, {'int' => 'INT','short' => 'INT16','long' => 'INT','char' => 'INT8','const char*' => 'STRING'}
|
||||
@cmock_generator_utils_simple = CMockGeneratorUtils.new(@config, {:unity_helper => @unity_helper})
|
||||
|
||||
@config.expect :when_ptr, :smart
|
||||
@config.expect :enforce_strict_ordering, true
|
||||
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore]
|
||||
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore]
|
||||
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore]
|
||||
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore]
|
||||
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore]
|
||||
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore]
|
||||
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
||||
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
||||
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
||||
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
||||
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
||||
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
||||
@config.expect :plugins, [:array, :cexception, :return_thru_ptr, :ignore_arg, :ignore, :ignore_stateless]
|
||||
@config.expect :treat_as, {'int' => 'INT','short' => 'INT16','long' => 'INT','char' => 'INT8','uint32_t' => 'HEX32','const char*' => 'STRING'}
|
||||
@cmock_generator_utils_complex = CMockGeneratorUtils.new(@config, {:unity_helper => @unity_helper, :A=>1, :B=>2})
|
||||
end
|
||||
@@ -153,7 +155,8 @@ describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do
|
||||
:args_string => "stuff",
|
||||
:args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]]
|
||||
}
|
||||
expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, stuff)\n{\n" +
|
||||
expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, stuff);\n" +
|
||||
"void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, stuff)\n{\n" +
|
||||
" cmock_call_instance->Expected_MyIntPtr = MyIntPtr;\n" +
|
||||
" memcpy((void*)(&cmock_call_instance->Expected_MyMyType), (void*)(&MyMyType),\n" +
|
||||
" sizeof(MY_TYPE[sizeof(MyMyType) == sizeof(MY_TYPE) ? 1 : -1])); /* add MY_TYPE to :treat_as_array if this causes an error */\n" +
|
||||
@@ -167,7 +170,8 @@ describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do
|
||||
:args_string => "stuff",
|
||||
:args => [test_arg[:int_ptr], test_arg[:mytype], test_arg[:string]]
|
||||
}
|
||||
expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* MyIntPtr, int MyIntPtr_Depth, const MY_TYPE MyMyType, const char* MyStr)\n{\n" +
|
||||
expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* MyIntPtr, int MyIntPtr_Depth, const MY_TYPE MyMyType, const char* MyStr);\n" +
|
||||
"void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* MyIntPtr, int MyIntPtr_Depth, const MY_TYPE MyMyType, const char* MyStr)\n{\n" +
|
||||
" cmock_call_instance->Expected_MyIntPtr = MyIntPtr;\n" +
|
||||
" cmock_call_instance->Expected_MyIntPtr_Depth = MyIntPtr_Depth;\n" +
|
||||
" cmock_call_instance->IgnoreArg_MyIntPtr = 0;\n" +
|
||||
@@ -186,7 +190,8 @@ describe CMockGeneratorUtils, "Verify CMockGeneratorUtils Module" do
|
||||
:args_string => "stuff",
|
||||
:args => [test_arg[:const_ptr], test_arg[:double_ptr]]
|
||||
}
|
||||
expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* const MyConstPtr, int MyConstPtr_Depth, int const** MyDoublePtr, int MyDoublePtr_Depth)\n{\n" +
|
||||
expected = "void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* const MyConstPtr, int MyConstPtr_Depth, int const** MyDoublePtr, int MyDoublePtr_Depth);\n" +
|
||||
"void CMockExpectParameters_Melon(CMOCK_Melon_CALL_INSTANCE* cmock_call_instance, int* const MyConstPtr, int MyConstPtr_Depth, int const** MyDoublePtr, int MyDoublePtr_Depth)\n{\n" +
|
||||
" cmock_call_instance->Expected_MyConstPtr = MyConstPtr;\n" +
|
||||
" cmock_call_instance->Expected_MyConstPtr_Depth = MyConstPtr_Depth;\n" +
|
||||
" cmock_call_instance->IgnoreArg_MyConstPtr = 0;\n" +
|
||||
|
||||
@@ -2009,7 +2009,8 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
end
|
||||
end
|
||||
|
||||
it "Transform inline functions doesn't change a header with no inlines" do
|
||||
it "Transform inline functions only removes comments from a header with no inlines" do
|
||||
# We remove the comments from the header, this is to protect the parser from wrongfully recognizing inline functions
|
||||
source =
|
||||
"#ifndef _NOINCLUDES\n" +
|
||||
"#define _NOINCLUDES\n" +
|
||||
@@ -2040,7 +2041,37 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
"\n" +
|
||||
"#endif _NOINCLUDES\n"
|
||||
|
||||
assert_equal(source, @parser.transform_inline_functions(source))
|
||||
expected =
|
||||
"#ifndef _NOINCLUDES\n" +
|
||||
"#define _NOINCLUDES\n" +
|
||||
"#include \"unity.h\"\n" +
|
||||
"#include \"cmock.h\"\n" +
|
||||
"#include \"YetAnotherHeader.h\"\n" +
|
||||
"\n" +
|
||||
"\n" + # Removed comment
|
||||
"#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__)\n" +
|
||||
"#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0)))\n" +
|
||||
"#pragma GCC diagnostic push\n" +
|
||||
"#endif\n" +
|
||||
"#if !defined(__clang__)\n" +
|
||||
"#pragma GCC diagnostic ignored \"-Wpragmas\"\n" +
|
||||
"#endif\n" +
|
||||
"#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n" +
|
||||
"#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n" +
|
||||
"#endif\n" +
|
||||
"\n" +
|
||||
"struct my_struct {\n" +
|
||||
"int a;\n" +
|
||||
"int b;\n" +
|
||||
"int b;\n" +
|
||||
"char c;\n" +
|
||||
"};\n" +
|
||||
"int my_function(int a);\n" +
|
||||
"int my_better_function(struct my_struct *s);\n" +
|
||||
"\n" +
|
||||
"#endif _NOINCLUDES\n"
|
||||
|
||||
assert_equal(expected, @parser.transform_inline_functions(source))
|
||||
end
|
||||
|
||||
it "Transform inline functions changes inline functions to function declarations" do
|
||||
@@ -2133,7 +2164,7 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
"#include \"cmock.h\"\n" +
|
||||
"#include \"YetAnotherHeader.h\"\n" +
|
||||
"\n" +
|
||||
"/* Ignore the following warnings since we are copying code */\n" +
|
||||
"\n" + # Removed comment
|
||||
"#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__)\n" +
|
||||
"#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0)))\n" +
|
||||
"#pragma GCC diagnostic push\n" +
|
||||
@@ -2173,6 +2204,73 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
assert_equal(expected, @parser.transform_inline_functions(source))
|
||||
end
|
||||
|
||||
it "Transform inline functions leaves static variables" do
|
||||
source =
|
||||
"#ifndef _NOINCLUDES\n" +
|
||||
"#define _NOINCLUDES\n" +
|
||||
"#include \"unity.h\"\n" +
|
||||
"#include \"cmock.h\"\n" +
|
||||
"#include \"YetAnotherHeader.h\"\n" +
|
||||
"\n" +
|
||||
"/* Ignore the following warnings since we are copying code */\n" +
|
||||
"#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__)\n" +
|
||||
"#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0)))\n" +
|
||||
"#pragma GCC diagnostic push\n" +
|
||||
"#endif\n" +
|
||||
"#if !defined(__clang__)\n" +
|
||||
"#pragma GCC diagnostic ignored \"-Wpragmas\"\n" +
|
||||
"#endif\n" +
|
||||
"#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n" +
|
||||
"#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n" +
|
||||
"#endif\n" +
|
||||
"\n" +
|
||||
"int my_function(int a);\n" +
|
||||
"static inline int staticinlinefunc(struct my_struct *s)\n" +
|
||||
"{\n" +
|
||||
" return s->a;\n" +
|
||||
"}\n" +
|
||||
"static const int my_variable = 5;\n" +
|
||||
"struct my_struct {\n" +
|
||||
"int a;\n" +
|
||||
"int b;\n" +
|
||||
"int b;\n" +
|
||||
"char c;\n" +
|
||||
"};\n" +
|
||||
"#endif _NOINCLUDES\n"
|
||||
|
||||
expected =
|
||||
"#ifndef _NOINCLUDES\n" +
|
||||
"#define _NOINCLUDES\n" +
|
||||
"#include \"unity.h\"\n" +
|
||||
"#include \"cmock.h\"\n" +
|
||||
"#include \"YetAnotherHeader.h\"\n" +
|
||||
"\n" +
|
||||
"\n" + #The comments are now removed
|
||||
"#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__)\n" +
|
||||
"#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0)))\n" +
|
||||
"#pragma GCC diagnostic push\n" +
|
||||
"#endif\n" +
|
||||
"#if !defined(__clang__)\n" +
|
||||
"#pragma GCC diagnostic ignored \"-Wpragmas\"\n" +
|
||||
"#endif\n" +
|
||||
"#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n" +
|
||||
"#pragma GCC diagnostic ignored \"-Wduplicate-decl-specifier\"\n" +
|
||||
"#endif\n" +
|
||||
"\n" +
|
||||
"int my_function(int a);\n" +
|
||||
"int staticinlinefunc(struct my_struct *s);\n" +
|
||||
"static const int my_variable = 5;\n" +
|
||||
"struct my_struct {\n" +
|
||||
"int a;\n" +
|
||||
"int b;\n" +
|
||||
"int b;\n" +
|
||||
"char c;\n" +
|
||||
"};\n" +
|
||||
"#endif _NOINCLUDES\n"
|
||||
|
||||
assert_equal(expected, @parser.transform_inline_functions(source))
|
||||
end
|
||||
|
||||
it "Count number of pairs of braces in function succesfully" do
|
||||
source =
|
||||
"int foo(struct my_struct *s)\n" +
|
||||
@@ -2714,4 +2812,32 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
|
||||
assert_equal(expected, @parser.transform_inline_functions(source))
|
||||
end
|
||||
|
||||
it "Transform inline functions will ignore comments containing static" do
|
||||
source =
|
||||
"typedef struct {\n" +
|
||||
"const uint32_t var1;\n" +
|
||||
"const uint16_t var2; // comment with the word static in it\n" +
|
||||
"} struct1;\n" +
|
||||
"\n" +
|
||||
"typedef struct {\n" +
|
||||
"const uint32_t var1;\n" +
|
||||
"const uint16_t var2;\n" +
|
||||
"} struct2;\n"
|
||||
|
||||
expected =
|
||||
"typedef struct {\n" +
|
||||
"const uint32_t var1;\n" +
|
||||
"const uint16_t var2; \n" +
|
||||
"} struct1;\n" +
|
||||
"\n" +
|
||||
"typedef struct {\n" +
|
||||
"const uint32_t var1;\n" +
|
||||
"const uint16_t var2;\n" +
|
||||
"} struct2;\n"
|
||||
|
||||
@parser.treat_inlines = :include
|
||||
assert_equal(expected, @parser.transform_inline_functions(source))
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user