Git Product home page Git Product logo

cmock's Introduction

CMock CI

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!

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

If you're using Ceedling, there is no need to install CMock. It will handle it for you. For everyone else, the simplest way is to grab it off github. You can also download it as a zip if you prefer. The Github method looks something like this:

> git clone --recursive https://github.com/throwtheswitch/cmock.git
> cd cmock
> bundle install # Ensures you have all RubyGems needed

If you plan to help with the development of CMock (or just want to verify that it can perform its self tests on your system) then you can enter the test directory and then ask it to test:

> cd test
> rake # Run all CMock self tests

API Documentation

cmock's People

Contributors

andred avatar art-of-dom avatar barneywilliams avatar cezarygapinski avatar chrishonson avatar cloudsftp avatar d-led avatar dmurdin avatar dreamer-coding-555 avatar hannes103 avatar jlindgren90 avatar jvranish avatar laurensmiers avatar lgreve avatar malsyned avatar merazmus avatar metc avatar mvandervoord avatar novanekmit avatar ollehu avatar phonetagger avatar pwatt01 avatar skelliam avatar steinheselmans avatar sw17ch avatar tbates-redarc avatar tuc-an avatar tz18 avatar wojciechjasko avatar xenoamor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cmock's Issues

Test Fails When TEST_ASSERT_EQUAL is true inside CMock Callback

I must be missing something trivial here. I'd appreciate any help.
I reduced my test file to this:

#include <unity.h>
#include <stdbool.h>
#include "uart.h"
#include "mock_assert.h"

bool ASSERT_EXPECTED;

void setUp(void)
{
    ASSERT_EXPECTED = false;
}

void tearDown(void)
{
}

void _assert_Callback(const char* file, int line, int cmock_num_calls)
{
    TEST_ASSERT_EQUAL(true, ASSERT_EXPECTED);
}

void test_Verify_Init_With_NULL_Reference(void)
{
    _assert_StubWithCallback(_assert_Callback);
    ASSERT_EXPECTED = true;
    uart_init(0);
}

I'm using Ceedling and when I do "rake test:all", I receive the message:

ERROR: Test executable "test_uart.out" failed.

Produced no output to $stdout.
And then likely crashed.
This is often a symptom of a bad memory access in source or test code.

My tests were running OK, until I tried to use CMock to mock my _assert function.
ASSERT_EXPECTED has global scope. I may be missing something here but I don't see why it would not be acessible from those functions.

The crazy thing is:
if I set the ASSERT_EXPECTED to falsein the test_Verify_Init_With_NULL_Reference, the test runs and then fails correctly.
So I tried this two situations inside _assert_Callback:
1- TEST_ASSERT_EQUAL(true, false) - test runs and fails as expected
2= TEST_ASSERT_EQUAL(true,true) - test fails with above message

Any idea what may be causing this?

CMock unexpected Ignore behavior

Say you have a function under test like this:

void foo(){
    DoThing(1,2);
    DoThing(3,4);
}

and then you write a test like this:

void test_foo_should_do_the_first_thing()
{
    DoThing_Expect(500, 600);
    DoThing_Ignore();
    foo();
}

the test passes. Even though the expect has the wrong parameters. In my cmock settings I have the :ignore property set to :args_only. Apparently, including one call to xxx_Ignore(), causes the arguments to be ignored to every call made to that function. But that is quite unintuitive. It's dangerous because It looks like I have an expectation in place but that expect is begin ignored completely. However, If I delete the line DoThing_Expect(500, 600); from the test, the test fails! So behind the scene, the expect seems to be getting replaced with an ignore, making the test quite useless.

Memory alignment of CMock_Guts_Buffer

Hi,
I think I stumbled upon a bug in CMock which can occurs when the memory alignment is not 1 byte.
In the CMock_Guts_MemNew function, access to CMock_Guts_Buffer is done by first adding CMock_Guts_FreePtr (which is 4 initially), and then casting it to a (in my case) an 32bit unsigned int pointer. CMock_Guts_Buffer currently is defined as a char array, and thus does not have to be aligned. So if the CMock_Guts_Buffer is not allocated to a 32 bit aligned location, CMock will crash the system on the first call to CMock_Guts_MemNew. (Assuming unaligned access is not supported ofcourse.)

Add support for mocking headers in subdirectories.

Suggested syntax:

#include "foo/bar/mock_baz.h"

Produces a set of mocked files pulled in by the statement:

#include <foo/bar/baz.h>

or

#include "foo/bar/baz.h"

The primary motivation for this is to support stubbing out architecture interface header files for testing.

Expect does not work with ReturnThrPtr

I have a function that I would like to mock
void my_third_function(int * p_arg);

But in a test case:
...
int retval = 10;
int expected = 11;
my_third_function_Expect(&expected);
my_third_function_ReturnThruPtr_p_arg(&retval);
...
I will get this
Element 0 Expected 11 Was 10. Function 'my_third_function' called with unexpected value for argument 'p_arg'.

If I change
int retval = 10;
to
int retval = 11;
The case will work.

The problem is in the generated code (UNITY_TEST_ASSERT_EQUAL_INT_ARRAY is done after memcpy, which will over write the checked argument):
...
if (cmock_call_instance->ReturnThruPtr_p_arg_Used)
{
memcpy(p_arg, cmock_call_instance->ReturnThruPtr_p_arg_Val,
cmock_call_instance->ReturnThruPtr_p_arg_Size);
}
{
if (cmock_call_instance->Expected_p_arg == NULL)
{ UNITY_TEST_ASSERT_NULL(p_arg, cmock_line, "Expected NULL. Function 'my_third_function' called with unexpected value for argument 'p_arg'."); }
else
{ UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(cmock_call_instance->Expected_p_arg, p_arg, 1, cmock_line, "Function 'my_third_function' called with unexpected value for argument 'p_arg'."); }
}
...

Following the cmock getting started tutorial (yes those 4 lines) don't work.

Well, I tried with 1.8.7 and 1.9.3 from http://rubyinstaller.org/downloads/

I first ran:

gem install rake
gem install bundler

I skipped the git checkout because I don't have git installed. I just downloaded CMock and Unity and put Unity in the vendor/unity folder.

I then run (and get as output)

C:\cmock>bundle install rake
ERROR: "bundle install" was called with arguments ["rake"]
Usage: "bundle install [OPTIONS]"

C:\cmock>bundle install
Using rake 10.4.2
Using constructor 2.0.0
Using diy 1.1.2
Using minitest 5.5.0
Using require_all 1.3.2
Using bundler 1.7.9
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.

