From a2758b2183bd6fa2ce3ae8867b5f703fe3fcec08 Mon Sep 17 00:00:00 2001 From: Typist Date: Wed, 8 Nov 2023 12:38:42 +0000 Subject: [PATCH] added cmocka version --- c_cmocka/.gitignore | 13 +++ c_cmocka/CMakeLists.txt | 13 +++ c_cmocka/GildedRoseTextTests.c | 50 +++++++++++ c_cmocka/README.md | 20 +++++ c_cmocka/src/CMakeLists.txt | 5 ++ c_cmocka/src/GildedRose.c | 90 +++++++++++++++++++ c_cmocka/src/GildedRose.h | 9 ++ c_cmocka/src/sample.c | 5 ++ c_cmocka/src/sample.h | 6 ++ c_cmocka/test-cmocka/CMakeLists.txt | 44 +++++++++ .../test-cmocka/sample_test/CMakeLists.txt | 6 ++ .../test-cmocka/sample_test/sample_test.c | 24 +++++ 12 files changed, 285 insertions(+) create mode 100644 c_cmocka/.gitignore create mode 100644 c_cmocka/CMakeLists.txt create mode 100644 c_cmocka/GildedRoseTextTests.c create mode 100644 c_cmocka/README.md create mode 100644 c_cmocka/src/CMakeLists.txt create mode 100644 c_cmocka/src/GildedRose.c create mode 100644 c_cmocka/src/GildedRose.h create mode 100644 c_cmocka/src/sample.c create mode 100644 c_cmocka/src/sample.h create mode 100644 c_cmocka/test-cmocka/CMakeLists.txt create mode 100644 c_cmocka/test-cmocka/sample_test/CMakeLists.txt create mode 100644 c_cmocka/test-cmocka/sample_test/sample_test.c diff --git a/c_cmocka/.gitignore b/c_cmocka/.gitignore new file mode 100644 index 00000000..5de8153c --- /dev/null +++ b/c_cmocka/.gitignore @@ -0,0 +1,13 @@ +# Allow in source build +[Bb]uild*/ +# Ignore qt files when importing CMakeLists +*.users +# Ignore CLion project files +*.idea +# For macOs users +.DS_Store + +/build_meson/ +/subprojects/Catch2-*/ +/subprojects/packagecache/ +/cmake-build-*/ diff --git a/c_cmocka/CMakeLists.txt b/c_cmocka/CMakeLists.txt new file mode 100644 index 00000000..b694a976 --- /dev/null +++ b/c_cmocka/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.14 FATAL_ERROR) + +project(GildedRose VERSION 1.0) + +set(CMAKE_C_STANDARD 11) + +add_subdirectory(src) +add_subdirectory(test-cmocka) + + +add_executable(main GildedRoseTextTests.c) +target_link_libraries(main src) + diff --git a/c_cmocka/GildedRoseTextTests.c b/c_cmocka/GildedRoseTextTests.c new file mode 100644 index 00000000..9e79a033 --- /dev/null +++ b/c_cmocka/GildedRoseTextTests.c @@ -0,0 +1,50 @@ +#include +#include +#include "GildedRose.h" + +int +print_item(Item *item) +{ + return printf("%s, %d, %d\n", item->name, item->sellIn, item->quality); +} + +int main(int argc, char **argv) +{ + int days = 2; + if (argc > 1) { + char *a = argv[1]; + days = atoi(a); + } + + Item items[9]; + int last = 0; + int day; + int index; + + init_item(items + last++, "+5 Dexterity Vest", 10, 20); + init_item(items + last++, "Aged Brie", 2, 0); + init_item(items + last++, "Elixir of the Mongoose", 5, 7); + init_item(items + last++, "Sulfuras, Hand of Ragnaros", 0, 80); + init_item(items + last++, "Sulfuras, Hand of Ragnaros", -1, 80); + init_item(items + last++, "Backstage passes to a TAFKAL80ETC concert", 15, 20); + init_item(items + last++, "Backstage passes to a TAFKAL80ETC concert", 10, 49); + init_item(items + last++, "Backstage passes to a TAFKAL80ETC concert", 5, 49); + // this Conjured item doesn't yet work properly + init_item(items + last++, "Conjured Mana Cake", 3, 6); + + puts("OMGHAI!"); + + for (day = 0; day <= days; day++) + { + printf("-------- day %d --------\n", day); + printf("name, sellIn, quality\n"); + for(index = 0; index < last; index++) { + print_item(items + index); + } + + printf("\n"); + + update_quality(items, last); + } + return 0; +} diff --git a/c_cmocka/README.md b/c_cmocka/README.md new file mode 100644 index 00000000..0a872b74 --- /dev/null +++ b/c_cmocka/README.md @@ -0,0 +1,20 @@ +# Gilded Rose starting position in C with CMocka + +Use CMake to build it. Run the target "sample_test" to run the sample unit test using the cmocka framework. + +## Run the TextTest fixture on the command line + +When you build this project this executable should be created: + + c_cmocka/cmake-build-debug/main + +Execute it on the command line with an argument for the number of days: + + c_cmocka/cmake-build-debug/main 10 + +## Run the TextTest approval test that comes with this project + +There are instructions in the [TextTest Readme](../texttests/README.md) for setting up TextTest. You will need to specify the C executable in [config.gr](../texttests/config.gr). Uncomment this line to use it: + + executable:${TEXTTEST_HOME}/c_cmocka/cmake-build-debug/main + diff --git a/c_cmocka/src/CMakeLists.txt b/c_cmocka/src/CMakeLists.txt new file mode 100644 index 00000000..ed464f5a --- /dev/null +++ b/c_cmocka/src/CMakeLists.txt @@ -0,0 +1,5 @@ +set(SRC_LIB_NAME src) +set(SOURCES GildedRose.c) +add_library(${SRC_LIB_NAME} ${SOURCES}) +target_sources(${SRC_LIB_NAME} PRIVATE ${SOURCES}) +target_include_directories(${SRC_LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/c_cmocka/src/GildedRose.c b/c_cmocka/src/GildedRose.c new file mode 100644 index 00000000..afb97bbe --- /dev/null +++ b/c_cmocka/src/GildedRose.c @@ -0,0 +1,90 @@ +#include +#include "GildedRose.h" + +Item* +init_item(Item* item, const char *name, int sellIn, int quality) +{ + item->sellIn = sellIn; + item->quality = quality; + item->name = strdup(name); + + return item; +} + +void update_quality(Item items[], int size) +{ + int i; + + for (i = 0; i < size; i++) + { + if (strcmp(items[i].name, "Aged Brie") && strcmp(items[i].name, "Backstage passes to a TAFKAL80ETC concert")) + { + if (items[i].quality > 0) + { + if (strcmp(items[i].name, "Sulfuras, Hand of Ragnaros")) + { + items[i].quality = items[i].quality - 1; + } + } + } + else + { + if (items[i].quality < 50) + { + items[i].quality = items[i].quality + 1; + + if (!strcmp(items[i].name, "Backstage passes to a TAFKAL80ETC concert")) + { + if (items[i].sellIn < 11) + { + if (items[i].quality < 50) + { + items[i].quality = items[i].quality + 1; + } + } + + if (items[i].sellIn < 6) + { + if (items[i].quality < 50) + { + items[i].quality = items[i].quality + 1; + } + } + } + } + } + + if (strcmp(items[i].name, "Sulfuras, Hand of Ragnaros")) + { + items[i].sellIn = items[i].sellIn - 1; + } + + if (items[i].sellIn < 0) + { + if (strcmp(items[i].name, "Aged Brie")) + { + if (strcmp(items[i].name, "Backstage passes to a TAFKAL80ETC concert")) + { + if (items[i].quality > 0) + { + if (strcmp(items[i].name, "Sulfuras, Hand of Ragnaros")) + { + items[i].quality = items[i].quality - 1; + } + } + } + else + { + items[i].quality = items[i].quality - items[i].quality; + } + } + else + { + if (items[i].quality < 50) + { + items[i].quality = items[i].quality + 1; + } + } + } + } +} diff --git a/c_cmocka/src/GildedRose.h b/c_cmocka/src/GildedRose.h new file mode 100644 index 00000000..78d54a08 --- /dev/null +++ b/c_cmocka/src/GildedRose.h @@ -0,0 +1,9 @@ +typedef struct +{ + char *name; + int sellIn; + int quality; +} Item; + +extern Item* init_item(Item* item, const char *name, int sellIn, int quality); +extern void update_quality(Item items[], int size); diff --git a/c_cmocka/src/sample.c b/c_cmocka/src/sample.c new file mode 100644 index 00000000..c548e1f3 --- /dev/null +++ b/c_cmocka/src/sample.c @@ -0,0 +1,5 @@ +#include "sample.h" + +int add(int left, int right) { + return left + right; +} \ No newline at end of file diff --git a/c_cmocka/src/sample.h b/c_cmocka/src/sample.h new file mode 100644 index 00000000..2bff1afc --- /dev/null +++ b/c_cmocka/src/sample.h @@ -0,0 +1,6 @@ +#ifndef SAMPLE_H +#define SAMPLE_H + +int add(int left, int right); + +#endif //SAMPLE_H diff --git a/c_cmocka/test-cmocka/CMakeLists.txt b/c_cmocka/test-cmocka/CMakeLists.txt new file mode 100644 index 00000000..7f0429c7 --- /dev/null +++ b/c_cmocka/test-cmocka/CMakeLists.txt @@ -0,0 +1,44 @@ +set(TEST_NAME test-cmocka) + +include(FetchContent) + +FetchContent_Declare( + cmocka + GIT_REPOSITORY https://git.cryptomilk.org/projects/cmocka.git + GIT_TAG cmocka-1.1.5 + GIT_SHALLOW 1 +) + +set(WITH_STATIC_LIB ON CACHE BOOL "CMocka: Build with a static library" FORCE) +set(WITH_CMOCKERY_SUPPORT OFF CACHE BOOL "CMocka: Install a cmockery header" FORCE) +set(WITH_EXAMPLES OFF CACHE BOOL "CMocka: Build examples" FORCE) +set(UNIT_TESTING OFF CACHE BOOL "CMocka: Build with unit testing" FORCE) +set(PICKY_DEVELOPER OFF CACHE BOOL "CMocka: Build with picky developer flags" FORCE) + +FetchContent_MakeAvailable(cmocka) + +function(ADD_CMOCKA_TEST_ENVIRONMENT _TARGET_NAME) + if (WIN32 OR CYGWIN OR MINGW OR MSVC) + file(TO_NATIVE_PATH "${cmocka-library_BINARY_DIR}" CMOCKA_DLL_PATH) + + if (TARGET_SYSTEM_EMULATOR) + set(DLL_PATH_ENV "WINEPATH=${CMOCKA_DLL_PATH};$ENV{WINEPATH}") + else () + set(DLL_PATH_ENV "PATH=${CMOCKA_DLL_PATH}\\${CMAKE_BUILD_TYPE};$ENV{PATH}") + endif () + # + # IMPORTANT NOTE: The set_tests_properties(), below, internally + # stores its name/value pairs with a semicolon delimiter. + # because of this we must protect the semicolons in the path + # + string(REPLACE ";" "\\;" DLL_PATH_ENV "${DLL_PATH_ENV}") + + set_tests_properties(${_TARGET_NAME} + PROPERTIES + ENVIRONMENT + "${DLL_PATH_ENV}") + endif () +endfunction() + + +add_subdirectory(sample_test) diff --git a/c_cmocka/test-cmocka/sample_test/CMakeLists.txt b/c_cmocka/test-cmocka/sample_test/CMakeLists.txt new file mode 100644 index 00000000..297eefbf --- /dev/null +++ b/c_cmocka/test-cmocka/sample_test/CMakeLists.txt @@ -0,0 +1,6 @@ +project(sample-cmocka C) + +add_cmocka_test(sample_test + SOURCES sample_test.c + LINK_LIBRARIES src cmocka-static) +add_cmocka_test_environment(add_test) diff --git a/c_cmocka/test-cmocka/sample_test/sample_test.c b/c_cmocka/test-cmocka/sample_test/sample_test.c new file mode 100644 index 00000000..92525d16 --- /dev/null +++ b/c_cmocka/test-cmocka/sample_test/sample_test.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include "cmocka.h" + +#include "GildedRose.h" + +static void test_rose(void **state) +{ + Item items[1]; + init_item(items, "foo", 0, 0); + update_quality(items, 1); + + assert_string_equal("fixme", items[0].name); +} + +int main(void) { + const struct CMUnitTest tests[] = + { + cmocka_unit_test(test_rose), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +}