Browse Source

Merge branch 'feature/update-current-customer-account-balance' into feature/balance-operations

remotes/origin/feature/transfer-money
fdlt3817 2 years ago
parent
commit
83c6c9a9b7
  1. 1
      .gitignore
  2. 3
      build-project.sh
  3. 3
      build/test/cache/defines_dependency.yml
  4. 242
      build/test/cache/input.yml
  5. 63
      build/test/cache/test_updateCustomerAccountBalance.c
  6. 6
      build/test/dependencies/cmock.d
  7. 5
      build/test/dependencies/test_updateCustomerAccountBalance.d
  8. 4
      build/test/dependencies/test_updateCustomerAccountBalance_runner.d
  9. 4
      build/test/dependencies/unity.d
  10. 5
      build/test/dependencies/updateCustomerAccountBalance.d
  11. BIN
      build/test/out/c/cmock.o
  12. BIN
      build/test/out/c/test_updateCustomerAccountBalance.o
  13. BIN
      build/test/out/c/test_updateCustomerAccountBalance_runner.o
  14. BIN
      build/test/out/c/unity.o
  15. BIN
      build/test/out/c/updateCustomerAccountBalance.o
  16. BIN
      build/test/out/test_updateCustomerAccountBalance.out
  17. 63
      build/test/preprocess/files/test_updateCustomerAccountBalance.c
  18. 3
      build/test/preprocess/includes/test_updateCustomerAccountBalance.c
  19. 81
      build/test/runners/test_updateCustomerAccountBalance_runner.c
  20. 101
      project.yml
  21. 20
      src/CustomerData.txt
  22. 4
      src/CustomerProperties.h
  23. 97
      src/LoginCustomer.c
  24. 10
      src/LoginCustomer.h
  25. 2
      src/_file_information.h
  26. BIN
      src/a.exe
  27. 63
      src/currentCustomerAccountBalance.c
  28. 10
      src/currentCustomerAccountBalance.h
  29. 6
      src/lineReplacer.h
  30. 6
      src/main.c
  31. 93
      src/mainMenu.c
  32. 15
      src/mainMenu.h
  33. 84
      src/updateCustomerAccountBalance.c
  34. 11
      src/updateCustomerAccountBalance.h
  35. 0
      tests/support/.gitkeep
  36. 34
      tests/test_updateCustomerAccountBalance.c

1
.gitignore

@ -1 +1,2 @@
.DS_Store .DS_Store
.vscode

3
build-project.sh

@ -1,5 +1,6 @@
clear clear
ceedling test:all
cd src/ cd src/
gcc main.c
gcc main.c mainMenu.c
./a.out ./a.out
rm a.out rm a.out

3
build/test/cache/defines_dependency.yml

@ -0,0 +1,3 @@
---
src/updateCustomerAccountBalance.c:
- TEST

242
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/

63
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);
}

6
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

5
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

4
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

4
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

5
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

BIN
build/test/out/c/cmock.o

BIN
build/test/out/c/test_updateCustomerAccountBalance.o

BIN
build/test/out/c/test_updateCustomerAccountBalance_runner.o

BIN
build/test/out/c/unity.o

BIN
build/test/out/c/updateCustomerAccountBalance.o

BIN
build/test/out/test_updateCustomerAccountBalance.out

63
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);
}

3
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

81
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();
}

101
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
...

20
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

4
src/CustomerProperties.h

@ -0,0 +1,4 @@
typedef struct Customer{
char *ID, *forename, *surname, *password;
float balance;
}customer_t;

97
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<IDMaxLength){
if(digitCharacterFromUser>='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){
*(c.password+passwordLengthCounter) = passwordCharacterFromUser;
++passwordLengthCounter;
}
*(c.password+passwordLengthCounter) = '\0';
if(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;
}

10
src/LoginCustomer.h

@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "CustomerProperties.h"
#define MAX_LOGIN_ATTEMPTS 3
char *generateCheckString(char *, char*);
bool checkLogin(bool);
void collectCustomerDataForLogin(int);
bool loginCustomer(customer_t *);

2
src/_file_information.h

@ -0,0 +1,2 @@
#define MAX_LENGTH 100
#define CUSTOMER_DATA_FILE "CustomerData.txt"

BIN
src/a.exe

63
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;
}

10
src/currentCustomerAccountBalance.h

@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include "_file_information.h"
float getAvailableAccountBalance(int user_id);
float fetchBalanceFromBalanceString(char balance_String[MAX_LENGTH]);
float readFileAndGetAvailableBalance(FILE *file, char stringID[MAX_LENGTH]);

6
src/lineReplacer.h

@ -0,0 +1,6 @@
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
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".

6
src/main.c

@ -1,6 +1,8 @@
#include <stdio.h> #include <stdio.h>
#include"mainMenu.h"
int main() {
int main()
{
ageInput();
return 0; return 0;
} }

93
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");
}

15
src/mainMenu.h

@ -0,0 +1,15 @@
#ifndef MAINMENU_H_
#define MAINMENU_H_
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
void showMenu();
void ageInput();
bool agePermission(int age);
bool checkIfInteger(char* input);
#endif

84
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;
}

11
src/updateCustomerAccountBalance.h

@ -0,0 +1,11 @@
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH 100
bool updateAvailableAccountBalance(int user_id, float newBalance);
void replaceBalanceInString(float replacementBalance, int currentLine);

0
tests/support/.gitkeep

34
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
Loading…
Cancel
Save