C:\cmock>bundle exec rake
mkdir -p C:/cmock/test/system/generated
mkdir -p C:/cmock/test/system/build
C:/Ruby187/bin/ruby.exe -I"lib" -I"C:/Ruby187/lib/ruby/gems/1.8/gems/rake-10.4.2/lib" "C:/Ruby187/lib/ruby/gems/1.8/gems/rake-10.4.2/lib/rake/rake_test_loader.rb" "test/unit/*_test.rb"
C:/cmock/test/unit/cmock_config_test.rb:8:in `require': C:/cmock/test/unit/../test_helper.rb:19: syntax error, unexpected '=', expecting '|' (SyntaxError)
    stub.define_singleton_method(k) {|unused=nil| return v }
                                             ^
C:/cmock/test/unit/../test_helper.rb:19: void value expression
    stub.define_singleton_method(k) {|unused=nil| return v }
                                                          ^
C:/cmock/test/unit/../test_helper.rb:19: syntax error, unexpected tIDENTIFIER, expecting kEND
    stub.define_singleton_method(k) {|unused=nil| return v }
                                                          ^
C:/cmock/test/unit/../test_helper.rb:42: syntax error, unexpected $end, expecting kEND
        from C:/cmock/test/unit/cmock_config_test.rb:8
        from C:/Ruby187/lib/ruby/gems/1.8/gems/rake-10.4.2/lib/rake/rake_test_loader.rb:15:in `require'
        from C:/Ruby187/lib/ruby/gems/1.8/gems/rake-10.4.2/lib/rake/rake_test_loader.rb:15
        from C:/Ruby187/lib/ruby/gems/1.8/gems/rake-10.4.2/lib/rake/rake_test_loader.rb:4:in `select'
        from C:/Ruby187/lib/ruby/gems/1.8/gems/rake-10.4.2/lib/rake/rake_test_loader.rb:4
rake aborted!
Command failed with status (1): [ruby -I"lib" -I"C:/Ruby187/lib/ruby/gems/1.8/gems/rake-10.4.2/lib" "C:/Ruby187/lib/ruby/gems/1.8/gems/rake-10.4.2/lib/rake/rake_test_loader.rb" "test/unit/*_test.rb" ]


Tasks: TOP => default => test => test:units
(See full trace by running task with --trace)

C:\cmock>

How do I solve this? I am no rubyguru (first time ever using it to be honest).

Any help is appreciated.

CMock uses GCC-specific #pragmas with non-GCC toolchains

On one of my projects I am using IAR for ARM with the following :tools: configuration for the compiler:

:tools:
  :test_compiler:
    :executable: iccarm.exe
    :name: 'IAR-ARM C/C++ Compiler'
    :stderr_redirect: :win #inform Ceedling what model of $stderr capture to use
    :arguments:
      - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE #expands to -I search paths
      - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR #expands to -I search paths
      - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR #expands to all -D defined symbols
      - --silent --use_unix_directory_separators --no_wrap_diagnostics #Configure output
      - --diag_suppress=Pa050 # Ignore warning about non-native line-ends
      - --no_cse --no_unroll --no_inline --no_code_motion --no_tbaa --no_clustering --no_scheduling
      - --endian=little --cpu=Cortex-M4 --fpu=VFPv4_sp
      - --debug
      - -Ol --dlib_config
      - "#{'\"'}#{`type iar-path.inc`}#{'/arm/inc/c/DLib_Config_Normal.h'}#{'\"'}"
      - ${1} #source code input file (Ruby method call param list sub)
      - -o ${2} #object file output (Ruby method call param list sub)

And I get the following warning:

Warning[Pe161]: unrecognized #pragma

Looking into the MockMyFile.h I see this:

/* Ignore the following warnings, since we are copying code */
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
#pragma GCC diagnostic ignored "-Wpragmas"
#endif
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wduplicate-decl-specifier"

It's those lower two #pragmas that are being used even though I'm not using GCC. I can fix this by ignoring Pe161 but other compilers might fail with an error so please fix this. Thank you!

Generated mocks for void typedefs result in CL.exe compiler warning C4034

The generated mock of the following syntactically correct function generates a compiler warning C4034 :

typedef void SOMETHING;
void foo(SOMETHING* arg0);

The offending generated function looks like this:

void foo(SOMETHING* arg0)
{
  UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;
  CMOCK_foo_CALL_INSTANCE* cmock_call_instance = (CMOCK_foo_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.foo_CallInstance);
  Mock.foo_CallInstance = CMock_Guts_MemNext(Mock.foo_CallInstance);
  UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "Function 'foo' called more times than expected.");
  cmock_line = cmock_call_instance->LineNumber;
  {
    UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(cmock_call_instance->Expected_arg0), (void*)(arg0), sizeof(SOMETHING), cmock_line, "Function 'foo' called with unexpected value for argument 'arg0'.");
  }
}

As you can see, calling sizeof(SOMETHING) is essentially sizeof(void) and may result in 0.

CMock generates invalid C for headers with dashes in the name

When I gave CMock a header file named cmock-bug.h with the contents:

#ifndef CMOCK_BUG_H
#define CMOCK_BUG_H

void cmock_bug(void);

#endif /* !CMOCK_BUG_H */

It created this Mockcmock-bug.h:

#ifndef _MOCKCMOCK-BUG_H
#define _MOCKCMOCK-BUG_H

#include "cmock-bug.h"

void Mockcmock-bug_Init(void);
void Mockcmock-bug_Destroy(void);
void Mockcmock-bug_Verify(void);

#define cmock_bug_Expect() cmock_bug_CMockExpect(__LINE__)
void cmock_bug_CMockExpect(UNITY_LINE_TYPE cmock_line);

#endif

This mock header file won't compile because of the dashes in the guard macro and function names.

Dashes are pretty common in C file names, particularly in GNU and Gnome source code. This seems like a use case CMock would want to support.

Mocking a function with String-Argument

Hello,
I guess, I'm missing something. Lets suppose I have a function

void ToTest(void)
{
  char string[512] = "";

  for (int i = 0; i < 100; i++)
  {
    sprintf(string, "String%d", i);
    Function(string);
  }
}

that I want to test. It calls a function int Function(char* string) that I have to mock.
Then, back in the testcase, I use Function_ExpectAndReturn(..) to enter the expected strings. As long as I enter hardcoded strings here (Function_ExpectAndReturn("String1")) everything is fine (by chance, I guess). Not the string is passed (in terms of strcpy/memcpy) but only the address. That means, if I want to enter all 100 strings with a loop, only the last string is placed at the address and the test fails.

Is that a bug or a feature? :) Is there a way to overcome this issue?

All the best,
Oliver

cmock does not create the mock directory by default

The first time running cmock, I got this error:

:> cmock spi.h
Creating mock for spi...
../lib/cmock_file_writer.rb:26:in `initialize': No such file or directory @ rb_sysopen - mocks/Mockspi.h.new (Errno::ENOENT)

Once I create the mocks directory then everything works fine. However the above error message is a bit cryptic, especially for new users. Can we either:

a) Create the mocks dir by default
b) have a better warning message prompting the user to create or configure the mocks directory

Any preference?

invalid byte sequence in UTF-8

This seems to be a ruby issue related to 1.9, my version:

ruby -v
ruby 1.9.3p392 (2013-02-22 revision 39386) [x86_64-linux]

Error output when I try to run the mocking process:

tools/Cmock/lib/cmock_header_parser.rb:53:in `scan': invalid byte sequence in UTF-8 (ArgumentError)
    from [snip]/tools/Cmock/lib/cmock_header_parser.rb:53:in `import_source'
    from [snip]/tools/Cmock/lib/cmock_header_parser.rb:32:in `parse'
    from tools/Cmock/lib/cmock.rb:40:in `generate_mock'
    from tools/Cmock/lib/cmock.rb:31:in `block in setup_mocks'
    from tools/Cmock/lib/cmock.rb:30:in `each'
    from tools/Cmock/lib/cmock.rb:30:in `setup_mocks'
    from tools/Cmock/lib/cmock.rb:64:in `<main>'

Regards

Only One Ignore Is Allowed

It would be nice to be able to ignore calls to a function after the initial call. Something like:
TestFunction_Expect(...)
TestFunction_Ignore()

CodeUnderTestCall() <-- calls 'TestFunction' twice.

This would allow the testing of individual parts in some functions. The ignore_args module already does something very similar. I am able to add a second 'expect', then just ignore all of the args. It's just ugly.

mock functions with __wrap_ prefix

I'm new to github, so not really sure if it's a right place to propose ideas and new functionality here, but still...

It would be really nice to have a configurable option that defines a prefix name for the generated mock functions. Say, the original function is "int foo(int a)", then CMock would generate a mock with slightly changed name as "int prefixfoo(int a)". It would be a neat feature to use it together with the GNU linker --wrap option, which would make it possible to generate a wrapper mock with CMock, like "int __wrap_foo(int a)". Then, in a unit test, one could define a callback for the mock and from that callback call the original (being mocked) function as __real_foo().

Thanks!

CMock cannot generator mocks for function which uses incomplete struct type.

Hello,

I've downloaded the most recent version of CMock from the origin/master branch with SHA-1 f341e3f650ffa2b301768b5a1acbea0264999db2 and then I've tried to play with it a little bit. I've encountered a problem when I was trying to generate mocks for function which argument is of incomplete struct type, please find my modified foo.c, foo.h and test_foo.c files:

[https://gist.github.com/a-d-v-e-n-t-u-r-o-u-s/1089367da8f2ba7af39caf900400c062]

Here is also console output:

build/test/mocks/mock_foo.c: In function โ€˜foo_attachโ€™:
build/test/mocks/mock_foo.c:140:107: error: invalid application of โ€˜sizeofโ€™ to incomplete type โ€˜struct FOO_handle_tโ€™
     UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(cmock_call_instance->Expected_handle), (void*)(handle), sizeof(struct FOO_handle_t), cmock_line, CMockStringMismatch);
                                                                                                           ^
