summaryrefslogtreecommitdiffstats
path: root/tinyusb/test/vendor/ceedling/plugins/fake_function_framework
diff options
context:
space:
mode:
authorJoey Castillo <jose.castillo@gmail.com>2021-08-28 12:50:18 -0400
committerJoey Castillo <jose.castillo@gmail.com>2021-08-28 12:50:18 -0400
commit39a5c822a2a2e798e2e39ff8a98b7af84253026c (patch)
treefa157c98d3aea0d4f996e4415aa2a7ad1093ac05 /tinyusb/test/vendor/ceedling/plugins/fake_function_framework
parentc9e00b83bbdcb05058806d915ec4fff3cf4e596f (diff)
downloadSensor-Watch-39a5c822a2a2e798e2e39ff8a98b7af84253026c.tar.gz
Sensor-Watch-39a5c822a2a2e798e2e39ff8a98b7af84253026c.tar.bz2
Sensor-Watch-39a5c822a2a2e798e2e39ff8a98b7af84253026c.zip
add tinyusb
Diffstat (limited to 'tinyusb/test/vendor/ceedling/plugins/fake_function_framework')
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/README.md250
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/Rakefile19
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/project.yml71
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/rakefile.rb7
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.c1
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.h14
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/custom_types.h6
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.c7
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.h16
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.c93
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.h11
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.c16
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.h8
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.c1
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.h6
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_event_processor.c155
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_foo.c47
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fake_function_framework.rb87
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fff_mock_generator.rb163
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_header_generator_spec.rb304
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_source_generator_spec.rb149
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/header_generator.rb51
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/spec_helper.rb96
-rwxr-xr-xtinyusb/test/vendor/ceedling/plugins/fake_function_framework/src/fff_unity_helper.h33
24 files changed, 1611 insertions, 0 deletions
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/README.md b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/README.md
new file mode 100755
index 00000000..8042775e
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/README.md
@@ -0,0 +1,250 @@
+# A Fake Function Framework Plug-in for Ceedling
+
+This is a plug-in for [Ceedling](https://github.com/ThrowTheSwitch/Ceedling) to use the [Fake Function Framework](https://github.com/meekrosoft/fff) for mocking instead of CMock.
+
+Using fff provides less strict mocking than CMock, and allows for more loosely-coupled tests.
+And, when tests fail -- since you get the actual line number of the failure -- it's a lot easier to figure out what went wrong.
+
+## Installing the plug-in
+
+To use the plugin you need to 1) get the contents of this repo and 2) configure your project to use it.
+
+### Get the source
+
+The easiest way to get the source is to just clone this repo into the Ceedling plugin folder for your existing Ceedling project.
+(Don't have a Ceedling project already? [Here are instructions to create one.](http://www.electronvector.com/blog/try-embedded-test-driven-development-right-now-with-ceedling))
+From within `<your-project>/vendor/ceedling/plugins`, run:
+
+`git clone https://github.com/ElectronVector/fake_function_framework.git`
+
+This will create a new folder named `fake_function_framework` in the plugins folder.
+
+### Enable the plug-in.
+
+The plug-in is enabled from within your project.yml file.
+
+In the `:plugins` configuration, add `fake_function_framework` to the list of enabled plugins:
+
+```yaml
+:plugins:
+ :load_paths:
+ - vendor/ceedling/plugins
+ :enabled:
+ - stdout_pretty_tests_report
+ - module_generator
+ - fake_function_framework
+```
+*Note that you could put the plugin source in some other loaction.
+In that case you'd need to add a new path the `:load_paths`.*
+
+## How to use it
+
+You use fff with Ceedling the same way you used to use CMock.
+Modules can still be generated with the default module generator: `rake module:create[my_module]`.
+If you want to "mock" `some_module.h` in your tests, just `#include "mock_some_module.h"`.
+This creates a fake function for each of the functions defined in `some_module.h`.
+
+The name of each fake is the original function name with an appended `_fake`.
+For example, if we're generating fakes for a stack module with `push` and `pop` functions, we would have the fakes `push_fake` and `pop_fake`.
+These fakes are linked into our test executable so that any time our unit under test calls `push` or `pop` our fakes are called instead.
+
+Each of these fakes is actually a structure containing information about how the function was called, and what it might return.
+We can use Unity to inspect these fakes in our tests, and verify the interactions of our units.
+There is also a global structure named `fff` which we can use to check the sequence of calls.
+
+The fakes can also be configured to return particular values, so you can exercise the unit under test however you want.
+
+The examples below explain how to use fff to test a variety of module interactions.
+Each example uses fakes for a "display" module, created from a display.h file with `#include "mock_display.h"`. The `display.h` file must exist and must contain the prototypes for the functions to be faked.
+
+### Test that a function was called once
+
+```c
+void
+test_whenTheDeviceIsReset_thenTheStatusLedIsTurnedOff()
+{
+ // When
+ event_deviceReset();
+
+ // Then
+ TEST_ASSERT_EQUAL(1, display_turnOffStatusLed_fake.call_count);
+}
+```
+
+### Test that a function was NOT called
+
+```c
+void
+test_whenThePowerReadingIsLessThan5_thenTheStatusLedIsNotTurnedOn(void)
+{
+ // When
+ event_powerReadingUpdate(4);
+
+ // Then
+ TEST_ASSERT_EQUAL(0, display_turnOnStatusLed_fake.call_count);
+}
+```
+
+## Test that a single function was called with the correct argument
+
+```c
+void
+test_whenTheVolumeKnobIsMaxed_thenVolumeDisplayIsSetTo11(void)
+{
+ // When
+ event_volumeKnobMaxed();
+
+ // Then
+ TEST_ASSERT_EQUAL(1, display_setVolume_fake.call_count);
+ TEST_ASSERT_EQUAL(11, display_setVolume_fake.arg0_val);
+}
+```
+
+## Test that calls are made in a particular sequence
+
+```c
+void
+test_whenTheModeSelectButtonIsPressed_thenTheDisplayModeIsCycled(void)
+{
+ // When
+ event_modeSelectButtonPressed();
+ event_modeSelectButtonPressed();
+ event_modeSelectButtonPressed();
+
+ // Then
+ TEST_ASSERT_EQUAL_PTR((void*)display_setModeToMinimum, fff.call_history[0]);
+ TEST_ASSERT_EQUAL_PTR((void*)display_setModeToMaximum, fff.call_history[1]);
+ TEST_ASSERT_EQUAL_PTR((void*)display_setModeToAverage, fff.call_history[2]);
+}
+```
+
+## Fake a return value from a function
+
+```c
+void
+test_givenTheDisplayHasAnError_whenTheDeviceIsPoweredOn_thenTheDisplayIsPoweredDown(void)
+{
+ // Given
+ display_isError_fake.return_val = true;
+
+ // When
+ event_devicePoweredOn();
+
+ // Then
+ TEST_ASSERT_EQUAL(1, display_powerDown_fake.call_count);
+}
+```
+
+## Fake a function with a value returned by reference
+
+```c
+void
+test_givenTheUserHasTypedSleep_whenItIsTimeToCheckTheKeyboard_theDisplayIsPoweredDown(void)
+{
+ // Given
+ char mockedEntry[] = "sleep";
+ void return_mock_value(char * entry, int length)
+ {
+ if (length > strlen(mockedEntry))
+ {
+ strncpy(entry, mockedEntry, length);
+ }
+ }
+ display_getKeyboardEntry_fake.custom_fake = return_mock_value;
+
+ // When
+ event_keyboardCheckTimerExpired();
+
+ // Then
+ TEST_ASSERT_EQUAL(1, display_powerDown_fake.call_count);
+}
+```
+
+## Fake a function with a function pointer parameter
+
+```
+void
+test_givenNewDataIsAvailable_whenTheDisplayHasUpdated_thenTheEventIsComplete(void)
+{
+ // A mock function for capturing the callback handler function pointer.
+ void(*registeredCallback)(void) = 0;
+ void mock_display_updateData(int data, void(*callback)(void))
+ {
+ //Save the callback function.
+ registeredCallback = callback;
+ }
+ display_updateData_fake.custom_fake = mock_display_updateData;
+
+ // Given
+ event_newDataAvailable(10);
+
+ // When
+ if (registeredCallback != 0)
+ {
+ registeredCallback();
+ }
+
+ // Then
+ TEST_ASSERT_EQUAL(true, eventProcessor_isLastEventComplete());
+}
+```
+
+## Helper macros
+
+For convenience, there are also some helper macros that create new Unity-style asserts:
+
+- `TEST_ASSERT_CALLED(function)`: Asserts that a function was called once.
+- `TEST_ASSERT_NOT_CALLED(function)`: Asserts that a function was never called.
+- `TEST_ASSERT_CALLED_TIMES(times, function)`: Asserts that a function was called a particular number of times.
+- `TEST_ASSERT_CALLED_IN_ORDER(order, function)`: Asserts that a function was called in a particular order.
+
+Here's how you might use one of these instead of simply checking the call_count value:
+
+```c
+void
+test_whenTheDeviceIsReset_thenTheStatusLedIsTurnedOff()
+{
+ // When
+ event_deviceReset();
+
+ // Then
+ // This how to directly use fff...
+ TEST_ASSERT_EQUAL(1, display_turnOffStatusLed_fake.call_count);
+ // ...and this is how to use the helper macro.
+ TEST_ASSERT_CALLED(display_turnOffStatusLed);
+}
+```
+
+## Test setup
+
+All of the fake functions, and any fff global state are all reset automatically between each test.
+
+## CMock configuration
+
+Use still use some of the CMock configuration options for setting things like the mock prefix, and for including additional header files in the mock files.
+
+```yaml
+:cmock:
+ :mock_prefix: mock_
+ :includes:
+ -
+ :includes_h_pre_orig_header:
+ -
+ :includes_h_post_orig_header:
+ -
+ :includes_c_pre_header:
+ -
+ :includes_c_post_header:
+```
+
+## Running the tests
+
+There are unit and integration tests for the plug-in itself.
+These are run with the default `rake` task.
+The integration test runs the tests for the example project in examples/fff_example.
+For the integration tests to succeed, this repository must be placed in a Ceedling tree in the plugins folder.
+
+## More examples
+
+There is an example project in examples/fff_example.
+It shows how to use the plug-in with some full-size examples.
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/Rakefile b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/Rakefile
new file mode 100755
index 00000000..bc559411
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/Rakefile
@@ -0,0 +1,19 @@
+require 'rake'
+require 'rspec/core/rake_task'
+
+desc "Run all rspecs"
+RSpec::Core::RakeTask.new(:spec) do |t|
+ t.pattern = Dir.glob('spec/**/*_spec.rb')
+ t.rspec_opts = '--format documentation'
+ # t.rspec_opts << ' more options'
+end
+
+desc "Run integration test on example"
+task :integration_test do
+ chdir("./examples/fff_example") do
+ sh "rake clobber"
+ sh "rake test:all"
+ end
+end
+
+task :default => [:spec, :integration_test] \ No newline at end of file
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/project.yml b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/project.yml
new file mode 100755
index 00000000..6bda2229
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/project.yml
@@ -0,0 +1,71 @@
+---
+
+# Notes:
+# Sample project C code is not presently written to produce a release artifact.
+# As such, release build options are disabled.
+# This sample, therefore, only demonstrates running a collection of unit tests.
+
+:project:
+ :use_exceptions: FALSE
+ :use_test_preprocessor: TRUE
+ :use_auxiliary_dependencies: TRUE
+ :build_root: build
+# :release_build: TRUE
+ :test_file_prefix: test_
+
+#:release_build:
+# :output: MyApp.out
+# :use_assembly: FALSE
+
+:environment:
+
+:extension:
+ :executable: .out
+
+:paths:
+ :test:
+ - +:test/**
+ :source:
+ - src/**
+ :support:
+
+:defines:
+ # in order to add common defines:
+ # 1) remove the trailing [] from the :common: section
+ # 2) add entries to the :common: section (e.g. :test: has TEST defined)
+ :commmon: &common_defines []
+ :test:
+ - *common_defines
+ - TEST
+ :test_preprocess:
+ - *common_defines
+ - TEST
+
+:cmock:
+ :mock_prefix: mock_
+ :when_no_prototypes: :warn
+ :enforce_strict_ordering: TRUE
+ :plugins:
+ - :ignore
+ - :callback
+ :treat_as:
+ uint8: HEX8
+ uint16: HEX16
+ uint32: UINT32
+ int8: INT8
+ bool: UINT8
+
+#:tools:
+# Ceedling defaults to using gcc for compiling, linking, etc.
+# As [:tools] is blank, gcc will be used (so long as it's in your system path)
+# See documentation to configure a given toolchain for use
+
+:plugins:
+ :load_paths:
+ # This change from the default is for running Ceedling out of another folder.
+ - ../../../../plugins
+ :enabled:
+ - stdout_pretty_tests_report
+ - module_generator
+ - fake_function_framework
+...
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/rakefile.rb b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/rakefile.rb
new file mode 100755
index 00000000..e484d5fb
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/rakefile.rb
@@ -0,0 +1,7 @@
+# This change from the default is for running Ceedling out of another folder.
+PROJECT_CEEDLING_ROOT = "../../../.."
+load "#{PROJECT_CEEDLING_ROOT}/lib/ceedling.rb"
+
+Ceedling.load_project
+
+task :default => %w[ test:all release ]
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.c b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.c
new file mode 100755
index 00000000..6a403234
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.c
@@ -0,0 +1 @@
+#include "bar.h"
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.h b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.h
new file mode 100755
index 00000000..febc5865
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/bar.h
@@ -0,0 +1,14 @@
+#ifndef bar_H
+#define bar_H
+
+#include "custom_types.h"
+
+void bar_turn_on(void);
+void bar_print_message(const char * message);
+void bar_print_message_formatted(const char * format, ...);
+void bar_numbers(int one, int two, char three);
+void bar_const_test(const char * a, char * const b, const int c);
+custom_t bar_needs_custom_type(void);
+const char * bar_return_const_ptr(int one);
+
+#endif // bar_H
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/custom_types.h b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/custom_types.h
new file mode 100755
index 00000000..b426b32c
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/custom_types.h
@@ -0,0 +1,6 @@
+#ifndef custom_types_H
+#define custom_types_H
+
+typedef int custom_t;
+
+#endif
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.c b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.c
new file mode 100755
index 00000000..2f03449b
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include "display.h"
+
+void display_turnOffStatusLed(void)
+{
+ printf("Display: Status LED off");
+} \ No newline at end of file
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.h b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.h
new file mode 100755
index 00000000..def29960
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/display.h
@@ -0,0 +1,16 @@
+#include <stdbool.h>
+
+void display_turnOffStatusLed(void);
+void display_turnOnStatusLed(void);
+void display_setVolume(int level);
+void display_setModeToMinimum(void);
+void display_setModeToMaximum(void);
+void display_setModeToAverage(void);
+bool display_isError(void);
+void display_powerDown(void);
+void display_updateData(int data, void(*updateCompleteCallback)(void));
+
+/*
+ The entry is returned (up to `length` bytes) in the provided `entry` buffer.
+*/
+void display_getKeyboardEntry(char * entry, int length);
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.c b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.c
new file mode 100755
index 00000000..916a9236
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.c
@@ -0,0 +1,93 @@
+/*
+ This module implements some business logic to test.
+
+ Signal events by calling the functions on the module.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "event_processor.h"
+#include "display.h"
+
+void event_deviceReset(void)
+{
+ //printf ("Device reset\n");
+ display_turnOffStatusLed();
+}
+
+void event_volumeKnobMaxed(void)
+{
+ display_setVolume(11);
+}
+
+void event_powerReadingUpdate(int powerReading)
+{
+ if (powerReading >= 5)
+ {
+ display_turnOnStatusLed();
+ }
+}
+
+void event_modeSelectButtonPressed(void)
+{
+ static int mode = 0;
+
+ if (mode == 0)
+ {
+ display_setModeToMinimum();
+ mode++;
+ }
+ else if (mode == 1)
+ {
+ display_setModeToMaximum();
+ mode++;
+ }
+ else if (mode == 2)
+ {
+ display_setModeToAverage();
+ mode++;
+ }
+ else
+ {
+ mode = 0;
+ }
+}
+
+void event_devicePoweredOn(void)
+{
+ if (display_isError())
+ {
+ display_powerDown();
+ }
+}
+
+void event_keyboardCheckTimerExpired(void)
+{
+ char userEntry[100];
+
+ display_getKeyboardEntry(userEntry, 100);
+
+ if (strcmp(userEntry, "sleep") == 0)
+ {
+ display_powerDown();
+ }
+}
+
+static bool event_lastComplete = false;
+
+/* Function called when the display update is complete. */
+static void displayUpdateComplete(void)
+{
+ event_lastComplete = true;
+}
+
+void event_newDataAvailable(int data)
+{
+ event_lastComplete = false;
+ display_updateData(data, displayUpdateComplete);
+}
+
+bool eventProcessor_isLastEventComplete(void)
+{
+ return event_lastComplete;
+}
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.h b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.h
new file mode 100755
index 00000000..a79e68c5
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/event_processor.h
@@ -0,0 +1,11 @@
+#include <stdbool.h>
+
+void event_deviceReset(void);
+void event_volumeKnobMaxed(void);
+void event_powerReadingUpdate(int powerReading);
+void event_modeSelectButtonPressed(void);
+void event_devicePoweredOn(void);
+void event_keyboardCheckTimerExpired(void);
+void event_newDataAvailable(int data);
+
+bool eventProcessor_isLastEventComplete(void);
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.c b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.c
new file mode 100755
index 00000000..c05b1154
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.c
@@ -0,0 +1,16 @@
+#include "foo.h"
+#include "bar.h"
+#include "subfolder/zzz.h"
+
+void foo_turn_on(void) {
+ bar_turn_on();
+ zzz_sleep(1, "sleepy");
+}
+
+void foo_print_message(const char * message) {
+ bar_print_message(message);
+}
+
+void foo_print_special_message(void) {
+ bar_print_message_formatted("The numbers are %d, %d and %d", 1, 2, 3);
+}
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.h b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.h
new file mode 100755
index 00000000..3fea6994
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/foo.h
@@ -0,0 +1,8 @@
+#ifndef foo_H
+#define foo_H
+
+void foo_turn_on(void);
+void foo_print_message(const char * message);
+void foo_print_special_message(void);
+
+#endif // foo_H
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.c b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.c
new file mode 100755
index 00000000..85f370e1
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.c
@@ -0,0 +1 @@
+#include "zzz.h"
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.h b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.h
new file mode 100755
index 00000000..32c52940
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/src/subfolder/zzz.h
@@ -0,0 +1,6 @@
+#ifndef zzz_H
+#define zzz_H
+
+int zzz_sleep(int time, char * name);
+
+#endif // zzz_H
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_event_processor.c b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_event_processor.c
new file mode 100755
index 00000000..9f999443
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_event_processor.c
@@ -0,0 +1,155 @@
+#include "unity.h"
+#include "event_processor.h"
+#include "mock_display.h"
+#include <string.h>
+
+void setUp (void)
+{
+}
+
+void tearDown (void)
+{
+}
+/*
+ Test that a single function was called.
+*/
+void
+test_whenTheDeviceIsReset_thenTheStatusLedIsTurnedOff()
+{
+ // When
+ event_deviceReset();
+
+ // Then
+ TEST_ASSERT_EQUAL(1, display_turnOffStatusLed_fake.call_count);
+ // or use the helper macro...
+ TEST_ASSERT_CALLED(display_turnOffStatusLed);
+}
+
+/*
+ Test that a single function is NOT called.
+*/
+void
+test_whenThePowerReadingIsLessThan5_thenTheStatusLedIsNotTurnedOn(void)
+{
+ // When
+ event_powerReadingUpdate(4);
+
+ // Then
+ TEST_ASSERT_EQUAL(0, display_turnOnStatusLed_fake.call_count);
+ // or use the helper macro...
+ TEST_ASSERT_NOT_CALLED(display_turnOffStatusLed);
+}
+
+/*
+ Test that a single function was called with the correct arugment.
+*/
+void
+test_whenTheVolumeKnobIsMaxed_thenVolumeDisplayIsSetTo11(void)
+{
+ // When
+ event_volumeKnobMaxed();
+
+ // Then
+ TEST_ASSERT_EQUAL(1, display_setVolume_fake.call_count);
+ // or use the helper macro...
+ TEST_ASSERT_CALLED(display_setVolume);
+ TEST_ASSERT_EQUAL(11, display_setVolume_fake.arg0_val);
+}
+
+/*
+ Test a sequence of calls.
+*/
+
+void
+test_whenTheModeSelectButtonIsPressed_thenTheDisplayModeIsCycled(void)
+{
+ // When
+ event_modeSelectButtonPressed();
+ event_modeSelectButtonPressed();
+ event_modeSelectButtonPressed();
+
+ // Then
+ TEST_ASSERT_EQUAL_PTR((void *)display_setModeToMinimum, fff.call_history[0]);
+ TEST_ASSERT_EQUAL_PTR((void *)display_setModeToMaximum, fff.call_history[1]);
+ TEST_ASSERT_EQUAL_PTR((void *)display_setModeToAverage, fff.call_history[2]);
+ // or use the helper macros...
+ TEST_ASSERT_CALLED_IN_ORDER(0, display_setModeToMinimum);
+ TEST_ASSERT_CALLED_IN_ORDER(1, display_setModeToMaximum);
+ TEST_ASSERT_CALLED_IN_ORDER(2, display_setModeToAverage);
+}
+
+/*
+ Mock a return value from a function.
+*/
+void
+test_givenTheDisplayHasAnError_whenTheDeviceIsPoweredOn_thenTheDisplayIsPoweredDown(void)
+{
+ // Given
+ display_isError_fake.return_val = true;
+
+ // When
+ event_devicePoweredOn();
+
+ // Then
+ TEST_ASSERT_EQUAL(1, display_powerDown_fake.call_count);
+ // or use the helper macro...
+ TEST_ASSERT_CALLED(display_powerDown);
+}
+
+/*
+ Mock a sequence of calls with return values.
+*/
+
+/*
+ Mocking a function with a value returned by reference.
+*/
+void
+test_givenTheUserHasTypedSleep_whenItIsTimeToCheckTheKeyboard_theDisplayIsPoweredDown(void)
+{
+ // Given
+ char mockedEntry[] = "sleep";
+ void return_mock_value(char * entry, int length)
+ {
+ if (length > strlen(mockedEntry))
+ {
+ strncpy(entry, mockedEntry, length);
+ }
+ }
+ display_getKeyboardEntry_fake.custom_fake = return_mock_value;
+
+ // When
+ event_keyboardCheckTimerExpired();
+
+ // Then
+ TEST_ASSERT_EQUAL(1, display_powerDown_fake.call_count);
+ // or use the helper macro...
+ TEST_ASSERT_CALLED(display_powerDown);
+}
+
+/*
+ Mock a function with a function pointer parameter.
+*/
+void
+test_givenNewDataIsAvailable_whenTheDisplayHasUpdated_thenTheEventIsComplete(void)
+{
+ // A mock function for capturing the callback handler function pointer.
+ void(*registeredCallback)(void) = 0;
+ void mock_display_updateData(int data, void(*callback)(void))
+ {
+ //Save the callback function.
+ registeredCallback = callback;
+ }
+ display_updateData_fake.custom_fake = mock_display_updateData;
+
+ // Given
+ event_newDataAvailable(10);
+
+ // When
+ if (registeredCallback != 0)
+ {
+ registeredCallback();
+ }
+
+ // Then
+ TEST_ASSERT_EQUAL(true, eventProcessor_isLastEventComplete());
+}
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_foo.c b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_foo.c
new file mode 100755
index 00000000..12dd61a1
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/examples/fff_example/test/test_foo.c
@@ -0,0 +1,47 @@
+#include "unity.h"
+#include "foo.h"
+#include "mock_bar.h"
+#include "mock_zzz.h"
+
+void setUp(void)
+{
+}
+
+void tearDown(void)
+{
+}
+
+void test_foo(void)
+{
+ //When
+ foo_turn_on();
+
+ //Then
+ TEST_ASSERT_EQUAL(1, bar_turn_on_fake.call_count);
+ TEST_ASSERT_EQUAL(1, zzz_sleep_fake.call_count);
+ TEST_ASSERT_EQUAL_STRING("sleepy", zzz_sleep_fake.arg1_val);
+}
+
+void test_foo_again(void)
+{
+ //When
+ foo_turn_on();
+
+ //Then
+ TEST_ASSERT_EQUAL(1, bar_turn_on_fake.call_count);
+}
+
+void test_foo_mock_with_const(void)
+{
+ foo_print_message("123");
+
+ TEST_ASSERT_EQUAL(1, bar_print_message_fake.call_count);
+ TEST_ASSERT_EQUAL_STRING("123", bar_print_message_fake.arg0_val);
+}
+
+void test_foo_mock_with_variable_args(void)
+{
+ foo_print_special_message();
+ TEST_ASSERT_EQUAL(1, bar_print_message_formatted_fake.call_count);
+ TEST_ASSERT_EQUAL_STRING("The numbers are %d, %d and %d", bar_print_message_formatted_fake.arg0_val);
+}
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fake_function_framework.rb b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fake_function_framework.rb
new file mode 100755
index 00000000..51a90b3a
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fake_function_framework.rb
@@ -0,0 +1,87 @@
+require 'ceedling/plugin'
+require 'fff_mock_generator'
+
+class FakeFunctionFramework < Plugin
+
+ # Set up Ceedling to use this plugin.
+ def setup
+ # Get the location of this plugin.
+ @plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
+ puts "Using fake function framework (fff)..."
+
+ # Switch out the cmock_builder with our own.
+ @ceedling[:cmock_builder].cmock = FffMockGeneratorForCMock.new(@ceedling[:setupinator].config_hash[:cmock])
+
+ # Add the path to fff.h to the include paths.
+ COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR << "#{@plugin_root}/vendor/fff"
+ COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR << "#{@plugin_root}/src"
+ end
+
+ def post_runner_generate(arg_hash)
+ # After the test runner file has been created, append the FFF globals
+ # definition to the end of the test runner. These globals will be shared by
+ # all mocks linked into the test.
+ File.open(arg_hash[:runner_file], 'a') do |f|
+ f.puts
+ f.puts "//=======Defintions of FFF variables====="
+ f.puts %{#include "fff.h"}
+ f.puts "DEFINE_FFF_GLOBALS;"
+ end
+ end
+
+end # class FakeFunctionFramework
+
+class FffMockGeneratorForCMock
+
+ def initialize(options=nil)
+ @cm_config = CMockConfig.new(options)
+ @cm_parser = CMockHeaderParser.new(@cm_config)
+ @silent = (@cm_config.verbosity < 2)
+
+ # These are the additional files to include in the mock files.
+ @includes_h_pre_orig_header = (@cm_config.includes || @cm_config.includes_h_pre_orig_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""}
+ @includes_h_post_orig_header = (@cm_config.includes_h_post_orig_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""}
+ @includes_c_pre_header = (@cm_config.includes_c_pre_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""}
+ @includes_c_post_header = (@cm_config.includes_c_post_header || []).map{|h| h =~ /</ ? h : "\"#{h}\""}
+ end
+
+ def setup_mocks(files)
+ [files].flatten.each do |src|
+ generate_mock (src)
+ end
+ end
+
+ def generate_mock (header_file_to_mock)
+ module_name = File.basename(header_file_to_mock, '.h')
+ puts "Creating mock for #{module_name}..." unless @silent
+ mock_name = @cm_config.mock_prefix + module_name + @cm_config.mock_suffix
+ mock_path = @cm_config.mock_path
+ if @cm_config.subdir
+ # If a subdirectory has been configured, append it to the mock path.
+ mock_path = "#{mock_path}/#{@cm_config.subdir}"
+ end
+ full_path_for_mock = "#{mock_path}/#{mock_name}"
+
+ # Parse the header file so we know what to mock.
+ parsed_header = @cm_parser.parse(module_name, File.read(header_file_to_mock))
+
+ # Create the directory if it doesn't exist.
+ mkdir_p full_path_for_mock.pathmap("%d")
+
+ # Generate the mock header file.
+ puts "Creating mock: #{full_path_for_mock}.h"
+
+ # Create the mock header.
+ File.open("#{full_path_for_mock}.h", 'w') do |f|
+ f.write(FffMockGenerator.create_mock_header(module_name, mock_name, parsed_header,
+ @includes_h_pre_orig_header, @includes_h_post_orig_header))
+ end
+
+ # Create the mock source file.
+ File.open("#{full_path_for_mock}.c", 'w') do |f|
+ f.write(FffMockGenerator.create_mock_source(mock_name, parsed_header,
+ @includes_c_pre_orig_header, @includes_c_post_orig_header))
+ end
+ end
+
+end
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fff_mock_generator.rb b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fff_mock_generator.rb
new file mode 100755
index 00000000..9dc03a65
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/lib/fff_mock_generator.rb
@@ -0,0 +1,163 @@
+# Creates mock files from parsed header files that can be linked into applications.
+# The mocks created are compatible with CMock for use with Ceedling.
+
+class FffMockGenerator
+
+ def self.create_mock_header(module_name, mock_name, parsed_header, pre_includes=nil,
+ post_includes=nil)
+ output = StringIO.new
+ write_opening_include_guard(mock_name, output)
+ output.puts
+ write_extra_includes(pre_includes, output)
+ write_header_includes(module_name, output)
+ write_extra_includes(post_includes, output)
+ output.puts
+ write_typedefs(parsed_header, output)
+ output.puts
+ write_function_declarations(parsed_header, output)
+ output.puts
+ write_control_function_prototypes(mock_name, output)
+ output.puts
+ write_closing_include_guard(mock_name, output)
+ output.string
+ end
+
+ def self.create_mock_source (mock_name, parsed_header, pre_includes=nil,
+ post_includes=nil)
+ output = StringIO.new
+ write_extra_includes(pre_includes, output)
+ write_source_includes(mock_name, output)
+ write_extra_includes(post_includes, output)
+ output.puts
+ write_function_definitions(parsed_header, output)
+ output.puts
+ write_control_function_definitions(mock_name, parsed_header, output)
+ output.string
+ end
+
+ private
+
+# Header file generation functions.
+
+ def self.write_opening_include_guard(mock_name, output)
+ output.puts "#ifndef #{mock_name}_H"
+ output.puts "#define #{mock_name}_H"
+ end
+
+ def self.write_header_includes(module_name, output)
+ output.puts %{#include "fff.h"}
+ output.puts %{#include "fff_unity_helper.h"}
+ output.puts %{#include "#{module_name}.h"}
+ end
+
+ def self.write_typedefs(parsed_header, output)
+ return unless parsed_header.key?(:typedefs)
+ parsed_header[:typedefs].each do |typedef|
+ output.puts typedef
+ end
+ end
+
+ def self.write_function_declarations(parsed_header, output)
+ write_function_macros("DECLARE", parsed_header, output)
+ end
+
+
+ def self.write_control_function_prototypes(mock_name, output)
+ output.puts "void #{mock_name}_Init(void);"
+ output.puts "void #{mock_name}_Verify(void);"
+ output.puts "void #{mock_name}_Destroy(void);"
+ end
+
+ def self.write_closing_include_guard(mock_name, output)
+ output.puts "#endif // #{mock_name}_H"
+ end
+
+# Source file generation functions.
+
+ def self.write_source_includes (mock_name, output)
+ output.puts "#include <string.h>"
+ output.puts %{#include "fff.h"}
+ output.puts %{#include "#{mock_name}.h"}
+ end
+
+ def self.write_function_definitions(parsed_header, output)
+ write_function_macros("DEFINE", parsed_header, output)
+ end
+
+ def self.write_control_function_definitions(mock_name, parsed_header, output)
+ output.puts "void #{mock_name}_Init(void)"
+ output.puts "{"
+ # In the init function, reset the FFF globals. These are used for things
+ # like the call history.
+ output.puts " FFF_RESET_HISTORY();"
+
+ # Also, reset all of the fakes.
+ if parsed_header[:functions]
+ parsed_header[:functions].each do |function|
+ output.puts " RESET_FAKE(#{function[:name]})"
+ end
+ end
+ output.puts "}"
+ output.puts "void #{mock_name}_Verify(void)"
+ output.puts "{"
+ output.puts "}"
+ output.puts "void #{mock_name}_Destroy(void)"
+ output.puts "{"
+ output.puts "}"
+ end
+
+# Shared functions.
+
+ def self.write_extra_includes(includes, output)
+ if includes
+ includes.each {|inc| output.puts "#include #{inc}\n"}
+ end
+ end
+
+ def self.write_function_macros(macro_type, parsed_header, output)
+ return unless parsed_header.key?(:functions)
+ parsed_header[:functions].each do |function|
+ name = function[:name]
+ return_type = function[:return][:type]
+ if function.has_key? :modifier
+ # Prepend any modifier. If there isn't one, trim any leading whitespace.
+ return_type = "#{function[:modifier]} #{return_type}".lstrip
+ end
+ arg_count = function[:args].size
+
+ # Check for variable arguments.
+ var_arg_suffix = ""
+ if function[:var_arg]
+ # If there are are variable arguments, then we need to add this argument
+ # to the count, update the suffix that will get added to the macro.
+ arg_count += 1
+ var_arg_suffix = "_VARARG"
+ end
+
+ # Generate the correct macro.
+ if return_type == 'void'
+ output.print "#{macro_type}_FAKE_VOID_FUNC#{arg_count}#{var_arg_suffix}(#{name}"
+ else
+ output.print "#{macro_type}_FAKE_VALUE_FUNC#{arg_count}#{var_arg_suffix}(#{return_type}, #{name}"
+ end
+
+ # Append each argument type.
+ function[:args].each do |arg|
+ output.print ", "
+ if arg[:const?]
+ output.print "const "
+ end
+ output.print "#{arg[:type]}"
+ end
+
+ # If this argument list ends with a variable argument, add it here at the end.
+ if function[:var_arg]
+ output.print ", ..."
+ end
+
+ # Close the declaration.
+ output.puts ");"
+ end
+ end
+
+end
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_header_generator_spec.rb b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_header_generator_spec.rb
new file mode 100755
index 00000000..e6ac11dd
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_header_generator_spec.rb
@@ -0,0 +1,304 @@
+require 'stringio'
+require 'fff_mock_generator.rb'
+require 'header_generator.rb'
+
+# Test the contents of the .h file created for the mock.
+describe "FffMockGenerator.create_mock_header" do
+
+ context "when there is nothing to mock," do
+ let(:mock_header) {
+ parsed_header = {}
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated header file starts with an opening include guard" do
+ expect(mock_header).to start_with(
+ "#ifndef mock_display_H\n" +
+ "#define mock_display_H")
+ end
+ it "then the generated file ends with a closing include guard" do
+ expect(mock_header).to end_with(
+ "#endif // mock_display_H\n")
+ end
+ it "then the generated file includes the fff header" do
+ expect(mock_header).to include(
+ %{#include "fff.h"\n})
+ end
+ it "then the generated file has a prototype for the init function" do
+ expect(mock_header).to include(
+ "void mock_display_Init(void);")
+ end
+ it "then the generated file has a prototype for the verify function" do
+ expect(mock_header).to include(
+ "void mock_display_Verify(void);")
+ end
+ it "then the generated file has a prototype for the destroy function" do
+ expect(mock_header).to include(
+ "void mock_display_Destroy(void);")
+ end
+ end
+
+ context "when there is a function with no args and a void return," do
+ let(:mock_header) {
+ parsed_header = create_cmock_style_parsed_header(
+ [{:name => 'display_turnOffStatusLed', :return_type => 'void'}])
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated header file starts with an opening include guard" do
+ expect(mock_header).to start_with(
+ "#ifndef mock_display_H\n" +
+ "#define mock_display_H")
+ end
+ it "then the generated header file contains a fake function declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VOID_FUNC0(display_turnOffStatusLed);"
+ )
+ end
+ it "then the generated file ends with a closing include guard" do
+ expect(mock_header).to end_with(
+ "#endif // mock_display_H\n")
+ end
+ end
+
+ context "when there is a function with no args and a bool return," do
+ let(:mock_header) {
+ parsed_header = create_cmock_style_parsed_header(
+ [{:name => 'display_isError', :return_type => 'bool'}])
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated file contains the fake function declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VALUE_FUNC0(bool, display_isError);"
+ )
+ end
+ end
+
+ context "when there is a function with no args and an int return," do
+ let(:mock_header) {
+ parsed_header = create_cmock_style_parsed_header(
+ [{:name => 'display_isError', :return_type => 'int'}])
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated file contains the fake function declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VALUE_FUNC0(int, display_isError);"
+ )
+ end
+ end
+
+ context "when there is a function with args and a void return," do
+ let(:mock_header) {
+ parsed_header = create_cmock_style_parsed_header(
+ [{:name => 'display_setVolume', :return_type => 'void', :args => ['int']}])
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated file contains the fake function declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VOID_FUNC1(display_setVolume, int);"
+ )
+ end
+ end
+
+ context "when there is a function with args and a value return," do
+ let(:mock_header) {
+ parsed_header = create_cmock_style_parsed_header(
+ [{:name => 'a_function', :return_type => 'int', :args => ['char *']}])
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated file contains the fake function declaration" do
+ expect(mock_header).to include(
+ "FAKE_VALUE_FUNC1(int, a_function, char *);"
+ )
+ end
+ end
+
+ context "when there is a function with many args and a void return," do
+ let(:mock_header) {
+ parsed_header = create_cmock_style_parsed_header(
+ [{:name => 'a_function', :return_type => 'void',
+ :args => ['int', 'char *', 'int', 'int', 'bool', 'applesauce']}])
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated file contains the fake function declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VOID_FUNC6(a_function, int, char *, int, int, bool, applesauce);"
+ )
+ end
+ end
+
+ context "when there are multiple functions," do
+ let(:mock_header) {
+ parsed_header = create_cmock_style_parsed_header(
+ [ {:name => 'a_function', :return_type => 'int', :args => ['char *']},
+ {:name => 'another_function', :return_type => 'void'},
+ {:name => 'three', :return_type => 'bool', :args => ['float', 'int']}
+ ])
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated file contains the first fake function declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VALUE_FUNC1(int, a_function, char *);"
+ )
+ end
+ it "then the generated file contains the second fake function declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VOID_FUNC0(another_function);"
+ )
+ end
+ it "then the generated file contains the third fake function declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VALUE_FUNC2(bool, three, float, int);"
+ )
+ end
+ end
+
+ context "when there is a typedef," do
+ let(:mock_header) {
+ parsed_header = create_cmock_style_parsed_header(
+ nil, ["typedef void (*displayCompleteCallback) (void);"])
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated file contains the typedef" do
+ expect(mock_header).to include(
+ "typedef void (*displayCompleteCallback) (void);"
+ )
+ end
+ end
+
+ context "when there is a void function with variable arguments" do
+ let(:mock_header){
+ parsed_header = {}
+ parsed_header[:functions] = [{
+ :name => "function_with_var_args",
+ :return => {:type => "void"},
+ :var_arg => "...",
+ :args => [{:type => 'char *'}]
+ }]
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated file contains the vararg declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VOID_FUNC2_VARARG(function_with_var_args, char *, ...)"
+ )
+ end
+ end
+
+ context "when there is a function with a return value and variable arguments" do
+ let(:mock_header){
+ parsed_header = {}
+ parsed_header[:functions] = [{
+ :name => "function_with_var_args",
+ :return => {:type => "int"},
+ :var_arg => "...",
+ :args => [{:type => 'char *'}]
+ }]
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated file contains the vararg declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VALUE_FUNC2_VARARG(int, function_with_var_args, char *, ...)"
+ )
+ end
+ end
+
+ context "when there is a void function with variable arguments and " +
+ "additional arguments" do
+ let(:mock_header){
+ parsed_header = {}
+ parsed_header[:functions] = [{
+ :name => "function_with_var_args",
+ :return => {:type => "void"},
+ :var_arg => "...",
+ :args => [{:type => 'char *'}, {:type => 'int'}]
+ }]
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated file contains the vararg declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VOID_FUNC3_VARARG(function_with_var_args, char *, int, ...)"
+ )
+ end
+ end
+
+ context "when there is a function with a pointer to a const value" do
+ let(:mock_header){
+ parsed_header = {}
+ parsed_header[:functions] = [{
+ :name => "const_test_function",
+ :return => {:type => "void"},
+ :args => [{:type => "char *", :name => "a", :ptr? => false, :const? => true},
+ {:type => "char *", :name => "b", :ptr? => false, :const? => false}]
+ }]
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated file contains the correct const argument in the declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VOID_FUNC2(const_test_function, const char *, char *)"
+ )
+ end
+ end
+
+ context "when there is a function that returns a const pointer" do
+ let(:mock_header){
+ parsed_header = {}
+ parsed_header[:functions] = [{
+ :name => "return_const_pointer_test_function",
+ :modifier => "const",
+ :return => {:type => "char *" },
+ :args => [{:type => "int", :name => "a"}]
+ }]
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated file contains the correct const return value in the declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VALUE_FUNC1(const char *, return_const_pointer_test_function, int)"
+ )
+ end
+ end
+
+ context "when there is a function that returns a const int" do
+ let(:mock_header){
+ parsed_header = {}
+ parsed_header[:functions] = [{
+ :name => "return_const_int_test_function",
+ :modifier => "const",
+ :return => {:type => "int" },
+ :args => []
+ }]
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header)
+ }
+ it "then the generated file contains the correct const return value in the declaration" do
+ expect(mock_header).to include(
+ "DECLARE_FAKE_VALUE_FUNC0(const int, return_const_int_test_function)"
+ )
+ end
+ end
+
+ context "when there are pre-includes" do
+ let(:mock_header) {
+ parsed_header = {}
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header,
+ [%{"another_header.h"}])
+ }
+ it "then they are included before the other files" do
+ expect(mock_header).to include(
+ %{#include "another_header.h"\n} +
+ %{#include "fff.h"}
+ )
+ end
+ end
+
+ context "when there are post-includes" do
+ let(:mock_header) {
+ parsed_header = {}
+ FffMockGenerator.create_mock_header("display", "mock_display", parsed_header,
+ nil, [%{"another_header.h"}])
+ }
+ it "then they are included after the other files" do
+ expect(mock_header).to include(
+ %{#include "display.h"\n} +
+ %{#include "another_header.h"\n}
+ )
+ end
+ end
+
+end
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_source_generator_spec.rb b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_source_generator_spec.rb
new file mode 100755
index 00000000..364f8521
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/fff_mock_source_generator_spec.rb
@@ -0,0 +1,149 @@
+require 'stringio'
+require 'fff_mock_generator.rb'
+
+# Test the contents of the .c file created for the mock.
+describe "FffMockGenerator.create_mock_source" do
+
+ context "when there is nothing to mock," do
+ let(:mock_source) {
+ parsed_header = {}
+ FffMockGenerator.create_mock_source("mock_my_module", parsed_header)
+ }
+ it "then the generated file includes the fff header" do
+ expect(mock_source).to include(
+ # fff.h also requires including string.h
+ %{#include <string.h>\n} +
+ %{#include "fff.h"}
+ )
+ end
+ it "then the generated file includes the mock header" do
+ expect(mock_source).to include(
+ %{#include "mock_my_module.h"\n}
+ )
+ end
+ it "then the generated file defines the init function" do
+ expect(mock_source).to include(
+ "void mock_my_module_Init(void)\n" +
+ "{\n" +
+ " FFF_RESET_HISTORY();\n" +
+ "}"
+ )
+ end
+ it "then the generated file defines the verify function" do
+ expect(mock_source).to include(
+ "void mock_my_module_Verify(void)\n" +
+ "{\n" +
+ "}"
+ )
+ end
+ it "then the generated file defines the destroy function" do
+ expect(mock_source).to include(
+ "void mock_my_module_Destroy(void)\n" +
+ "{\n" +
+ "}"
+ )
+ end
+ end
+
+ context "when there are multiple functions," do
+ let(:mock_source) {
+ parsed_header = create_cmock_style_parsed_header(
+ [ {:name => 'a_function', :return_type => 'int', :args => ['char *']},
+ {:name => 'another_function', :return_type => 'void'},
+ {:name => 'three', :return_type => 'bool', :args => ['float', 'int']}
+ ])
+ FffMockGenerator.create_mock_source("mock_display", parsed_header)
+ }
+ it "then the generated file contains the first fake function definition" do
+ expect(mock_source).to include(
+ "DEFINE_FAKE_VALUE_FUNC1(int, a_function, char *);"
+ )
+ end
+ it "then the generated file contains the second fake function definition" do
+ expect(mock_source).to include(
+ "DEFINE_FAKE_VOID_FUNC0(another_function);"
+ )
+ end
+ it "then the generated file contains the third fake function definition" do
+ expect(mock_source).to include(
+ "DEFINE_FAKE_VALUE_FUNC2(bool, three, float, int);"
+ )
+ end
+ it "then the init function resets all of the fakes" do
+ expect(mock_source).to include(
+ "void mock_display_Init(void)\n" +
+ "{\n" +
+ " FFF_RESET_HISTORY();\n" +
+ " RESET_FAKE(a_function)\n" +
+ " RESET_FAKE(another_function)\n" +
+ " RESET_FAKE(three)\n" +
+ "}"
+ )
+ end
+ end
+
+ context "when there is a void function with variable arguments and " +
+ "additional arguments" do
+ let(:mock_source){
+ parsed_header = {}
+ parsed_header[:functions] = [{
+ :name => "function_with_var_args",
+ :return => {:type => "void"},
+ :var_arg => "...",
+ :args => [{:type => 'char *'}, {:type => 'int'}]
+ }]
+ FffMockGenerator.create_mock_source("mock_display", parsed_header)
+ }
+ it "then the generated file contains the vararg definition" do
+ expect(mock_source).to include(
+ "DEFINE_FAKE_VOID_FUNC3_VARARG(function_with_var_args, char *, int, ...)"
+ )
+ end
+ end
+
+ context "when there is a function with a pointer to a const value" do
+ let(:mock_source){
+ parsed_header = {}
+ parsed_header[:functions] = [{
+ :name => "const_test_function",
+ :return => {:type => "void"},
+ :args => [{:type => "char *", :name => "a", :ptr? => false, :const? => true},
+ {:type => "char *", :name => "b", :ptr? => false, :const? => false}]
+ }]
+ FffMockGenerator.create_mock_source("mock_display", parsed_header)
+ }
+ it "then the generated file contains the correct const argument in the declaration" do
+ expect(mock_source).to include(
+ "DEFINE_FAKE_VOID_FUNC2(const_test_function, const char *, char *)"
+ )
+ end
+ end
+
+ context "when there are pre-includes" do
+ let(:mock_source) {
+ parsed_source = {}
+ FffMockGenerator.create_mock_source("mock_display", parsed_source,
+ [%{"another_header.h"}])
+ }
+ it "then they are included before the other files" do
+ expect(mock_source).to include(
+ %{#include "another_header.h"\n} +
+ %{#include <string.h>}
+ )
+ end
+ end
+
+ context "when there are post-includes" do
+ let(:mock_source) {
+ parsed_source = {}
+ FffMockGenerator.create_mock_source("mock_display", parsed_source,
+ nil, [%{"another_header.h"}])
+ }
+ it "then they are included before the other files" do
+ expect(mock_source).to include(
+ %{#include "mock_display.h"\n} +
+ %{#include "another_header.h"\n}
+ )
+ end
+ end
+end \ No newline at end of file
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/header_generator.rb b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/header_generator.rb
new file mode 100755
index 00000000..cda27844
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/header_generator.rb
@@ -0,0 +1,51 @@
+# Create a CMock-style parsed header hash. This the type of hash created by
+# CMock when parsing header files for automock generation. It contains all of
+# includes, typedefs and functions (with return types and arguments) parsed from
+# the header file.
+def create_cmock_style_parsed_header(functions, typedefs = nil)
+ parsed_header = {
+ :includes => nil,
+ :functions => [],
+ :typedefs => []
+ }
+
+ # Add the typedefs.
+ if typedefs
+ typedefs.each do |typedef|
+ parsed_header[:typedefs] << typedef
+ end
+ end
+
+ # Add the functions.
+ if functions
+ functions.each do |function|
+ # Build the array of arguments.
+ args = []
+ if function.key?(:args)
+ function[:args].each do |arg|
+ args << {
+ :type => arg
+ }
+ end
+ end
+ parsed_header[:functions] << {
+ :name => function[:name],
+ :modifier => "",
+ :return => {
+ :type => function[:return_type],
+ :name => "cmock_to_return",
+ :ptr? => false,
+ :const? => false,
+ :str => "void cmock_to_return",
+ :void? => true
+ },
+ :var_arg => nil,
+ :args_string => "void",
+ :args => args,
+ :args_call => "",
+ :contains_ptr? => false
+ }
+ end
+ end
+ parsed_header
+end \ No newline at end of file
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/spec_helper.rb b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/spec_helper.rb
new file mode 100755
index 00000000..25dc80ac
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/spec/spec_helper.rb
@@ -0,0 +1,96 @@
+# This file was generated by the `rspec --init` command. Conventionally, all
+# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
+# The generated `.rspec` file contains `--require spec_helper` which will cause
+# this file to always be loaded, without a need to explicitly require it in any
+# files.
+#
+# Given that it is always loaded, you are encouraged to keep this file as
+# light-weight as possible. Requiring heavyweight dependencies from this file
+# will add to the boot time of your test suite on EVERY test run, even for an
+# individual file that may not need all of that loaded. Instead, consider making
+# a separate helper file that requires the additional dependencies and performs
+# the additional setup, and require it from the spec files that actually need
+# it.
+#
+# The `.rspec` file also contains a few flags that are not defaults but that
+# users commonly want.
+#
+# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
+RSpec.configure do |config|
+ # rspec-expectations config goes here. You can use an alternate
+ # assertion/expectation library such as wrong or the stdlib/minitest
+ # assertions if you prefer.
+ config.expect_with :rspec do |expectations|
+ # This option will default to `true` in RSpec 4. It makes the `description`
+ # and `failure_message` of custom matchers include text for helper methods
+ # defined using `chain`, e.g.:
+ # be_bigger_than(2).and_smaller_than(4).description
+ # # => "be bigger than 2 and smaller than 4"
+ # ...rather than:
+ # # => "be bigger than 2"
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
+ end
+
+ # rspec-mocks config goes here. You can use an alternate test double
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
+ config.mock_with :rspec do |mocks|
+ # Prevents you from mocking or stubbing a method that does not exist on
+ # a real object. This is generally recommended, and will default to
+ # `true` in RSpec 4.
+ mocks.verify_partial_doubles = true
+ end
+
+# The settings below are suggested to provide a good initial experience
+# with RSpec, but feel free to customize to your heart's content.
+=begin
+ # These two settings work together to allow you to limit a spec run
+ # to individual examples or groups you care about by tagging them with
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
+ # get run.
+ config.filter_run :focus
+ config.run_all_when_everything_filtered = true
+
+ # Allows RSpec to persist some state between runs in order to support
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
+ # you configure your source control system to ignore this file.
+ config.example_status_persistence_file_path = "spec/examples.txt"
+
+ # Limits the available syntax to the non-monkey patched syntax that is
+ # recommended. For more details, see:
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
+ config.disable_monkey_patching!
+
+ # This setting enables warnings. It's recommended, but in some cases may
+ # be too noisy due to issues in dependencies.
+ config.warnings = true
+
+ # Many RSpec users commonly either run the entire suite or an individual
+ # file, and it's useful to allow more verbose output when running an
+ # individual spec file.
+ if config.files_to_run.one?
+ # Use the documentation formatter for detailed output,
+ # unless a formatter has already been configured
+ # (e.g. via a command-line flag).
+ config.default_formatter = 'doc'
+ end
+
+ # Print the 10 slowest examples and example groups at the
+ # end of the spec run, to help surface which specs are running
+ # particularly slow.
+ config.profile_examples = 10
+
+ # Run specs in random order to surface order dependencies. If you find an
+ # order dependency and want to debug it, you can fix the order by providing
+ # the seed, which is printed after each run.
+ # --seed 1234
+ config.order = :random
+
+ # Seed global randomization in this process using the `--seed` CLI option.
+ # Setting this allows you to use `--seed` to deterministically reproduce
+ # test failures related to randomization by passing the same `--seed` value
+ # as the one that triggered the failure.
+ Kernel.srand config.seed
+=end
+end
diff --git a/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/src/fff_unity_helper.h b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/src/fff_unity_helper.h
new file mode 100755
index 00000000..de3db44a
--- /dev/null
+++ b/tinyusb/test/vendor/ceedling/plugins/fake_function_framework/src/fff_unity_helper.h
@@ -0,0 +1,33 @@
+#ifndef fff_unity_helper_H
+#define fff_unity_helper_H
+
+/*
+ FFF helper macros for Unity.
+*/
+
+/*
+ Fail if the function was not called the expected number of times.
+*/
+#define TEST_ASSERT_CALLED_TIMES(times_, function_) \
+ TEST_ASSERT_EQUAL_MESSAGE(times_, \
+ function_ ## _fake.call_count, \
+ "Function " #function_ " called the incorrect number of times.")
+/*
+ Fail if the function was not called exactly once.
+*/
+#define TEST_ASSERT_CALLED(function_) TEST_ASSERT_CALLED_TIMES(1, function_)
+
+/*
+ Fail if the function was called 1 or more times.
+*/
+#define TEST_ASSERT_NOT_CALLED(function_) TEST_ASSERT_CALLED_TIMES(0, function_)
+
+/*
+ Fail if the function was not called in this particular order.
+*/
+#define TEST_ASSERT_CALLED_IN_ORDER(order_, function_) \
+ TEST_ASSERT_EQUAL_PTR_MESSAGE((void *) function_, \
+ fff.call_history[order_], \
+ "Function " #function_ " not called in order " #order_ )
+
+#endif \ No newline at end of file