diff --git a/.gitignore b/.gitignore index 496ee2c..2608ec2 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.DS_Store \ No newline at end of file +.DS_Store +.vscode \ No newline at end of file diff --git a/build-project.sh b/build-project.sh index c75f560..4247c59 100644 --- a/build-project.sh +++ b/build-project.sh @@ -1,5 +1,6 @@ clear +ceedling test:all cd src/ -gcc main.c +gcc main.c mainMenu.c ./a.out -rm a.out \ No newline at end of file +rm a.out diff --git a/build/test/cache/defines_dependency.yml b/build/test/cache/defines_dependency.yml new file mode 100644 index 0000000..217b8d2 --- /dev/null +++ b/build/test/cache/defines_dependency.yml @@ -0,0 +1,3 @@ +--- +src/updateCustomerAccountBalance.c: +- TEST diff --git a/build/test/cache/input.yml b/build/test/cache/input.yml new file mode 100644 index 0000000..bc8023f --- /dev/null +++ b/build/test/cache/input.yml @@ -0,0 +1,242 @@ +--- +:project: + :use_exceptions: false + :use_mocks: true + :compile_threads: 1 + :test_threads: 1 + :use_test_preprocessor: true + :use_preprocessor_directives: false + :use_deep_dependencies: false + :generate_deep_dependencies: true + :auto_link_deep_dependencies: false + :test_file_prefix: test_ + :options_paths: [] + :release_build: false + :use_auxiliary_dependencies: true + :build_root: build + :which_ceedling: gem + :ceedling_version: 0.31.1 + :default_tasks: + - test:all +:release_build: + :use_assembly: false + :artifacts: [] +:paths: + :test: + - "+:tests/**" + - "-:tests/support" + :source: + - src/** + :support: + - tests/support + :include: [] + :libraries: [] + :test_toolchain_include: [] + :release_toolchain_include: [] +:files: + :test: [] + :source: [] + :assembly: [] + :support: [] + :include: [] +:environment: +- :rake_columns: '120' +:defines: + :test: + - &1 [] + - TEST + :test_preprocess: + - *1 + - TEST + :release: [] + :release_preprocess: [] + :use_test_definition: false + :common: [] +:libraries: + :flag: "-l${1}" + :path_flag: "-L ${1}" + :test: [] + :test_preprocess: [] + :release: [] + :release_preprocess: [] + :placement: :end + :system: [] +:flags: {} +:extension: + :header: ".h" + :source: ".c" + :assembly: ".s" + :object: ".o" + :libraries: + - ".a" + - ".so" + :executable: ".out" + :map: ".map" + :list: ".lst" + :testpass: ".pass" + :testfail: ".fail" + :dependencies: ".d" +:unity: + :vendor_path: "/Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor" + :defines: [] +:cmock: + :vendor_path: "/Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor" + :defines: [] + :includes: [] + :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 + :mock_path: build/test/mocks + :verbosity: 3 + :unity_helper: false +:cexception: + :vendor_path: "/Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor" + :defines: [] +:test_runner: + :includes: [] + :file_suffix: _runner +:tools: + :test_compiler: + :executable: gcc + :name: default_test_compiler + :stderr_redirect: :none + :background_exec: :none + :optional: false + :arguments: + - '' + - '' + - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR + - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE + - "-D$": COLLECTION_DEFINES_TEST_AND_VENDOR + - "-DGNU_COMPILER" + - "-g" + - '' + - -c "${1}" + - -o "${2}" + - "-MMD" + - -MF "${4}" + :test_fixture: + :executable: "${1}" + :name: default_test_fixture + :stderr_redirect: :auto + :background_exec: :none + :optional: false + :arguments: [] + :test_linker: + :executable: gcc + :name: default_test_linker + :stderr_redirect: :none + :background_exec: :none + :optional: false + :arguments: + - '' + - '' + - '' + - '"${1}"' + - "${5}" + - -o "${2}" + - '' + - "${4}" + - '' + :test_file_preprocessor: + :executable: gcc + :name: default_test_file_preprocessor + :stderr_redirect: :none + :background_exec: :none + :optional: false + :arguments: + - '' + - '' + - "-E" + - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR + - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE + - "-D$": COLLECTION_DEFINES_TEST_AND_VENDOR + - "-D$": DEFINES_TEST_PREPROCESS + - "-DGNU_COMPILER" + - '"${1}"' + - -o "${2}" + :test_file_preprocessor_directives: + :executable: gcc + :name: default_test_file_preprocessor_directives + :stderr_redirect: :none + :background_exec: :none + :optional: false + :arguments: + - "-E" + - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR + - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE + - "-D$": COLLECTION_DEFINES_TEST_AND_VENDOR + - "-D$": DEFINES_TEST_PREPROCESS + - "-DGNU_COMPILER" + - "-fdirectives-only" + - '"${1}"' + - -o "${2}" + :test_includes_preprocessor: + :executable: gcc + :name: default_test_includes_preprocessor + :stderr_redirect: :none + :background_exec: :none + :optional: false + :arguments: + - '' + - '' + - "-E" + - "-MM" + - "-MG" + - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR + - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE + - "-D$": COLLECTION_DEFINES_TEST_AND_VENDOR + - "-D$": DEFINES_TEST_PREPROCESS + - "-DGNU_COMPILER" + - '"${1}"' +:test_compiler: + :arguments: [] +:test_linker: + :arguments: [] +:test_fixture: + :arguments: [] + :link_objects: [] +:test_includes_preprocessor: + :arguments: [] +:test_file_preprocessor: + :arguments: [] +:test_file_preprocessor_directives: + :arguments: [] +:test_dependencies_generator: + :arguments: [] +:release_compiler: + :arguments: [] +:release_linker: + :arguments: [] +:release_assembler: + :arguments: [] +:release_dependencies_generator: + :arguments: [] +:plugins: + :load_paths: + - "/Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/lib/../plugins" + :enabled: + - stdout_pretty_tests_report + - module_generator + :display_raw_test_results: false + :stdout_pretty_tests_report_path: "/Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/lib/../plugins/stdout_pretty_tests_report" + :module_generator_path: "/Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/lib/../plugins/module_generator" +:gcov: + :reports: + - HtmlDetailed + :gcovr: + :html_medium_threshold: 75 + :html_high_threshold: 90 +:module_generator: + :project_root: "./" + :source_root: src/ + :test_root: test/ diff --git a/build/test/cache/test_updateCustomerAccountBalance.c b/build/test/cache/test_updateCustomerAccountBalance.c new file mode 100644 index 0000000..5b6d44a --- /dev/null +++ b/build/test/cache/test_updateCustomerAccountBalance.c @@ -0,0 +1,63 @@ +#include "src/updateCustomerAccountBalance.h" +#include "/Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/unity/src/unity.h" + + + + + + + + +void setUp(void) + +{ + +} + + + +void tearDown(void) + +{ + +} + + + +void test_updateAvailableAccountBalanceSuccess(void){ + + + + int id1 = 1234; + + int id2 = 1327; + + int id3 = 1666; + + + + int newBalance1=500; + + int newBalance2=800; + + int newBalance3=700; + + + + _Bool results1=updateAvailableAccountBalance(id1,newBalance1); + + _Bool results2=updateAvailableAccountBalance(id2,newBalance2); + + _Bool results3=updateAvailableAccountBalance(id3,newBalance3); + + + + do {if ((results1)) {} else {UnityFail( ((" Expected TRUE Was FALSE")), (UNITY_UINT)((UNITY_UINT)(29)));}} while(0); + + do {if ((results2)) {} else {UnityFail( ((" Expected TRUE Was FALSE")), (UNITY_UINT)((UNITY_UINT)(30)));}} while(0); + + do {if ((results3)) {} else {UnityFail( ((" Expected TRUE Was FALSE")), (UNITY_UINT)((UNITY_UINT)(31)));}} while(0); + + + +} diff --git a/build/test/dependencies/cmock.d b/build/test/dependencies/cmock.d new file mode 100644 index 0000000..58d1e9e --- /dev/null +++ b/build/test/dependencies/cmock.d @@ -0,0 +1,6 @@ +build/test/out/c/cmock.o: \ + /Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/cmock/src/cmock.c \ + /Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/cmock/src/cmock.h \ + /Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/cmock/src/cmock_internals.h \ + /Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/unity/src/unity.h \ + /Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/unity/src/unity_internals.h diff --git a/build/test/dependencies/test_updateCustomerAccountBalance.d b/build/test/dependencies/test_updateCustomerAccountBalance.d new file mode 100644 index 0000000..506a323 --- /dev/null +++ b/build/test/dependencies/test_updateCustomerAccountBalance.d @@ -0,0 +1,5 @@ +build/test/out/c/test_updateCustomerAccountBalance.o: \ + tests/test_updateCustomerAccountBalance.c \ + /Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/unity/src/unity.h \ + /Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/unity/src/unity_internals.h \ + src/updateCustomerAccountBalance.h diff --git a/build/test/dependencies/test_updateCustomerAccountBalance_runner.d b/build/test/dependencies/test_updateCustomerAccountBalance_runner.d new file mode 100644 index 0000000..e38698a --- /dev/null +++ b/build/test/dependencies/test_updateCustomerAccountBalance_runner.d @@ -0,0 +1,4 @@ +build/test/out/c/test_updateCustomerAccountBalance_runner.o: \ + build/test/runners/test_updateCustomerAccountBalance_runner.c \ + /Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/unity/src/unity.h \ + /Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/unity/src/unity_internals.h diff --git a/build/test/dependencies/unity.d b/build/test/dependencies/unity.d new file mode 100644 index 0000000..931f713 --- /dev/null +++ b/build/test/dependencies/unity.d @@ -0,0 +1,4 @@ +build/test/out/c/unity.o: \ + /Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/unity/src/unity.c \ + /Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/unity/src/unity.h \ + /Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/unity/src/unity_internals.h diff --git a/build/test/dependencies/updateCustomerAccountBalance.d b/build/test/dependencies/updateCustomerAccountBalance.d new file mode 100644 index 0000000..5f06f3b --- /dev/null +++ b/build/test/dependencies/updateCustomerAccountBalance.d @@ -0,0 +1,5 @@ +build/test/out/c/updateCustomerAccountBalance.o: \ + src/updateCustomerAccountBalance.c src/updateCustomerAccountBalance.h \ + src/currentCustomerAccountBalance.c \ + src/currentCustomerAccountBalance.h src/_file_information.h \ + src/lineReplacer.h diff --git a/build/test/out/c/cmock.o b/build/test/out/c/cmock.o new file mode 100644 index 0000000..7a4b511 Binary files /dev/null and b/build/test/out/c/cmock.o differ diff --git a/build/test/out/c/test_updateCustomerAccountBalance.o b/build/test/out/c/test_updateCustomerAccountBalance.o new file mode 100644 index 0000000..fda3468 Binary files /dev/null and b/build/test/out/c/test_updateCustomerAccountBalance.o differ diff --git a/build/test/out/c/test_updateCustomerAccountBalance_runner.o b/build/test/out/c/test_updateCustomerAccountBalance_runner.o new file mode 100644 index 0000000..35fab4e Binary files /dev/null and b/build/test/out/c/test_updateCustomerAccountBalance_runner.o differ diff --git a/build/test/out/c/unity.o b/build/test/out/c/unity.o new file mode 100644 index 0000000..cf2d7fe Binary files /dev/null and b/build/test/out/c/unity.o differ diff --git a/build/test/out/c/updateCustomerAccountBalance.o b/build/test/out/c/updateCustomerAccountBalance.o new file mode 100644 index 0000000..3e002d0 Binary files /dev/null and b/build/test/out/c/updateCustomerAccountBalance.o differ diff --git a/build/test/out/test_updateCustomerAccountBalance.out b/build/test/out/test_updateCustomerAccountBalance.out new file mode 100755 index 0000000..42268fb Binary files /dev/null and b/build/test/out/test_updateCustomerAccountBalance.out differ diff --git a/build/test/preprocess/files/test_updateCustomerAccountBalance.c b/build/test/preprocess/files/test_updateCustomerAccountBalance.c new file mode 100644 index 0000000..5b6d44a --- /dev/null +++ b/build/test/preprocess/files/test_updateCustomerAccountBalance.c @@ -0,0 +1,63 @@ +#include "src/updateCustomerAccountBalance.h" +#include "/Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/unity/src/unity.h" + + + + + + + + +void setUp(void) + +{ + +} + + + +void tearDown(void) + +{ + +} + + + +void test_updateAvailableAccountBalanceSuccess(void){ + + + + int id1 = 1234; + + int id2 = 1327; + + int id3 = 1666; + + + + int newBalance1=500; + + int newBalance2=800; + + int newBalance3=700; + + + + _Bool results1=updateAvailableAccountBalance(id1,newBalance1); + + _Bool results2=updateAvailableAccountBalance(id2,newBalance2); + + _Bool results3=updateAvailableAccountBalance(id3,newBalance3); + + + + do {if ((results1)) {} else {UnityFail( ((" Expected TRUE Was FALSE")), (UNITY_UINT)((UNITY_UINT)(29)));}} while(0); + + do {if ((results2)) {} else {UnityFail( ((" Expected TRUE Was FALSE")), (UNITY_UINT)((UNITY_UINT)(30)));}} while(0); + + do {if ((results3)) {} else {UnityFail( ((" Expected TRUE Was FALSE")), (UNITY_UINT)((UNITY_UINT)(31)));}} while(0); + + + +} diff --git a/build/test/preprocess/includes/test_updateCustomerAccountBalance.c b/build/test/preprocess/includes/test_updateCustomerAccountBalance.c new file mode 100644 index 0000000..2b0ad02 --- /dev/null +++ b/build/test/preprocess/includes/test_updateCustomerAccountBalance.c @@ -0,0 +1,3 @@ +--- +- "/Users/canhacioglu/.rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/ceedling-0.31.1/vendor/unity/src/unity.h" +- src/updateCustomerAccountBalance.h diff --git a/build/test/runners/test_updateCustomerAccountBalance_runner.c b/build/test/runners/test_updateCustomerAccountBalance_runner.c new file mode 100644 index 0000000..887be8b --- /dev/null +++ b/build/test/runners/test_updateCustomerAccountBalance_runner.c @@ -0,0 +1,81 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ + +/*=======Automagically Detected Files To Include=====*/ +#include "unity.h" + +int GlobalExpectCount; +int GlobalVerifyOrder; +char* GlobalOrderError; + +/*=======External Functions This Runner Calls=====*/ +extern void setUp(void); +extern void tearDown(void); +extern void test_updateAvailableAccountBalanceSuccess(void); + + +/*=======Mock Management=====*/ +static void CMock_Init(void) +{ + GlobalExpectCount = 0; + GlobalVerifyOrder = 0; + GlobalOrderError = NULL; +} +static void CMock_Verify(void) +{ +} +static void CMock_Destroy(void) +{ +} + +/*=======Test Reset Options=====*/ +void resetTest(void); +void resetTest(void) +{ + tearDown(); + CMock_Verify(); + CMock_Destroy(); + CMock_Init(); + setUp(); +} +void verifyTest(void); +void verifyTest(void) +{ + CMock_Verify(); +} + +/*=======Test Runner Used To Run Each Test=====*/ +static void run_test(UnityTestFunction func, const char* name, UNITY_LINE_TYPE line_num) +{ + Unity.CurrentTestName = name; + Unity.CurrentTestLineNumber = line_num; +#ifdef UNITY_USE_COMMAND_LINE_ARGS + if (!UnityTestMatches()) + return; +#endif + Unity.NumberOfTests++; + UNITY_CLR_DETAILS(); + UNITY_EXEC_TIME_START(); + CMock_Init(); + if (TEST_PROTECT()) + { + setUp(); + func(); + } + if (TEST_PROTECT()) + { + tearDown(); + CMock_Verify(); + } + CMock_Destroy(); + UNITY_EXEC_TIME_STOP(); + UnityConcludeTest(); +} + +/*=======MAIN=====*/ +int main(void) +{ + UnityBegin("test_updateCustomerAccountBalance.c"); + run_test(test_updateAvailableAccountBalanceSuccess, "test_updateAvailableAccountBalanceSuccess", 15); + + return UnityEnd(); +} diff --git a/project.yml b/project.yml new file mode 100644 index 0000000..640cb8f --- /dev/null +++ b/project.yml @@ -0,0 +1,101 @@ +--- + +# 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_ + :which_ceedling: gem + :ceedling_version: 0.31.1 + :default_tasks: + - test:all + +#:test_build: +# :use_assembly: TRUE + +#:release_build: +# :output: MyApp.out +# :use_assembly: FALSE + +:environment: + +:extension: + :executable: .out + +:paths: + :test: + - +:tests/** + - -:tests/support + :source: + - src/** + :support: + - tests/support + :libraries: [] + +: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) + :common: &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 + +# Add -gcov to the plugins list to make sure of the gcov plugin +# You will need to have gcov and gcovr both installed to make it work. +# For more information on these options, see docs in plugins/gcov +:gcov: + :reports: + - HtmlDetailed + :gcovr: + :html_medium_threshold: 75 + :html_high_threshold: 90 + +#: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 + +# LIBRARIES +# These libraries are automatically injected into the build process. Those specified as +# common will be used in all types of builds. Otherwise, libraries can be injected in just +# tests or releases. These options are MERGED with the options in supplemental yaml files. +:libraries: + :placement: :end + :flag: "-l${1}" + :path_flag: "-L ${1}" + :system: [] # for example, you might list 'm' to grab the math library + :test: [] + :release: [] + +:plugins: + :load_paths: + - "#{Ceedling.load_path}" + :enabled: + - stdout_pretty_tests_report + - module_generator +... diff --git a/src/CustomerData.txt b/src/CustomerData.txt new file mode 100644 index 0000000..911b18e --- /dev/null +++ b/src/CustomerData.txt @@ -0,0 +1,20 @@ +1234=example +ID=1234 +forename=Max +Surname=Mustermann +password=example +balance=5000 + +1327=example +ID=1327 +forename=Max +Surname=Mustermann +password=example +balance=1500 + +1666=example +ID=1666 +forename=Max +Surname=Mustermann +password=example +balance=240 \ No newline at end of file diff --git a/src/CustomerProperties.h b/src/CustomerProperties.h new file mode 100644 index 0000000..2bbab62 --- /dev/null +++ b/src/CustomerProperties.h @@ -0,0 +1,4 @@ +typedef struct Customer{ + char *ID, *forename, *surname, *password; + float balance; +}customer_t; diff --git a/src/LoginCustomer.c b/src/LoginCustomer.c new file mode 100644 index 0000000..5c2a7a4 --- /dev/null +++ b/src/LoginCustomer.c @@ -0,0 +1,97 @@ +#include "LoginCustomer.h" + +bool checkLogin(bool loginSuccessful) +{ + return (loginSuccessful) ? true : false; +} + +void collectCustomerDataForLogin(int attempts) +{ + customer_t c; + c.ID = calloc(15+1,sizeof(char)); + c.password = calloc(15+1, sizeof(char)); + char digitCharacterFromUser, passwordCharacterFromUser; + int IDLengthCounter = 0, passwordLengthCounter = 0; + const int IDMaxLength = 16, passwordMaxLength = 16; + + printf("Enter ID:\n"); + while(((digitCharacterFromUser=getchar()) != '\n')&&IDLengthCounter='0'&&digitCharacterFromUser<='9'){ + *(c.ID+IDLengthCounter) = digitCharacterFromUser; + } + else{ + printf("Character entered is not a digit. Aborting.\n"); + exit(-1); + } + ++IDLengthCounter; + } + *(c.ID+IDLengthCounter) = '\0'; + + if(IDLengthCounter>=IDMaxLength){ + printf("ID entered is too long. Aborting.\n"); + exit(-1); + } + + printf("Enter password:\n"); + while((passwordCharacterFromUser=getchar())!='\n'&&passwordLengthCounter=passwordMaxLength){ + printf("Password entered is too long. Aborting.\n"); + exit(-1); + } + customer_t *ptr = &c; + bool loginSuccessful = loginCustomer(ptr); + if(loginSuccessful ) { + printf("Welcome to the menu!\n"); + //call menu() + }else if(!loginSuccessful && attempts < MAX_LOGIN_ATTEMPTS){ + printf("You have %d attempts left.\n", MAX_LOGIN_ATTEMPTS - attempts); + collectCustomerDataForLogin(++attempts); + }else{ + printf("Maximum number of attempts reached. Program terminates.\n"); + exit(-1); + //call error() + } + +} + +bool loginCustomer(customer_t *c) +{ + bool foundCustomerEntryInFile = false; + char *searchForThisString = generateCheckString(c->ID,c->password); + char *lineFromCustomerFile = calloc(40,sizeof(char)); + FILE *readCustomerFile = fopen("CustomerData.txt", "r"); + if(readCustomerFile==NULL){ + printf("Could not find file. Aborting.\n"); + exit(-1); + //call error() + } + while((fscanf(readCustomerFile,"%s",lineFromCustomerFile)!=EOF)){ + if(strcmp(searchForThisString,lineFromCustomerFile)==0){ + foundCustomerEntryInFile = true; + break; + } + } + + if(checkLogin(foundCustomerEntryInFile)){ + printf("Login successful.\n"); + return foundCustomerEntryInFile; + }else{ + printf("Login not successful.\n"); + } + fclose(readCustomerFile); + return foundCustomerEntryInFile; +} + +char *generateCheckString(char *ID, char *password){ + int checkStringLength = strlen(ID) + 1 + strlen(password) + 1; + char *checkString = calloc(checkStringLength, sizeof(char)); + checkString = strcat(ID,"="); + checkString = strcat(checkString,password); + *(checkString+checkStringLength) = '\0'; + return checkString; +} diff --git a/src/LoginCustomer.h b/src/LoginCustomer.h new file mode 100644 index 0000000..809765b --- /dev/null +++ b/src/LoginCustomer.h @@ -0,0 +1,10 @@ +#include +#include +#include +#include +#include "CustomerProperties.h" +#define MAX_LOGIN_ATTEMPTS 3 +char *generateCheckString(char *, char*); +bool checkLogin(bool); +void collectCustomerDataForLogin(int); +bool loginCustomer(customer_t *); diff --git a/src/_file_information.h b/src/_file_information.h new file mode 100644 index 0000000..1cb5200 --- /dev/null +++ b/src/_file_information.h @@ -0,0 +1,2 @@ +#define MAX_LENGTH 100 +#define CUSTOMER_DATA_FILE "CustomerData.txt" \ No newline at end of file diff --git a/src/a.exe b/src/a.exe new file mode 100644 index 0000000..7bbd2e2 Binary files /dev/null and b/src/a.exe differ diff --git a/src/currentCustomerAccountBalance.c b/src/currentCustomerAccountBalance.c new file mode 100644 index 0000000..a91e306 --- /dev/null +++ b/src/currentCustomerAccountBalance.c @@ -0,0 +1,63 @@ +#include "currentCustomerAccountBalance.h" + +float fetchBalanceFromBalanceString(char balance_String[MAX_LENGTH]) { + float balance = 0; + char *token = strtok(balance_String, "="); // separates string to two parts + while (token != NULL) { + if (atoi(token) != 0) { + balance = atof(token); // converts string to float + break; + } + token = strtok(NULL, "="); + } + return balance; +} + +float readFileAndGetAvailableBalance(FILE *file, char stringID[MAX_LENGTH]) { + float balance = 0; + bool keep_reading = true; + char buffer[MAX_LENGTH]; + char balance_String[MAX_LENGTH]; + + while(keep_reading) { + fgets(buffer, MAX_LENGTH, file); + if (feof(file)) { + keep_reading = false; + } + else if(strstr(buffer, stringID)) { + for (int i = 0; i < 4; i++) { + fgets(buffer, MAX_LENGTH, file); + } + strcpy(balance_String, buffer); + balance = fetchBalanceFromBalanceString(balance_String); + keep_reading = false; + } + + } + return balance; +} + +float getAvailableAccountBalance(int user_id) { + float availableBalance = 0; + char stringID[MAX_LENGTH] = "ID="; + char user_id_as_string[MAX_LENGTH]; + + sprintf(user_id_as_string, "%d", user_id); // converts user_id to string + strcat(stringID, user_id_as_string); + // Now stringID is "ID=user_id" + + FILE *file = fopen(CUSTOMER_DATA_FILE, "r"); + if(file == 0) { + printf("Error: customer data file cannot be opened!\n"); + return 0; + } + else { + availableBalance = readFileAndGetAvailableBalance(file, stringID); + } + + + fclose(file); + + return availableBalance; + +} \ No newline at end of file diff --git a/src/currentCustomerAccountBalance.h b/src/currentCustomerAccountBalance.h new file mode 100644 index 0000000..2795450 --- /dev/null +++ b/src/currentCustomerAccountBalance.h @@ -0,0 +1,10 @@ +#include +#include +#include +#include + +#include "_file_information.h" + +float getAvailableAccountBalance(int user_id); +float fetchBalanceFromBalanceString(char balance_String[MAX_LENGTH]); +float readFileAndGetAvailableBalance(FILE *file, char stringID[MAX_LENGTH]); \ No newline at end of file diff --git a/src/lineReplacer.h b/src/lineReplacer.h new file mode 100644 index 0000000..999855c --- /dev/null +++ b/src/lineReplacer.h @@ -0,0 +1,6 @@ +#include +#include +#include +#include + +void replaceLineInFile(const char* file_name, int line, const char* new_line); //replaces the line at "line" on the file "file_name", with the new line "new_line". \ No newline at end of file diff --git a/src/main.c b/src/main.c index a6b9b24..3e233a1 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,8 @@ #include +#include"mainMenu.h" -int main() { - +int main() +{ + ageInput(); return 0; -} \ No newline at end of file +} diff --git a/src/mainMenu.c b/src/mainMenu.c new file mode 100644 index 0000000..9bdfccb --- /dev/null +++ b/src/mainMenu.c @@ -0,0 +1,93 @@ + +#include"mainMenu.h" + + +bool agePermission(int age){ + + if(age >= 18) + { + + return true; + + } + + else + { + + return false; + + } + +} + +bool checkIfInteger(char* input){ + + char *end_pointer; + + strtol(input, &end_pointer, 10); + + if (end_pointer == input || *end_pointer != '\0') + { + + return false; + + } + + else + { + + return true; + + } +} + +void ageInput(){ + + char input[20]; + char* input_pointer; + + long age; + + printf("\nPlease specify your age : "); + scanf("%s",input); + + if (checkIfInteger(input) == true ) + { + age = strtol(input,&input_pointer,10); + + if(agePermission(age)== true) + { + printf("Access granted!\n\n\n\n"); + + showMenu(); + + } + else if(agePermission(age)== false) + { + + printf("You should be at least 18 years old to create a bank account!\n"); + + } + } + + else + { + + printf("input invalid! try again!\n"); + + } + +} + + +void showMenu(){ + + printf("\t\t\t\t\t\t\t Welcome to Bank Manager!"); + printf("\n\n\n\n\t\t\t\t\t\tPlease select one of the following functions!"); + printf("\n\n\n\n\t\t\t\t\t\t ->Login as an existing costumer."); + printf("\n\n\t\t\t\t\t\t ->Register as a new costumer."); + printf("\n\n\t\t\t\t\t\t ->Login as an Employee."); + printf("\n\n\t\t\t\t\t\t\t\t ->Exit.\n"); + printf("\n\n\n\n\n Selection :\n"); + +} diff --git a/src/mainMenu.h b/src/mainMenu.h new file mode 100644 index 0000000..f62dda9 --- /dev/null +++ b/src/mainMenu.h @@ -0,0 +1,15 @@ +#ifndef MAINMENU_H_ +#define MAINMENU_H_ + +#include +#include +#include +#include + +void showMenu(); +void ageInput(); + +bool agePermission(int age); +bool checkIfInteger(char* input); + +#endif diff --git a/src/updateCustomerAccountBalance.c b/src/updateCustomerAccountBalance.c new file mode 100644 index 0000000..6986e08 --- /dev/null +++ b/src/updateCustomerAccountBalance.c @@ -0,0 +1,84 @@ +#include "updateCustomerAccountBalance.h" +#include "currentCustomerAccountBalance.c" +#include "lineReplacer.h" + +void replaceLineInFile(const char* file_name, int line, const char* new_line){ + FILE* file = fopen(file_name, "r"); + if (file == NULL) { + printf("Error opening file!\n"); + return; + } + char current_string[100]; + int current_line = 1; + char *temp_file_name = calloc(8+1, sizeof(char)); + temp_file_name = "temp.txt"; + FILE* temp_file = fopen(temp_file_name, "w"); + if (temp_file == NULL) { + printf("Error creating temp file!\n"); + fclose(file); + return; + } + while (fgets(current_string, sizeof(current_string),file) != NULL) { + if (current_line == line) { + fprintf(temp_file, "%s\n", new_line); + //fputs("\n", temp_file); + } else { + fprintf(temp_file, "%s", current_string); + } + current_line++; + } + fclose(file); + fclose(temp_file); + if(remove(file_name)!=0){ + printf("could not remove the original file!"); + } // Remove the original file + if(rename(temp_file_name, file_name)!=0){ + printf("could not rename!"); + } // Rename the temp file to the original file +} + +void replaceBalanceInString(float replacementBalance, int currentLine) { + char newBalanceLine[MAX_LENGTH] = "balance="; + char balance_as_string[MAX_LENGTH]; + sprintf(balance_as_string, "%f", replacementBalance); //converts replacement balance to string + strcat(newBalanceLine, balance_as_string); + replaceLineInFile("CustomerData.txt",currentLine,newBalanceLine); +} + +bool updateAvailableAccountBalance(int user_id, float newBalance){ + + bool keep_reading = true; + + char *buffer = malloc(MAX_LENGTH * sizeof(char)); + char *stringID = malloc(MAX_LENGTH * sizeof(char)); + stringID = "ID="; + char *user_id_as_string =malloc(MAX_LENGTH * sizeof(char)); + char *balance_String = malloc(MAX_LENGTH * sizeof(char)); + int currentLine=0; + + sprintf(user_id_as_string, "%d", user_id); // converts user_id to string + strcat(stringID, user_id_as_string); + + FILE *file = fopen("CustomerData.txt", "r"); + //printf(stringID); + while(keep_reading) { + fgets(buffer, MAX_LENGTH, file); + currentLine++; + if (feof(file)) { + keep_reading = false; + } + else if(strstr(buffer, stringID)) { //found the customer + fgets(buffer, MAX_LENGTH, file); + fgets(buffer, MAX_LENGTH, file); + fgets(buffer, MAX_LENGTH, file); + fgets(buffer, MAX_LENGTH, file); + strcpy(balance_String, buffer); + currentLine+=4; + keep_reading = false; + } + + } + fclose(file);; + replaceBalanceInString(newBalance,currentLine); + return true; +} diff --git a/src/updateCustomerAccountBalance.h b/src/updateCustomerAccountBalance.h new file mode 100644 index 0000000..29f5b75 --- /dev/null +++ b/src/updateCustomerAccountBalance.h @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +#define MAX_LENGTH 100 + + +bool updateAvailableAccountBalance(int user_id, float newBalance); + +void replaceBalanceInString(float replacementBalance, int currentLine); diff --git a/tests/support/.gitkeep b/tests/support/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_updateCustomerAccountBalance.c b/tests/test_updateCustomerAccountBalance.c new file mode 100644 index 0000000..add1299 --- /dev/null +++ b/tests/test_updateCustomerAccountBalance.c @@ -0,0 +1,34 @@ +#ifdef TEST + +#include "unity.h" + +#include "updateCustomerAccountBalance.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_updateAvailableAccountBalanceSuccess(void){ + + int id1 = 1234; + int id2 = 1327; + int id3 = 1666; + + int newBalance1=500; + int newBalance2=800; + int newBalance3=700; + + bool results1=updateAvailableAccountBalance(id1,newBalance1); + bool results2=updateAvailableAccountBalance(id2,newBalance2); + bool results3=updateAvailableAccountBalance(id3,newBalance3); + + TEST_ASSERT_TRUE(results1); + TEST_ASSERT_TRUE(results2); + TEST_ASSERT_TRUE(results3); + +} +#endif