/home/babula/Documents/source/github/cmock/vendor/unity/src/unity_internals.h:670:191: note: in definition of macro โ€˜UNITY_TEST_ASSERT_EQUAL_MEMORYโ€™
 ITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message)                     UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(len), 1, (m
                                                                                                                                                                                     ^
build/test/MakefileTestSupport:59: recipe for target 'build/test/mocks/mock_foo.o' failed


Can you please advise is there some magic switch in the order to turn off those error messages ? Currently the simplest solution would be moving structure definition to the header file.

bundle exec rake fails under MinGW w/ GCC 4.8.1

Running the install instructions in the Readme.md, bundle exec rake failes when executing the first compiled C test on Windows, with MinGW and GCC 4.8.1. Forcing rakefile_helper.rb to output generated gcc commands renders the following (relevant) output:

----------------
UNIT TEST C CODE
----------------

Testing test/c/TestCMockC
(TEST, CMOCK_MEM_SIZE=128, CMOCK_MEM_ALIGN=2, CMOCK_MEM_INDEX_TYPE=int)
gcc -DUNITY_SUPPORT_64 -DCMOCK_MEM_INDEX_TYPE=int -DCMOCK_MEM_ALIGN=2 -DCMOCK_MEM_SIZE=128 -DTEST -c -Wall -Wextra -Wunused-parameter -Wno-address -std=c99 -pedantic -O0 -g3 -Itest/system/generated/ -Iexamples/test/ -Itest/system/generated/ -Isrc/ -Ivendor/unity/src/ -Ivendor/c_exception/lib/ -Itest/system/test_compilation/ -Itest/ src/cmock.c -otest/system/build/cmock.o
gcc -DUNITY_SUPPORT_64 -DCMOCK_MEM_INDEX_TYPE=int -DCMOCK_MEM_ALIGN=2 -DCMOCK_MEM_SIZE=128 -DTEST -c -Wall -Wextra -Wunused-parameter -Wno-address -std=c99 -pedantic -O0 -g3 -Itest/system/generated/ -Iexamples/test/ -Itest/system/generated/ -Isrc/ -Ivendor/unity/src/ -Ivendor/c_exception/lib/ -Itest/system/test_compilation/ -Itest/ test/c/TestCMockC.c -otest/system/build/TestCMockC.o
gcc -DUNITY_SUPPORT_64 -DCMOCK_MEM_INDEX_TYPE=int -DCMOCK_MEM_ALIGN=2 -DCMOCK_MEM_SIZE=128 -DTEST -c -Wall -Wextra -Wunused-parameter -Wno-address -std=c99 -pedantic -O0 -g3 -Itest/system/generated/ -Iexamples/test/ -Itest/system/generated/ -Isrc/ -Ivendor/unity/src/ -Ivendor/c_exception/lib/ -Itest/system/test_compilation/ -Itest/ test/c/TestCMockC_Runner.c -otest/system/build/TestCMockC_Runner.o
gcc -DUNITY_SUPPORT_64 -DCMOCK_MEM_INDEX_TYPE=int -DCMOCK_MEM_ALIGN=2 -DCMOCK_MEM_SIZE=128 -DTEST -c -Wall -Wextra -Wunused-parameter -Wno-address -std=c99 -pedantic -O0 -g3 -Itest/system/generated/ -Iexamples/test/ -Itest/system/generated/ -Isrc/ -Ivendor/unity/src/ -Ivendor/c_exception/lib/ -Itest/system/test_compilation/ -Itest/ vendor/unity/src/unity.c -otest/system/build/unity.o
gcc -lm test/system/build/cmock.o test/system/build/TestCMockC.o test/system/build/TestCMockC_Runner.o test/system/build/unity.o -lm -o test/system/build/TestCMockC.exe
rake aborted!
test/system/build/TestCMockC.exe failed. (Returned )
c:/Users/Brad/Dropbox/Dev/cmock/rakefile_helper.rb:148:in `execute'
c:/Users/Brad/Dropbox/Dev/cmock/rakefile_helper.rb:367:in `block in build_and_test_c_files'
c:/Users/Brad/Dropbox/Dev/cmock/rakefile_helper.rb:359:in `build_and_test_c_files'
c:/Users/Brad/Dropbox/Dev/cmock/Rakefile:65:in `block (2 levels) in <top (required)>'
Tasks: TOP => default => test => test:c
(See full trace by running task with --trace)

Looking at the objdump, or stepping through with GDB, the code appears to fail at the first call to setUp(), which calls into nowhere code:

    if (TEST_PROTECT())
  40503e:       c7 04 24 f8 1a 41 00    movl   $0x411af8,(%esp)
  405045:       e8 d6 70 00 00          call   40c120 <__setjmp>
  40504a:       85 c0                   test   %eax,%eax
  40504c:       75 0a                   jne    405058 <_UnityDefaultTestRun+0x53
>
    {
        setUp();
  40504e:       e8 c3 a6 ff ff          call   3ff716 <__size_of_stack_reserve__
+0x1ff716>
        Func();
  405053:       8b 45 08                mov    0x8(%ebp),%eax
  405056:       ff d0                   call   *%eax
    }

On an Ubuntu VM, for example, the following disassembly is generated:

   if (TEST_PROTECT())
  4031f8:       bf 60 51 60 00          mov    $0x605160,%edi
  4031fd:       e8 ae d2 ff ff          callq  4004b0 <_setjmp@plt>
  403202:       85 c0                   test   %eax,%eax
  403204:       75 0b                   jne    403211 <UnityDefaultTestRun+0x55>
    {
        setUp();
  403206:       e8 0b d6 ff ff          callq  400816 <setUp>
        Func();
  40320b:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  40320f:       ff d0                   callq  *%rax
    }

I'm.. Kinda at a loss here. I really suspect the toolchain, except that I've been able to compile other non-trivially large projects with this same toolchain, and haven't seen any weirdness, and my google-fu has failed. Appreciate any insights.

Wrong #include if file name includes mock_prefix

There seems to be a bug for recreating the original header file name from the cmock header in line 67 of lib/cmock_generator.rb

    orig_filename = filename.gsub(@config.mock_prefix, "") 

If the original file name contains @config.mock_prefix, the attempt to recreate the original file name in this line creates a wrong name where @config.mock_prefix is removed at all occurrences not just at the beginning.

Suggested replacement:

    orig_filename = filename[@config.mock_prefix.size..-1] 

CMock fails generating mock when :array plugin is used

I have a header with this function prototype (all others have been commented out) and the error persists:

I2C_AO_REQ_RET pubRequestI2C(unsigned char addr, unsigned char *data, uint32_t length, I2C_DIRECTION dir, QActive *requesting_AO);

This configuration works fine:

:cmock:
  :verbosity: 3
  :mock_prefix: mock_
  :when_no_prototypes: :warn
  :enforce_strict_ordering: TRUE
  :when_ptr: smart
  :plugins:
    - :ignore
    - :callback
    - :ignore_arg

  :treat_as:
    uint8:    HEX8
    uint16:   HEX16
    uint32:   UINT32
    int8:     INT8
    bool:     UINT8

However when I add :array I get the following error output:

vagrant@vagrant-ubuntu-trusty-64:/vagrant$ ceedling test:all


Test 'test_temp_humid.c'
------------------------
Creating mock for i2c...
rake aborted!
TypeError: can't convert nil into String
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb:60:in `block in mock_implementation
_always_check_args'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb:59:in `each'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_generator_plugin_expect.rb:59:in `mock_implementation_always_c
heck_args'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_plugin_manager.rb:33:in `block in run'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_plugin_manager.rb:33:in `collect'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_plugin_manager.rb:33:in `run'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb:225:in `create_mock_implementation'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb:79:in `block (2 levels) in create_mock_source_fil
e'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb:78:in `each'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb:78:in `block in create_mock_source_file'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_file_writer.rb:31:in `block in create_file'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_file_writer.rb:30:in `open'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_file_writer.rb:30:in `create_file'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb:71:in `create_mock_source_file'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock_generator.rb:47:in `create_mock'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock.rb:43:in `generate_mock'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock.rb:34:in `block in setup_mocks'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock.rb:33:in `each'
/vagrant/vendor/ceedling/vendor/cmock/lib/cmock.rb:33:in `setup_mocks'
/vagrant/vendor/ceedling/lib/ceedling/generator.rb:49:in `generate_mock'
/vagrant/vendor/ceedling/lib/ceedling/rules_cmock.rake:8:in `block in <top (required)>'
/vagrant/vendor/ceedling/lib/ceedling/task_invoker.rb:49:in `block in invoke_test_mocks'
/vagrant/vendor/ceedling/lib/ceedling/task_invoker.rb:49:in `invoke_test_mocks'
/vagrant/vendor/ceedling/lib/ceedling/preprocessinator.rb:23:in `preprocess_test_and_invoke_test_mocks'
/vagrant/vendor/ceedling/lib/ceedling/test_invoker.rb:42:in `block in setup_and_invoke'
/vagrant/vendor/ceedling/lib/ceedling/test_invoker.rb:32:in `setup_and_invoke'
/vagrant/vendor/ceedling/lib/ceedling/tasks_tests.rake:8:in `block (2 levels) in <top (required)>'
/var/lib/gems/1.9.1/gems/rake-11.2.2/exe/rake:27:in `<top (required)>'
Tasks: TOP => build/test/mocks/mock_i2c.c
(See full trace by running task with --trace)

--------------------
OVERALL TEST SUMMARY
--------------------

No tests executed.


vagrant@vagrant-ubuntu-trusty-64:/vagrant$

Parsing c function pointers

When trying to create a mock, this happened:
/CMock/lib/cmock_header_parser.rb:252:in `parse_declaration': Failed Parsing Declaration Prototype! (RuntimeError)
declaration: 'void(wakeup)(uint16_t ev, struct pico_socket *s)'
modifier: ''
return: {:type => '', :name => 'cmock_to_return', :ptr? => false, :const? => false, :str => ' cmock_to_return', :void? => false}
function: 'void'
args: [
{:type => '
wakeup)(uint16_t', :name => 'ev', :ptr? => true, :const? => false}
{:type => 'struct pico_socket*', :name => 's', :ptr? => true, :const? => false}
]

    from /home/x/Projects/CMock/lib/cmock_header_parser.rb:33:in `block in parse'
    from /home/x/Projects/CMock/lib/cmock_header_parser.rb:32:in `map'
    from /home/x/Projects/CMock/lib/cmock_header_parser.rb:32:in `parse'
    from ../../../CMock/lib/cmock.rb:40:in `generate_mock'
    from ../../../CMock/lib/cmock.rb:31:in `block in setup_mocks'
    from ../../../CMock/lib/cmock.rb:30:in `each'
    from ../../../CMock/lib/cmock.rb:30:in `setup_mocks'
    from ../../../CMock/lib/cmock.rb:85:in `<main>'

The header i used to mock was pico_socket.h from the picotcp repo (https://github.com/tass-belgium/picotcp)

It's failing on a function pointer declaration. Is CMock not able yet to handle function pointers?

Invalid byte sequence in UTF-8 parsing error

Hi all,

I get the following error when CMock attempts to parse a particular header file.

rake aborted!
invalid byte sequence in UTF-8
CMock/lib/cmock_header_parser.rb:51:in scan' CMock/lib/cmock_header_parser.rb:51:inimport_source'
CMock/lib/cmock_header_parser.rb:30:in parse' CMock/lib/cmock.rb:40:ingenerate_mock'
CMock/lib/cmock.rb:31:in block in setup_mocks' CMock/lib/cmock.rb:30:ineach'
CMock/lib/cmock.rb:30:in `setup_mocks'

I am using Ruby 1.9.3 and Ubuntu Linux. Surprisingly, the problem does not occur on a Windows machine.

Any ideas?

Valgrind still-reachable error

Hi all,

We have configured CMock to use dynamic memory in our environment because it ran out of memory when executing some tests in our codebase.

We are now running our unit tests under Valgrind (on Linux) and it always picks up an error like so -

==24766== HEAP SUMMARY:
==24766== in use at exit: 32,784 bytes in 1 blocks
==24766== total heap usage: 1 allocs, 0 frees, 32,784 bytes allocated
==24766==
==24766== 32,784 bytes in 1 blocks are still reachable in loss record 1 of 1
==24766== at 0x402BE18: malloc (vg_replace_malloc.c:270)
==24766== by 0x402BF9E: realloc (vg_replace_malloc.c:662)
==24766== by 0x804B839: CMock_Guts_MemNew (cmock.c:72)

Any idea why this could be happening?

No way to mock extern functions

Hi,

At line 116 of cmock_header_oarser.rb, I had to remove the extern keyword (and even the else branch) because it was not possible to mock something like:

extern void my_api(args...)

The above prototype is usually used when hardware/software I/F are provided and avoid linking unused API.

In my opinion, it is worth mocking extern functions.

Best regards;
Johan

returnThruPtr abuses constness

The returnThruPtr plugin generates the corresponding _ReturnThruPtr_ function for thins kind of prototype:

void my_func(my_type_t *param);

but does not for this

void my_func(const my_type_t *param);

nor this

void my_func(my_type_t *const param);

In the const my_type_t * case it seems right not to generate the mock function, since param is clearly not an output parameter. But the my_type_t *const case is different. Here we express the fact that the function cannot modify param, but it can modify *param, thus making it an output parameter.

Named nested parameters creates syntactically incorrect mocks

Mocking the following function:

void foo(void __stdcall * bar(int arg0));

creates the mock:

void foo(void __stdcall* bar(int arg0))
{
  UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;
  CMOCK_foo_CALL_INSTANCE* cmock_call_instance = (CMOCK_foo_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.foo_CallInstance);
  Mock.foo_CallInstance = CMock_Guts_MemNext(Mock.foo_CallInstance);
  UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "Function 'foo' called more times than expected.");
  cmock_line = cmock_call_instance->LineNumber;
  {
    UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_arg0)), (void*)(&arg0)), sizeof(void __stdcall* bar(int), cmock_line, "Function 'foo' called with unexpected value for argument 'arg0)'.");
  }
}

