diff --git a/.github/workflows/check-homework.yml b/.github/workflows/check-homework.yml
index 5696ca6..9a98b6b 100644
--- a/.github/workflows/check-homework.yml
+++ b/.github/workflows/check-homework.yml
@@ -3,168 +3,8 @@ name: CI
on: [pull_request]
jobs:
- add_progress_bar_comment:
- runs-on: ubuntu-latest
- steps:
- - name: Find Comment
- uses: peter-evans/find-comment@v1
- id: fc
- with:
- issue-number: ${{ github.event.pull_request.number }}
- comment-author: 'github-actions[bot]'
- body-includes: With ❤️ from Homework Bot 🤖
- - name: Create comment
- if: steps.fc.outputs.comment-id == ''
- uses: peter-evans/create-or-update-comment@v1
- with:
- comment-id: ${{ steps.fc.outputs.comment-id }}
- issue-number: ${{ github.event.pull_request.number }}
- body: |
- ## Tests are running! Please wait!
-
- ![Progress gif](https://cdn.dribbble.com/users/2015153/screenshots/6592242/progess-bar2.gif)
-
- > Progress gif from https://dribbble.com/shots/6592242-Please-wait-Animation#
-
- With ❤️ from Homework Bot 🤖
- - name: Update comment
- if: steps.fc.outputs.comment-id != ''
- uses: peter-evans/create-or-update-comment@v1
- with:
- comment-id: ${{ steps.fc.outputs.comment-id }}
- edit-mode: replace
- body: |
- ## Tests are running! Please wait!
-
- ![Progress gif](https://cdn.dribbble.com/users/2015153/screenshots/6592242/progess-bar2.gif)
-
- > Progress gif from https://dribbble.com/shots/6592242-Please-wait-Animation#
-
- With ❤️ from Homework Bot 🤖
-
- check_homework:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout this homework
- uses: actions/checkout@v2
- with:
- path: homework
- - name: Checkout homework definitions
- uses: actions/checkout@v2
- with:
- repository: cpp-for-yourself/homework-definitions
- path: definitions
- - name: Set up Python
- uses: actions/setup-python@v2
- with:
- python-version: '3.8'
- architecture: 'x64'
- - name: Install prerequisites
- run: |
- sudo apt install -y libgtest-dev
- python -m pip install --upgrade pip pipenv ruamel.yaml schema homework-checker
- - name: Run tests
- run: |
- mkdir checker
- cp definitions/homework.yml checker/
- cp -r homework/homeworks checker/
- cd checker
- check_homework -v -i homework.yml -o results.md
- - name: Upload result md file
- uses: actions/upload-artifact@v2
- with:
- name: homework_result
- path: checker/results.md
-
- upload_results_as_comment:
- needs: check_homework
- runs-on: ubuntu-latest
- steps:
- - name: Download result md file
- uses: actions/download-artifact@v2
- with:
- name: homework_result
- - name: Render template
- id: template
- uses: chuhlomin/render-template@v1.2
- with:
- template: results.md
- - name: Find Comment
- uses: peter-evans/find-comment@v1
- id: fc
- with:
- issue-number: ${{ github.event.pull_request.number }}
- comment-author: 'github-actions[bot]'
- body-includes: With ❤️ from Homework Bot 🤖
- - name: Update comment with test results
- uses: peter-evans/create-or-update-comment@v1
- with:
- comment-id: ${{ steps.fc.outputs.comment-id }}
- issue-number: ${{ github.event.pull_request.number }}
- body: ${{ steps.template.outputs.result }}
- edit-mode: replace
-
- upload_results_to_wiki:
- needs: check_homework
- runs-on: ubuntu-latest
- steps:
- - name: Download result md file
- uses: actions/download-artifact@v2
- with:
- name: homework_result
- - name: Find Comment
- uses: peter-evans/find-comment@v1
- id: fc
- with:
- issue-number: ${{ github.event.pull_request.number }}
- comment-author: 'github-actions[bot]'
- body-includes: With 💙 from Homework Bot 🤖
- - name: Checkout wiki
- uses: actions/checkout@v2
- with:
- repository: ${{ github.repository }}.wiki
- path: wiki
- - name: Upload result to wiki
- run: |
- echo \`\`\` > wiki/Home.md
- echo Author: ${{ github.actor }} >> wiki/Home.md
- echo Branch: ${{ github.head_ref }} >> wiki/Home.md
- echo Commit: ${{ github.sha }} >> wiki/Home.md
- echo \`\`\` >> wiki/Home.md
- cat results.md >> wiki/Home.md
- cd wiki
- git config user.name homework-bot
- git config user.email homework-bot@github.com
- git add .
- git commit -m "Update results" --allow-empty
- git push
- - name: Comment on wiki access failure
- uses: peter-evans/create-or-update-comment@v1
- if: failure()
- with:
- comment-id: ${{ steps.fc.outputs.comment-id }}
- issue-number: ${{ github.event.pull_request.number }}
- body: |
- # ‼️ Wiki is empty ‼️
-
- To fix this error you will have to perform the following actions once:
- 1. Create _any_ (even empty) page in the wiki by clicking this link: ${{ github.server_url }}/${{ github.repository }}/wiki/_new
- 2. Rerun the actions by clicking the 🔄 Re-run all jobs button here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
-
- ---
-
- With 💙 from Homework Bot 🤖
- edit-mode: replace
- - name: Comment on wiki access success
- uses: peter-evans/create-or-update-comment@v1
- if: success()
- with:
- comment-id: ${{ steps.fc.outputs.comment-id }}
- issue-number: ${{ github.event.pull_request.number }}
- body: |
- # ✅ Wiki is available
-
- Check it out at: ${{ github.server_url }}/${{ github.repository }}/wiki
-
- With 💙 from Homework Bot 🤖
- edit-mode: replace
+ run_all_tests:
+ name: Run all tests
+ uses: cpp-for-yourself/ci-jobs/.github/workflows/check-homework.yml@main
+ with:
+ homework-definitions-branch: main
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..e49f5b2
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "homeworks/homework_4/no_strings_attached/external/googletest"]
+ path = homeworks/homework_4/no_strings_attached/external/googletest
+ url = https://github.com/google/googletest.git
diff --git a/homeworks/homework_4/no_strings_attached/CMakeLists.txt b/homeworks/homework_4/no_strings_attached/CMakeLists.txt
new file mode 100644
index 0000000..acac191
--- /dev/null
+++ b/homeworks/homework_4/no_strings_attached/CMakeLists.txt
@@ -0,0 +1,29 @@
+cmake_minimum_required(VERSION 3.16..3.24)
+project(no_strings_attached VERSION 1
+ DESCRIPTION "Writing a string processing library"
+ LANGUAGES CXX)
+
+if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
+endif()
+
+message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
+
+add_library(cxx_setup INTERFACE)
+target_compile_options(cxx_setup INTERFACE -Wall -Wpedantic -Wextra)
+target_compile_features(cxx_setup INTERFACE cxx_std_17)
+target_include_directories(cxx_setup INTERFACE ${PROJECT_SOURCE_DIR})
+
+# Update the submodules here
+include(external/UpdateSubmodules.cmake)
+
+# Enable testing for this project
+include(CTest)
+
+# 🚨 Make sure CMakeLists.txt file exists in the subdirectories!
+add_subdirectory(examples)
+add_subdirectory(external)
+add_subdirectory(${PROJECT_NAME})
+
+
+
diff --git a/homeworks/homework_4/no_strings_attached/compile_run_bash.sh b/homeworks/homework_4/no_strings_attached/compile_run_bash.sh
new file mode 100644
index 0000000..ba592a9
--- /dev/null
+++ b/homeworks/homework_4/no_strings_attached/compile_run_bash.sh
@@ -0,0 +1,22 @@
+echo " ******** Current working directory ******** "
+pwd
+echo " -------- -------- -------- -------- -------- -------- -------- -------- -------- --------"
+
+echo " ******** BUILD directory ******** "
+rm -r build
+mkdir build
+echo " -------- -------- -------- -------- -------- -------- -------- -------- -------- --------"
+
+echo " ******** CMAKE ******** "
+cmake -S . -B build
+cmake --build build
+echo " -------- -------- -------- -------- -------- -------- -------- -------- -------- --------"
+
+echo " ******** Google Test ********"
+GTEST_COLOR=1 ctest --test-dir build --output-on-failure
+#GTEST_COLOR=1 ctest --test-dir build --verbose
+echo " -------- -------- -------- -------- -------- -------- -------- -------- -------- --------"
+
+#echo " ******** Run Binary ********"
+#./build/examples/split_strings
+echo " -------- -------- -------- -------- -------- -------- -------- -------- -------- --------"
\ No newline at end of file
diff --git a/homeworks/homework_4/no_strings_attached/examples/CMakeLists.txt b/homeworks/homework_4/no_strings_attached/examples/CMakeLists.txt
new file mode 100644
index 0000000..b689a0a
--- /dev/null
+++ b/homeworks/homework_4/no_strings_attached/examples/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_executable(split_strings split_strings.cpp)
+target_link_libraries(split_strings PRIVATE cxx_setup string_split)
+
+add_executable(trim_strings trim_strings.cpp)
+target_link_libraries(trim_strings PRIVATE cxx_setup string_trim)
\ No newline at end of file
diff --git a/homeworks/homework_4/no_strings_attached/examples/split_strings.cpp b/homeworks/homework_4/no_strings_attached/examples/split_strings.cpp
new file mode 100644
index 0000000..f3359a2
--- /dev/null
+++ b/homeworks/homework_4/no_strings_attached/examples/split_strings.cpp
@@ -0,0 +1,33 @@
+#include
+#include
+#include
+#include
+
+int main(){
+
+std::string string_to_be_splitted;
+std::string delimiter = " ";
+int number_of_chunks_to_keep = 2;
+
+std::cout << "Example program that splits strings."< Splitted_string = no_strings_attached::Split(string_to_be_splitted,delimiter);
+std::cout << "Your split string: ";
+for(auto index1:Splitted_string) {
+ std::cout <<"'"<< index1 <<"'"<<' ';
+ }
+
+std::cout < Splitted_string2 = no_strings_attached::Split(string_to_be_splitted,delimiter,number_of_chunks_to_keep);
+// std::cout << "Your split string2: ";
+// for(auto index2:Splitted_string2) {
+// std::cout <<"'"<< index2 <<"'"<<' ';
+// }
+
+// std::cout <
+#include
+#include
+#include
+
+using no_strings_attached::Side;
+
+int main(){
+
+std::string string_to_be_trimmed;
+char char_to_trim =' ';
+
+std::cout << "Example program that trims strings."<
+#include
+#include
+#include
+
+
+namespace no_strings_attached{
+
+ std::vector Split(const std::string& str, const std::string& delimiter){
+ //std::cout << " Debug : function entry "< Nend-1){
+ split_string = "";
+
+ }else{
+ split_string = str.substr(Nstart+next_start,Nend-(Nstart+next_start));
+ //std::cout << " Debug : @middle "< Split(const std::string& str, const std::string& delimiter, int number_of_chunks_to_keep){
+
+ int next_start = delimiter.size();
+
+ //std::cout << " Debug : next_start = "< n_vec;
+
+ std::vector container;
+
+ std::string split_string;
+ std::string string_init = str;
+
+ // To find indexes of all delimiter (METHOD 2)
+ if (string_init.find(delimiter) != std::string::npos){
+ n = 0;
+ //std::cout << "Debug: found delimiter"< Nend-1){
+ split_string = "";
+
+ }else{
+ split_string = str.substr(Nstart+next_start,Nend-(Nstart+next_start));
+ //std::cout << " Debug : @middle "< number_of_chunks_to_keep){
+ container.resize(number_of_chunks_to_keep) ;
+ }
+
+ return container;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/homeworks/homework_4/no_strings_attached/no_strings_attached/string_split.h b/homeworks/homework_4/no_strings_attached/no_strings_attached/string_split.h
new file mode 100644
index 0000000..fcda43b
--- /dev/null
+++ b/homeworks/homework_4/no_strings_attached/no_strings_attached/string_split.h
@@ -0,0 +1,10 @@
+#include
+#include
+#pragma once
+
+namespace no_strings_attached{
+
+ std::vector Split(const std::string& , const std::string& );
+ std::vector Split(const std::string& , const std::string& , int);
+
+}
\ No newline at end of file
diff --git a/homeworks/homework_4/no_strings_attached/no_strings_attached/string_split_test.cpp b/homeworks/homework_4/no_strings_attached/no_strings_attached/string_split_test.cpp
new file mode 100644
index 0000000..86c9822
--- /dev/null
+++ b/homeworks/homework_4/no_strings_attached/no_strings_attached/string_split_test.cpp
@@ -0,0 +1,56 @@
+#include
+#include
+#include
+#include
+
+// TEST is a macro, i.e., preprocessor replaces it with some code
+namespace {
+using no_strings_attached::Split;
+}
+
+TEST(SplitValidationTest, SplitDelimeterNotFound) {
+ auto test_string = "";
+ const auto split_on_empty = Split("", " ");
+ ASSERT_FALSE(split_on_empty.empty())
+ << "Failed to split: '" << test_string << "'";
+ EXPECT_EQ("", split_on_empty.front())
+ << "Failed to split: '" << test_string << "'";
+ test_string = "hello";
+ const auto split_no_space = Split(test_string, " ");
+ ASSERT_FALSE(split_no_space.empty())
+ << "Failed to split: '" << test_string << "'";
+ EXPECT_EQ("hello", split_no_space.front())
+ << "Failed to split: '" << test_string << "'";
+}
+
+TEST(SplitValidationTest, SplitTwoWordsOnString) {
+ const auto test_string = "hello world";
+ const auto split = Split(test_string, " ");
+ ASSERT_EQ(2UL, split.size()) << "Failed to split: '" << test_string << "'";
+ EXPECT_EQ("hello", split.front())
+ << "Failed to split: '" << test_string << "'";
+ EXPECT_EQ("world", split.back())
+ << "Failed to split: '" << test_string << "'";
+}
+
+TEST(SplitValidationTest, SplitMoreWords) {
+ const auto test_string = "some_string__split__with_underscores";
+ const auto split = Split(test_string, "__");
+ ASSERT_EQ(3UL, split.size()) << "Failed to split: '" << test_string << "'";
+ EXPECT_EQ("some_string", split[0])
+ << "Failed to split: '" << test_string << "'";
+ EXPECT_EQ("split", split[1]) << "Failed to split: '" << test_string << "'";
+ EXPECT_EQ("with_underscores", split[2])
+ << "Failed to split: '" << test_string << "'";
+}
+
+TEST(SplitValidationTest, RepeatedString) {
+ const auto test_string = "split_me__and_me";
+ const auto split = Split(test_string, "_");
+ ASSERT_EQ(5UL, split.size()) << "Failed to split: '" << test_string << "'";
+ EXPECT_EQ("split", split[0]) << "Failed to split: '" << test_string << "'";
+ EXPECT_EQ("me", split[1]) << "Failed to split: '" << test_string << "'";
+ EXPECT_EQ("", split[2]) << "Failed to split: '" << test_string << "'";
+ EXPECT_EQ("and", split[3]) << "Failed to split: '" << test_string << "'";
+ EXPECT_EQ("me", split[4]) << "Failed to split: '" << test_string << "'";
+}
diff --git a/homeworks/homework_4/no_strings_attached/no_strings_attached/string_trim.cpp b/homeworks/homework_4/no_strings_attached/no_strings_attached/string_trim.cpp
new file mode 100644
index 0000000..649efea
--- /dev/null
+++ b/homeworks/homework_4/no_strings_attached/no_strings_attached/string_trim.cpp
@@ -0,0 +1,115 @@
+#include
+#include
+#include
+
+namespace no_strings_attached{
+
+ //A function that allows trimming strings from a given direction:
+ std::string Trim(const std::string& str, char char_to_trim, Side side){
+
+ int next_start = 1; // since char type
+
+ int start_index, end_index, count;
+
+ std::string trim_str_init = str;
+
+ if(trim_str_init.find(char_to_trim) != std::string::npos){
+
+ switch(side){
+
+ case Side::kLeft:
+ if((start_index = trim_str_init.find_first_of(char_to_trim)) == 0){
+
+ end_index = trim_str_init.find_first_not_of(char_to_trim,start_index);
+ count = end_index-start_index;
+ trim_str_init.replace(start_index, count, "");
+ return trim_str_init;
+
+ }else{
+
+ return str;
+ }
+ break;
+
+ case Side::kRight:
+ if((start_index = trim_str_init.find_last_of(char_to_trim)) == trim_str_init.size()-1){
+
+ end_index = trim_str_init.find_last_not_of(char_to_trim); //find_last_not_of( const basic_string& str,size_type pos = npos )
+ count = start_index - end_index;
+ trim_str_init.replace(end_index+next_start, count, "");
+ return trim_str_init;
+
+ }else{
+
+ return str;
+ }
+ break;
+
+ case Side::kBoth:
+ if((start_index = trim_str_init.find_first_of(char_to_trim)) == 0){
+
+ end_index = trim_str_init.find_first_not_of(char_to_trim,start_index);
+ count = end_index-start_index;
+ trim_str_init.replace(start_index, count, "");
+ }
+
+ if((start_index = trim_str_init.find_last_of(char_to_trim)) == trim_str_init.size()-1){
+
+ end_index = trim_str_init.find_last_not_of(char_to_trim); //find_last_not_of( const basic_string& str,size_type pos = npos )
+ count = start_index - end_index;
+ trim_str_init.replace(end_index+next_start, count, "");
+
+ }
+ return trim_str_init;
+ break;
+
+
+ }
+
+ }else{
+ return str;
+ }
+
+
+
+ }
+
+
+
+
+
+ // An overload of this function function that allows trimming spaces from both sides:
+ std::string Trim(const std::string& str){
+
+ int next_start = 1; // since space character
+
+ int start_index, end_index, count;
+
+ std::string trim_str_init = str;
+
+ std::string char_to_trim = " "; // space character
+
+ if(trim_str_init.find(char_to_trim) != std::string::npos){
+
+ if((start_index = trim_str_init.find_first_of(char_to_trim)) == 0){
+
+ end_index = trim_str_init.find_first_not_of(char_to_trim,start_index);
+ count = end_index-start_index;
+ trim_str_init.replace(start_index, count, "");
+ }
+
+ if((start_index = trim_str_init.find_last_of(char_to_trim)) == trim_str_init.size()-1){
+
+ end_index = trim_str_init.find_last_not_of(char_to_trim); //find_last_not_of( const basic_string& str,size_type pos = npos )
+ count = start_index - end_index;
+ trim_str_init.replace(end_index+next_start, count, "");
+
+ }
+ return trim_str_init;
+
+ }else{
+ return str;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/homeworks/homework_4/no_strings_attached/no_strings_attached/string_trim.h b/homeworks/homework_4/no_strings_attached/no_strings_attached/string_trim.h
new file mode 100644
index 0000000..6960889
--- /dev/null
+++ b/homeworks/homework_4/no_strings_attached/no_strings_attached/string_trim.h
@@ -0,0 +1,12 @@
+#include
+#include
+#pragma once
+
+namespace no_strings_attached{
+
+ enum class Side {kLeft,kRight,kBoth}; // 💡 This enum class should be defined here (not in string_trim.cpp)
+
+ std::string Trim(const std::string& , char , Side);
+ std::string Trim(const std::string& );
+
+}
diff --git a/homeworks/homework_4/no_strings_attached/no_strings_attached/string_trim_test.cpp b/homeworks/homework_4/no_strings_attached/no_strings_attached/string_trim_test.cpp
new file mode 100644
index 0000000..89ea752
--- /dev/null
+++ b/homeworks/homework_4/no_strings_attached/no_strings_attached/string_trim_test.cpp
@@ -0,0 +1,56 @@
+#include
+#include
+#include
+#include
+
+namespace {
+using no_strings_attached::Side;
+using no_strings_attached::Trim;
+} // namespace
+
+TEST(TrimValidationTest, TrimEmpty) {
+ const auto test_string = "";
+ const auto trimmed_both_sides = Trim(test_string);
+ const auto trimmed_both_sides_explicit = Trim(test_string, ' ', Side::kBoth);
+ const auto trimmed_left_side = Trim(test_string, ' ', Side::kLeft);
+ const auto trimmed_right_side = Trim(test_string, ' ', Side::kRight);
+ EXPECT_EQ(trimmed_both_sides, test_string);
+ EXPECT_EQ(trimmed_both_sides_explicit, test_string);
+ EXPECT_EQ(trimmed_left_side, test_string);
+ EXPECT_EQ(trimmed_right_side, test_string);
+}
+
+TEST(TrimValidationTest, TrimTrivial) {
+ const auto test_string = "hello";
+ const auto trimmed_both_sides = Trim(test_string);
+ const auto trimmed_both_sides_explicit = Trim(test_string, ' ', Side::kBoth);
+ const auto trimmed_left_side = Trim(test_string, ' ', Side::kLeft);
+ const auto trimmed_right_side = Trim(test_string, ' ', Side::kRight);
+ EXPECT_EQ(trimmed_both_sides, test_string)
+ << "Failed to trim string: '" << test_string << "'";
+ EXPECT_EQ(trimmed_both_sides_explicit, test_string)
+ << "Failed to trim string: '" << test_string << "'";
+ EXPECT_EQ(trimmed_left_side, test_string)
+ << "Failed to trim string: '" << test_string << "'";
+ EXPECT_EQ(trimmed_right_side, test_string)
+ << "Failed to trim string: '" << test_string << "'";
+}
+
+TEST(TrimValidationTest, TrimCorrect) {
+ const auto test_string = " hello ";
+ const auto trimmed_both_sides = Trim(test_string);
+ const auto trimmed_both_sides_explicit = Trim(test_string, ' ', Side::kBoth);
+ const auto trimmed_left_side = Trim(test_string, ' ', Side::kLeft);
+ const auto trimmed_right_side = Trim(test_string, ' ', Side::kRight);
+ const auto expected_both_trimmed = "hello";
+ EXPECT_EQ(trimmed_both_sides, expected_both_trimmed)
+ << "Failed to trim string: '" << test_string << "'";
+ EXPECT_EQ(trimmed_both_sides_explicit, expected_both_trimmed)
+ << "Failed to trim string: '" << test_string << "'";
+ const auto expected_left_trimmed = "hello ";
+ EXPECT_EQ(trimmed_left_side, expected_left_trimmed)
+ << "Failed to trim string: '" << test_string << "'";
+ const auto expected_right_trimmed = " hello";
+ EXPECT_EQ(trimmed_right_side, expected_right_trimmed)
+ << "Failed to trim string: '" << test_string << "'";
+}
\ No newline at end of file