The line

UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_arg0)), (void*)(&arg0)), sizeof(void __stdcall* bar(int), cmock_line, "Function 'foo' called with unexpected value for argument 'arg0)'.");

Seems to have a misplaced paren, as the open/close match ends at UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(&cmock_call_instance->Expected_arg0)).

Issue with mocking an header file that uses hiredis

I have the following header file { http://pastebin.com/Pcbi6hYQ } . I want to mock it using cmock so that i can write unit test for 'Server.c' that uses the methods in the header file. But while compiling, i get the following message :

/tmp/ccGINIbW.o: In function `redisLibuvAttach':
TestServer.c:(.text+0x378): multiple definition of `redisLibuvAttach'
/tmp/cc1dEQsm.o:MockStore.c:(.text+0x229): first defined here
collect2: error: ld returned 1 exit status
make: *** [default] Error 1

'TestServer.c' is file that contains that unit tests. 'MockStore.c' is the file generated by cmock. I searched 'MockStore.c' for 'redisLibuvAttach', but found nothing by that name.

Mock segfault on incorrect expectations in test tearDown function

This was a tricky one! I was performing some very basic tests to make sure that a deInit() function was being cascaded from a top-layer module down to the layers below. CMock provided the lower-layer deInit() functions.

In my Unity tearDown() routine, I accidentally called "ExpectAndReturn" on the wrong functions (init instead of deInit) and provided a return value.

The test executable seg-faulted in one of the mocked deInit() functions, at the line:

cmock_line = cmock_call_instance->LineNumber;

gdb reported the value of cmock_call_instance was 0, so the mock was trying to dereference a null pointer.

While I'm still not certain exactly what in my test configuration caused CMock_Guts_GetAddressFor() to return null, and the segfault stopped once I started Expect-ing the correct functions, it strikes me that the cmock_call_instance should at least be null checked to return an error code instead of causing a segmentation fault.

Possible clue: The test only segfaulted when the incorrect expectations occurred in the tearDown() function. Moving the identical lines of code to the end of a unit test did not cause a segfault.

Mocks of functions with function pointer parameters generate CL.exe compiler warning C4054

Mocking the following function:

typedef void * __stdcall foofn (void);
void bar(foofn * arg0);

Will generate this

void bar(foofn* arg0)
{
  UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;
  CMOCK_bar_CALL_INSTANCE* cmock_call_instance = (CMOCK_bar_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.bar_CallInstance);
  Mock.bar_CallInstance = CMock_Guts_MemNext(Mock.bar_CallInstance);
  UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "Function 'bar' called more times than expected.");
  cmock_line = cmock_call_instance->LineNumber;
  {
    UNITY_TEST_ASSERT_EQUAL_MEMORY((void*)(cmock_call_instance->Expected_arg0), (void*)(arg0), sizeof(foofn), cmock_line, "Function 'bar' called with unexpected value for argument 'arg0'.");
  }
}

which casts a function pointer to a data pointer during the operation (void*)(arg0).

func_IgnoreAndReturn() always expects func to be called at least once?

Hi,

I'm using build version 2.0, build info 212 and I have the following yaml file:

:cmock:
:verbosity: 3
:plugins:
- 'ignore'
- 'ignore_arg'
- 'expect_any_args'
:includes:
- 'unity_fixture.h'
:mock_prefix: mock_
:mock_path: test/mocks
:treat_as_void: []

My test looks like this:
TEST_SETUP(some_group)
{
mock_foo_Init();
}

TEST_TEAR_DOWN(some_group)
{
mock_foo_Verify();
mock_foo_Destroy();
}

TEST(some_group, init_foo_not_called)
{
init_foo_IgnoreAndReturn(true);
}

TEST(some_group, init_foo_called_once)
{
init_foo_IgnoreAndReturn(true);
init_foo();
}

TEST(some_group, init_foo_called_twice)
{
init_foo_IgnoreAndReturn(true);
init_foo();
init_foo();
}

Results:

init_foo_not_called:FAIL: Function 'init_foo' called less times than expected.
init_foo_called_once -> PASS
init_foo_called_twice -> PASS

I'm looking for a way where 0 calls to init_foo() also passes the test.

Is this a bug, or do I need to do something else?

Ignore does not work with ReturnThrPtr when a mocked function has a void return type

I have a function that I would like to mock
void my_third_function(int * p_arg);

But in a test case:
...
int retval = 10;
my_third_function_Ignore();
my_third_function_ReturnThruPtr_p_arg(&retval);
...
I will get this
ReturnThruPtr called before Expect on 'my_third_function'..

The problem is in the generated code, which does not set up the call instance correctly:
void my_third_function_CMockIgnore(void)
{
Mock.my_third_function_IgnoreBool = (int)1;
}

Exception when Return_Thru_Ptr enabled

I enabled Return_Thru_Ptr and ran into an instance where a mock generated a memory protection exception. The problem appears to be that the cmock_call_instance data (setup in _CMockExpect) was not cleared resulting in the mock attempting to memcpy from a random location with a random length when called. This was fixed by editing the generated mock code and adding the line commented "/*added by CWS */" below:

X_CMockExpect(UNITY_LINE_TYPE cmock_line, , ...)
{
CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_CC_Execute_CALL_INSTANCE));
CMOCK_CC_Execute_CALL_INSTANCE* cmock_call_instance = (CMOCK_CC_Execute_CALL_INSTANCE_)CMock_Guts_GetAddressFor(cmock_guts_index);
/_added by CWS */ memset(cmock_call_instance, 0, sizeof(CMOCK_CC_Execute_CALL_INSTANCE));
UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "CMock has run out of memory. Please allocate more.");
Mock.CC_Execute_CallInstance = CMock_Guts_MemChain(Mock.CC_Execute_CallInstance, cmock_guts_index);
Mock.CC_Execute_IgnoreBool = (int)0;
cmock_call_instance->LineNumber = cmock_line;
cmock_call_instance->CallOrder = ++GlobalExpectCount;
CMockExpectParameters_CC_Execute(cmock_call_instance, ...);
}

Assert fix #24 removed from master

Hi

When having the same issue as handled in assert fix #24 (committed to master in 31ae10b, March 9 2014) I found that this fix - which seems to work as expected in my code - have been removed from the master (commit fcc6a40, March 17 2014) with the comment "resolved conflicts".

My questions is:

  • Has it been removed on purpose or is there something I should be aware of when using this fix?

Thanks.
/Steven

Suffix attributes not handled

Putting a token after the ) of a function definition causes cmock to fail to detect the signature, even if the token is listed in :attributes:. For example

void my_function(void) SUFFIX;

with this cmock.yml:

:cmock:
  :attributes:
    - SUFFIX

causes WARNING: No function prototypes found!. This is a problem since GCC attribute((...))'s are often placed after the function signature.

By looking at the code I discovered that adding SUFFIX to :strippables: does the trick, but it's not documented so I'm not sure if that is a supported use. Possibly the documentation just needs improvement to clarify what exactly attributes and strippables are for.

SyntaxError raised for cmock_header_parser.rb in Ruby 1.8

$ ruby lib/cmock.rb examples/src/AdcConductor.h
lib/cmock.rb:14:in require': /sandbox/kyleh/workspace/cmock/lib/cmock_header_parser.rb:51: syntax error, unexpected ':', expecting ')' (SyntaxError) ...9-1").encode("utf-8", replace: nil) if ($QUICK_RUBY_VERSION ... ^ from lib/cmock.rb:14 from lib/cmock.rb:7:ineach'
from lib/cmock.rb:7

Test fail due to expected parameter value mismatch

Hello,

First, thank you for providing such wonderful development tools.

I am having a odd issue that has been driving me bonkers for days. I'll start with my environment:

  • Windows 7 (64-bit)
  • gcc-4.6.2 running on MinGW (32-bit)
  • Ceedling:: 0.10.226
  • CExeption:: 1.2.16
  • CMock:: 2.0.212
  • Unity:: 2.1.0.118

Here is a helper function that will set up the mocks for writing a CRC16 value into my external flash chip:

void setupMocksForWritingFullStageImageCrc( uint16_t expectedCrc )
{
    //uint16_t crcValue = expectedCrc;
    uint16_t crcValue = 0xDEAD;
    flash_sectorErase_ExpectAndReturn( ADDRESS_FW_IMAGE_CRC_SECTOR, eFlash_Success );
    flash_writeDataBytes_ExpectAndReturn( crcAddress, sizeof( uint16_t ), (uint8_t *)&crcValue, eFlash_Success );
}

So I am expecting a flash sector erase then a call to write the CRC value to the external flash with a value of 0xDEAD. I hard-coded it to make sure I wasn't going crazy.

Here is the test summary output:

------------------------
FAILED UNIT TEST SUMMARY
------------------------
[test_FirmwareInit.c]
  Test: testInitBacksUpImageIfCrcCheckFails
  At line (113): "Element 0 Expected 0xC340 Was 0xDEAD. Function 'flash_writeDataBytes' called with unexpected value for argument 'data'."

As you can see, the function is being called and sending the correct value to the mock. But, even though I told it to expect 0xDEAD, it expects 0xC340 instead.

I should mention that I manually modified the mock function for flash_writeDataBytes to UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY instead of UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY and the data depth from 1 to 2 so that it will display the entire hex value.

I am going crazy here. Any help would be appreciated.

Thank you,

Alvin

infinite loop

This is a copy of an issue from the closed cmock-forum.

inital post:

I mocked printf and used IgnoreAndReturn. Since then the test loops and never finishs.

Every time I stop the execution in gdb it is somewhere in CMock_Guts_MemChain.

Program received signal SIGINT, Interrupt.
0x0000000000423728 in CMock_Guts_MemChain (root_index=8, obj_index=272)
at /home/sschwarz/dev/COR4114/tools/Cmock/src/cmock.c:116
116 index = (CMOCK_MEM_INDEX_TYPE)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE);
(gdb) where
#0 0x0000000000423728 in CMock_Guts_MemChain (root_index=8, obj_index=272)

at /home/sschwarz/dev/COR4114/tools/Cmock/src/cmock.c:116

#1 0x000000000040db0c in dbg_printf_CMockIgnoreAndReturn (cmock_line=55,

cmock_to_return=0 '\000')

(version is 2.0.203)

thx

first reply

Wow. that's a new one.

Can you post the function prototype you are using for printf (that is getting fed into the mock) and also the generated mock code? Out of curiosity, is that 32-bit or 64-it gcc? native?

Thanks

Mark

second reply

Hi Mark,

the prototype is:
uint8_t dbg_printf(const char* format, ...);

In my code I use macros like this to call it:

define DEBUG_PRINTF(...) dbg_printf(VA_ARGS)

The generated code is:
/* AUTOGENERATED FILE. DO NOT EDIT. */

include <string.h>

include <stdlib.h>

include <setjmp.h>

include "unity.h"

include "cmock.h"

include "Mockdebug.h"

typedef struct _CMOCK_dbg_setup_CALL_INSTANCE
{
UNITY_LINE_TYPE LineNumber;
int ReturnVal;

} CMOCK_dbg_setup_CALL_INSTANCE;

typedef struct _CMOCK_dbg_printf_CALL_INSTANCE
{
UNITY_LINE_TYPE LineNumber;
uint8_t ReturnVal;
char* Expected_format;

} CMOCK_dbg_printf_CALL_INSTANCE;

static struct MockdebugInstance
{
int dbg_setup_IgnoreBool;
int dbg_setup_FinalReturn;
CMOCK_dbg_setup_CALLBACK dbg_setup_CallbackFunctionPointer;
int dbg_setup_CallbackCalls;
CMOCK_MEM_INDEX_TYPE dbg_setup_CallInstance;
int dbg_printf_IgnoreBool;
uint8_t dbg_printf_FinalReturn;
CMOCK_dbg_printf_CALLBACK dbg_printf_CallbackFunctionPointer;
int dbg_printf_CallbackCalls;
CMOCK_MEM_INDEX_TYPE dbg_printf_CallInstance;
} Mock;

extern jmp_buf AbortFrame;

void Mockdebug_Verify(void)
{
UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;
if (Mock.dbg_setup_IgnoreBool)
Mock.dbg_setup_CallInstance = CMOCK_GUTS_NONE;
UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == Mock.dbg_setup_CallInstance, cmock_line, "Function 'dbg_setup' called less times than expected.");
if (Mock.dbg_setup_CallbackFunctionPointer != NULL)
Mock.dbg_setup_CallInstance = CMOCK_GUTS_NONE;
if (Mock.dbg_printf_IgnoreBool)
Mock.dbg_printf_CallInstance = CMOCK_GUTS_NONE;
UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == Mock.dbg_printf_CallInstance, cmock_line, "Function 'dbg_printf' called less times than expected.");
if (Mock.dbg_printf_CallbackFunctionPointer != NULL)
Mock.dbg_printf_CallInstance = CMOCK_GUTS_NONE;
}

void Mockdebug_Init(void)
{
Mockdebug_Destroy();
}

void Mockdebug_Destroy(void)
{
CMock_Guts_MemFreeAll();
memset(&Mock, 0, sizeof(Mock));
Mock.dbg_setup_CallbackFunctionPointer = NULL;
Mock.dbg_setup_CallbackCalls = 0;
Mock.dbg_printf_CallbackFunctionPointer = NULL;
Mock.dbg_printf_CallbackCalls = 0;
}

int dbg_setup(void)
{
UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;
CMOCK_dbg_setup_CALL_INSTANCE* cmock_call_instance = (CMOCK_dbg_setup_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.dbg_setup_CallInstance);
Mock.dbg_setup_CallInstance = CMock_Guts_MemNext(Mock.dbg_setup_CallInstance);
if (Mock.dbg_setup_IgnoreBool)
{
if (cmock_call_instance == NULL)
return Mock.dbg_setup_FinalReturn;
Mock.dbg_setup_FinalReturn = cmock_call_instance->ReturnVal;
return cmock_call_instance->ReturnVal;
}
if (Mock.dbg_setup_CallbackFunctionPointer != NULL)
{
return Mock.dbg_setup_CallbackFunctionPointer(Mock.dbg_setup_CallbackCalls++);
}
UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "Function 'dbg_setup' called more times than expected.");
cmock_line = cmock_call_instance->LineNumber;
return cmock_call_instance->ReturnVal;
}

void dbg_setup_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return)
{
CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_dbg_setup_CALL_INSTANCE));
CMOCK_dbg_setup_CALL_INSTANCE* cmock_call_instance = (CMOCK_dbg_setup_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);
UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "CMock has run out of memory. Please allocate more.");
Mock.dbg_setup_CallInstance = CMock_Guts_MemChain(Mock.dbg_setup_CallInstance, cmock_guts_index);
cmock_call_instance->LineNumber = cmock_line;
cmock_call_instance->ReturnVal = cmock_to_return;
Mock.dbg_setup_IgnoreBool = (int)1;
}

void dbg_setup_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return)
{
CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_dbg_setup_CALL_INSTANCE));
CMOCK_dbg_setup_CALL_INSTANCE* cmock_call_instance = (CMOCK_dbg_setup_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);
UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "CMock has run out of memory. Please allocate more.");
Mock.dbg_setup_CallInstance = CMock_Guts_MemChain(Mock.dbg_setup_CallInstance, cmock_guts_index);
cmock_call_instance->LineNumber = cmock_line;
cmock_call_instance->ReturnVal = cmock_to_return;
}

void dbg_setup_StubWithCallback(CMOCK_dbg_setup_CALLBACK Callback)
{
Mock.dbg_setup_CallbackFunctionPointer = Callback;
}

uint8_t dbg_printf(const char* format, ...)
{
UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;
CMOCK_dbg_printf_CALL_INSTANCE* cmock_call_instance = (CMOCK_dbg_printf_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.dbg_printf_CallInstance);
Mock.dbg_printf_CallInstance = CMock_Guts_MemNext(Mock.dbg_printf_CallInstance);
if (Mock.dbg_printf_IgnoreBool)
{
if (cmock_call_instance == NULL)
return Mock.dbg_printf_FinalReturn;
Mock.dbg_printf_FinalReturn = cmock_call_instance->ReturnVal;
return cmock_call_instance->ReturnVal;
}
if (Mock.dbg_printf_CallbackFunctionPointer != NULL)
{
return Mock.dbg_printf_CallbackFunctionPointer(format, Mock.dbg_printf_CallbackCalls++);
}
UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "Function 'dbg_printf' called more times than expected.");
cmock_line = cmock_call_instance->LineNumber;
UNITY_TEST_ASSERT_EQUAL_STRING(cmock_call_instance->Expected_format, format, cmock_line, "Function 'dbg_printf' called with unexpected value for argument 'format'.");
return cmock_call_instance->ReturnVal;
}

void CMockExpectParameters_dbg_printf(CMOCK_dbg_printf_CALL_INSTANCE* cmock_call_instance, const char* format)
{
cmock_call_instance->Expected_format = (char*)format;
}

void dbg_printf_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, uint8_t cmock_to_return)
{
CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_dbg_printf_CALL_INSTANCE));
CMOCK_dbg_printf_CALL_INSTANCE* cmock_call_instance = (CMOCK_dbg_printf_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);
UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "CMock has run out of memory. Please allocate more.");
Mock.dbg_printf_CallInstance = CMock_Guts_MemChain(Mock.dbg_printf_CallInstance, cmock_guts_index);
cmock_call_instance->LineNumber = cmock_line;
cmock_call_instance->ReturnVal = cmock_to_return;
Mock.dbg_printf_IgnoreBool = (int)1;
}

void dbg_printf_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, const char* format, uint8_t cmock_to_return)
{
CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_dbg_printf_CALL_INSTANCE));
CMOCK_dbg_printf_CALL_INSTANCE* cmock_call_instance = (CMOCK_dbg_printf_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index);
UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "CMock has run out of memory. Please allocate more.");
Mock.dbg_printf_CallInstance = CMock_Guts_MemChain(Mock.dbg_printf_CallInstance, cmock_guts_index);
cmock_call_instance->LineNumber = cmock_line;
CMockExpectParameters_dbg_printf(cmock_call_instance, format);
cmock_call_instance->ReturnVal = cmock_to_return;
}

void dbg_printf_StubWithCallback(CMOCK_dbg_printf_CALLBACK Callback)
{
Mock.dbg_printf_CallbackFunctionPointer = Callback;
}

And the header:
/* AUTOGENERATED FILE. DO NOT EDIT. */

ifndef _MOCKDEBUG_H

define _MOCKDEBUG_H

include "debug.h"

void Mockdebug_Init(void);
void Mockdebug_Destroy(void);
void Mockdebug_Verify(void);

define dbg_setup_IgnoreAndReturn(cmock_retval) dbg_setup_CMockIgnoreAndReturn(LINE, cmock_retval)

void dbg_setup_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return);

define dbg_setup_ExpectAndReturn(cmock_retval) dbg_setup_CMockExpectAndReturn(LINE, cmock_retval)

void dbg_setup_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int cmock_to_return);
typedef int (* CMOCK_dbg_setup_CALLBACK)(int cmock_num_calls);
void dbg_setup_StubWithCallback(CMOCK_dbg_setup_CALLBACK Callback);

define dbg_printf_IgnoreAndReturn(cmock_retval) dbg_printf_CMockIgnoreAndReturn(LINE, cmock_retval)

void dbg_printf_CMockIgnoreAndReturn(UNITY_LINE_TYPE cmock_line, uint8_t cmock_to_return);

define dbg_printf_ExpectAndReturn(format, cmock_retval) dbg_printf_CMockExpectAndReturn(LINE, format, cmock_retval)

void dbg_printf_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, const char* format, uint8_t cmock_to_return);
typedef uint8_t (* CMOCK_dbg_printf_CALLBACK)(const char* format, int cmock_num_calls);
void dbg_printf_StubWithCallback(CMOCK_dbg_printf_CALLBACK Callback);

endif

It's 64bit:
gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6.1/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.1-9ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)

third reply

Hmmm... That code looks right. Are you using the ruby scripts to generate a test runner for you? Can you verify that it is calling CMock_Init() and that function is calling Mockdebug_Init? I'm wondering if the Mock structure isn't getting cleared so that it's just following random memory locations or something? It seems unlikely, but maybe?

It's interesting that it's a function with a vararg that is giving you headaches, but at this point CMock just ignores the extra arguments (someday it will mock them... but not yet). Have you tried a different function in the same module? Does your dbg_setup have the same problem?

Thanks... sorry that I don't have any quick answers... hopefully we can work through this together.

Mark

rest

I was in vacation last week - sorry for the delay. Answer to your last post will follow soon.

cmock_header_parser.rb parsing problem with extern "C"

I hit to an issue that mock generation misses the first function in the header in case there is declaration

extern "C"{ in the beginning.

It seems that the parser requires whitespace between the " and {. The below patch fixed the issue for me.

Index: lib/cmock_header_parser.rb
===================================================================
--- lib/cmock_header_parser.rb  (revision 4699)
+++ lib/cmock_header_parser.rb  (working copy)
@@ -71,7 +71,7 @@

     # remove preprocessor statements and extern "C"
     source.gsub!(/^\s*#.*/, '')
-    source.gsub!(/extern\s+\"C\"\s+\{/, '')
+    source.gsub!(/extern\s+\"C\"\s*\{/, '')

     # enums, unions, structs, and typedefs can all contain things (e.g. function pointers) that parse like function prototypes, so yank them
     # forward declared structs are removed before struct definitions so they don't mess up real thing later. we leave structs keywords in function prototypes

[PATCH] Return through pointer arguments

As discussed at http://throwtheswitch.org/white-papers/cmock-pointers-and-structs.html, CMock doesn't provide a way for mocks to modify the data pointed to by pointer arguments. This makes it impossible to mock functions that return data through pointers. That article discusses workarounds, but they all assume that you have control over the API of the function in question. Sometimes, you don't.

I've developed a patch to add this ability to CMock: [EDIT: Link removed due to bugs. In a later comment I posted a link to a fixed version with additional features]

The patch adds a plugin, return_thru_ptr. When this plugin is enabled, additional macros are generated for each function's pointer arguments which allow you to specify data to be copied onto the target of that pointer by the mock. For example, for a function with the prototype void ptr_ret_int(int *r), the following macros are created:

void ptr_ret_int_ReturnThruPtr_r(int *r)
void ptr_ret_int_ReturnArrayThruPtr_r(int *r, int len)
void ptr_ret_int_ReturnMemThruPtr_r(int *r, int size)

These functions can be called after one of the Expect family of calls to give the most recently defined expectation a value to return through a pointer argument.

ReturnThruPtr arranges for a single value to be copied onto the target of the pointer argument.
ReturnArrayThruPtr arranges for an array of values, with a length specified by len, to be copied.
ReturnMemThruPtr arranges for a memory buffer, with a size specified in bytes, to be copied.

Here is an example of a test that exercises ReturnThruPtr for a function void ptr_ret_ints(int *r, int *s):

{
    int r, s = 0x0880AA55;
    int r_res = 4;
    int s_res = 6;

    Mock_ptr_ret_Init();

    ptr_ret_ints_Expect(&r, &s);
    ptr_ret_ints_ReturnThruPtr_r(&r_res);
    ptr_ret_ints_ReturnThruPtr_s(&s_res);

    ptr_ret_ints(&r, &s);

    Mock_ptr_ret_Verify();
    TEST_ASSERT_EQUAL(4, r);
    TEST_ASSERT_EQUAL(6, s);
}

Usage Notes

The expectation object created by these calls only stores a pointer to the memory to be copied, so it's important that the memory, in this case r_res and s_res, not be modified between the calls to ReturnThruPtr and the call to the mocked function.

ReturnThruPtr functions must be called after the Expect calls they modify. A ReturnThruPtr call before any Expect calls will result in undefined behavior.

return_thru_ptr doesn't work with the ignore plugin. It only properly returns through pointer arguments when the expectation was created with an Expect call.

Implementation Notes

The CMock plugin architecture isn't quite flexible enough to support implementing this feature entirely within the plugin class file. Since there's no structured way to add additional constructor code to expectations, I had to hack cm_utils.code_add_argument_loader to detect the presence of the return_thru_ptr plugin and add initialization of the ReturnThruPtr_..._Used fields, using the same technique that code_add_argument_loader already used to hack in support for the array plugin.

While incomplete types won't prevent mocks from being generated or compiled with return_thru_ptr enabled, they will present an obstacle for anyone wanting to actually use the plugin to pass data through an incompletely typed argument. This can be worked around with ReturnMemThruPtr but requires hard-coding the size of the abstract type, which is very dangerous and brittle. A better solution is to use preprocessor magic to make sure that the type is complete when compiling the test harness.

Interesting issue with Rake

I run bundle exec rake from Windows and get the following. It appears to try and access a non-existent file.


C:\>bundle install --gemfile Gemfile
Using rake 10.5.0
Using constructor 2.0.0
Using minitest 5.8.4
Using require_all 1.3.3
Using bundler 1.11.2
Using diy 1.1.2
Bundle complete! 6 Gemfile dependencies, 6 gems now installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.

C:\> bundle exec rake
....
....
C:/Ruby22/bin/ruby.exe -I"lib" -I"C:/Ruby22/lib/ruby/gems/2.2.0/gems/rake-10.5.0/lib" "C:/Ruby22/lib/ruby/gems/2.2.0/gems/rake-10.5.0/lib/rake/rake_test_loader.rb" "test/unit/*_test.rb"
Run options: --seed 49888

# Running:

.........................................................................................................................................................................................................................................

Finished in 0.112229s, 2076.1060 runs/s, 2833.4837 assertions/s.

233 runs, 318 assertions, 0 failures, 0 errors, 0 skips

----------------
UNIT TEST C CODE
----------------

Testing test/c/TestCMockC
(TEST, CMOCK_MEM_STATIC, CMOCK_MEM_SIZE=128, CMOCK_MEM_ALIGN=2, CMOCK_MEM_INDEX_TYPE=int)
rake aborted!
Errno::ENOENT: No such file or directory - gcc -DCMOCK -DUNITY_SUPPORT_64 -DCMOCK_MEM_INDEX_TYPE=int -DCMOCK_MEM_ALIGN=2 -DCMOCK_MEM_SIZE=128 -DCMOCK_MEM_STATIC -DTEST -c -Wall -Wextra -Wunused-parameter -Wno-address -Wno-invalid-token-paste -std=c99 -pedantic -O0 -Itest/system/generated/ -Iexamples/test/ -Itest/system/generated/ -Isrc/ -Ivendor/unity/src/ -Ivendor/c_exception/lib/ -Itest/system/test_compilation/ -Itest/ src/cmock.c -otest/system/build/cmock.o
....
....
....
Tasks: TOP => default => test => test:c
(See full trace by running task with --trace)

header_parser crashes on particular inline functions

The cmock_header_parser.rb script has some serious problems parsing nested braces, and it's causing some issues with inline functions:

If I declare an inline function with internal control blocks surrounded by braces (see below), then call a function from within the inline function, the parser crashes at cmock_header_parser.rb:264, as it can't resolve the type of the return.

To reproduce:
Run cmock on the following header file:

#ifndef TEST_H__
#define TEST_H__

static inline void test(int arg1, int arg2)
{
    if (arg1 == arg2)
    {
        return;
    }

    test_func2(arg1, arg2);
}

#endif

This triggers the exception at cmock_header_parser.rb:264 with the following output:

  declaration: 'test_func2(arg1, arg2)'
  modifier: ''
  return: {:type => '', :name => 'cmock_to_return', :ptr? => false, :const? => false, :str => ' cmock_to_return', :void? => false}
  function: 'test_func2'
  args: [
    {:type => 'arg1', :name => 'cmock_arg1', :ptr? => false, :const? => false}
    {:type => 'arg2', :name => 'cmock_arg2', :ptr? => false, :const? => false}
  ]

        from cmock/lib/cmock_header_parser.rb:33:in `block in parse'
        from cmock/lib/cmock_header_parser.rb:32:in `map'
        from cmock/lib/cmock_header_parser.rb:32:in `parse'
        from cmock/lib/cmock.rb:43:in `generate_mock'
        from cmock/lib/cmock.rb:34:in `block in setup_mocks'
        from cmock/lib/cmock.rb:33:in `each'
        from cmock/lib/cmock.rb:33:in `setup_mocks'
        from cmock/lib/cmock.rb:88:in `<main>'

The regexes in the cmock_header_parser.rb function import_source(source) are quite sloppy in general, mostly because they don't handle nested braces very well, and it relies on the functions after it to clean up. This particular issue could be solved by checking each potential function declaration for returns in parse_functions(source), or ignoring functions violating the conditional at L262, but that just seems like a work-around.

CMock fails to generate mock when marcos are used to create function declarations

When trying to generate a mock form a header file I am getting a runtime error. The header file uses a macro to generate function declarations.

Header file:

#define DECLARE_FUNCTION(ID) int Test##ID();
DECLARE_FUNCTION(55)

CMock error:

cmock/lib/cmock_header_parser.rb:263:in `parse_declaration': Failed Parsing Declaration Prototype! (RuntimeError)
  declaration: 'DECLARE_FUNCTION(55)'
  modifier: ''
  return: {:type => '', :name => 'cmock_to_return', :ptr? => false, :const? => false, :str => ' cmock_to_return', :void? => false}
  function: 'DECLARE_FUNCTION'
  args: [{:type => '55', :name => 'cmock_arg1', :ptr? => false, :const? => false}]
        from cmock/lib/cmock_header_parser.rb:33:in `block in parse'
        from cmock/lib/cmock_header_parser.rb:32:in `map'
        from cmock/lib/cmock_header_parser.rb:32:in `parse'
        from cmock/lib/cmock.rb:43:in `generate_mock'
        from cmock/lib/cmock.rb:34:in `block in setup_mocks'
        from cmock/lib/cmock.rb:33:in `each'
        from cmock/lib/cmock.rb:33:in `setup_mocks'
        from cmock/lib/cmock.rb:88:in `<main>'

This header causes no problems for the compiler (gcc). Running it through the preprocessor results in the following which CMock will correctly generate a mock from.

int Test55();

Suggestion: Stub with callback - reset on next Expect

When calling the <mock_name>_StubWithCallback(cb), I have to manually do another call <mock_name>_StubWithCallback(NULL) to be able to run my next ExpectAndReturn.

In some cases I use the stub as a special case for when I want to check for behavior specific to a single case, then switch back to regular, generated mocks. The regular Expect-functions will not be executed unless I disable the callback with the NULL-call, which seems a bit counter intuitive.

I think it makes sense to implicitly disable the callback if you call an expect or ignore function, is there any counter-argument I'm missing?

Dereferencing type-punned pointer warning

Compiling CMock with GCC and the following warnings throws strict-aliasing warning.

gcc  -g -O0 -Wall -Werror -Wextra -Wcast-align -Wcast-qual -Wconversion -Wdisabled-optimization -Wdouble-promotion -Wflo
at-equal -Wformat=2 -Winit-self -Winline -Winvalid-pch -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wmiss
ing-prototypes -Wnonnull -Wpacked -Wpointer-arith -Wredundant-decls -Wswitch-default -Wstrict-aliasing -Wstrict-overflow
=5 -Wsuggest-attribute=const -Wuninitialized -Wmaybe-uninitialized -Wunused -Wunreachable-code -Wreturn-type -Wshadow -W
undef -Wwrite-strings -Wno-missing-declarations -Wno-missing-prototypes -Wno-nested-externs -Wno-redundant-decls -Wno-un
used-parameter -Wno-variadic-macros -fms-extensions -fno-omit-frame-pointer -ffloat-store -fno-common -fstrict-aliasing
-std=gnu99 -Wbad-function-cast -o obj/cmock.o -ICMock/ -c cmock.c
cmock.c: In function 'CMock_Guts_MemNew':
cmock.c:77:3: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
cc1.exe: all warnings being treated as errors
Compilation of cmock.c failed!

"unused variable 'cmock_line' warning fix" no longer creates armcc compilable code

Hi,

After the following commit:
May 6, 8bd739e
Fixed 'unused variable `cmock_line' compiler warning. Warning was produced by generated code for functions without args.

CMock no longer creates compilable code for Armcc v5.04 (using uVision 5 IDE, similar to IAR workbench):

bool init_module(..)
{
UNITY_LINE_TYPE cmock_line;
cmock_line = TEST_LINE_NUM;
CMOCK_init_module_CALL_INSTANCE* cmock_call_instance = ...

error: (): error: #268: declaration may not appear after executable statement in block.

A fix for this would be to either solve the compiler warning in a different way (e.g. prefixing variable with (void)), or to move the statement "cmock_line = TEST_LINE_NUM;" after all variable declarations in the mocked function.

Memory freeing behavior

I have a function I'm testing that calls a mocked function lots of times. I tried using Expect in a loop, but I get an error that CMock has run out of memory. Consider the following code:

for(;;)
{
    mocked_function_Expect();
    mocked_function();
}

I would expect the mocked_function_Expect() call to use some memory, but I expected that to be freed when the actual function is called. However, it looks like the memory is only freed after the entire test is finished. Is that actually true, and if so, why does it work like that?

Of course, in the example above, the Expect doesn't seem useful, but in my actual test there is also a ReturnThruPtr, so it becomes necessary.

CMock does not create compilable code for functions that return a struct

I am trying to mock a piece of code that has a function that returns a struct directly (not via a pointer). The problem is that CMock generates a function that returns the value, but casts the return which causes a compile error.

So I have the following example code in myHeader.h:

typedef struct
{
    uint8 x;
    uint8 y;
    uint8 z;
} tMyStruct;

tMyStruct myFunc( void );

This generates the following mocked function:

tMyStruct myFunc(void)
{
  UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM;
  CMOCK_myFunc_CALL_INSTANCE* cmock_call_instance = (CMOCK_myFunc_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.myFunc_CallInstance);
  Mock.myFunc_CallInstance = CMock_Guts_MemNext(Mock.myFunc_CallInstance);
  if (Mock.myFunc_IgnoreBool)
  {
    if (cmock_call_instance == NULL)
      return (tMyStruct)Mock.myFunc_FinalReturn;
    memcpy(&Mock.myFunc_FinalReturn, &cmock_call_instance->ReturnVal, sizeof(tMyStruct));
    return (tMyStruct)cmock_call_instance->ReturnVal;
  }
  UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, "Function 'myFunc' called more times than expected.");
  cmock_line = cmock_call_instance->LineNumber;
  return cmock_call_instance->ReturnVal;
}

This will fail to compile in IAR with the error cast to type "tMyStruct" is not allowed.

Oddly it seems that the mocks structures contain the correct type for the return value anyway so don't actually need to be cast. I can get around the error in fact by removing the cast from the offending code. Does the cast need to be done at all?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.