TEST(TodoList, Throws_When_Get_By_Invalid_Pos) { // Arrange TodoList list; // Act & Assert EXPECT_THROW(list.getItem(100500), out_of_range); }
// virtual void SetUp() {} void ActWithExistingFile(vector<string> args_) { vector<const char*> options; TodoList list; TodoItem temp; temp.setTitle("abc"); temp.setPriority(1); temp.setText("abc text"); list.addItem(temp); temp.setTitle("def"); temp.setPriority(2); temp.setText(""); list.addItem(temp); temp.setTitle("gik"); temp.setPriority(1); list.addItem(temp); list.save("test.txt"); options.push_back("appname"); for (size_t i = 0; i < args_.size(); ++i) { options.push_back(args_[i].c_str()); } const char** argv = &options.front(); int argc = static_cast<int>(args_.size()) + 1; output_ = app_(argc, argv); }
// This function does the actual solving. void solvePuzzle(PuzzleState *start, TodoList<PuzzleState*> &active, PredDict<PuzzleState*> &seen, vector<PuzzleState*> &solution) { PuzzleState *state; PuzzleState *temp; active.add(start); // Must explore the successors of the start state. seen.add(start,NULL); // We've seen this state. It has no predecessor. while (!active.is_empty()) { // Loop Invariants: // 'seen' contains the set of puzzle states that we know how to reach. // 'active' contains the set of puzzle states that we know how to reach, // and whose successors we might not have explored yet. state = active.remove(); // Note: Do not delete this, as this PuzzleState is also in 'seen' // uncomment the next two lines for debugging, if you'd like! // cout << "Exploring State: \n"; // state->print(cout); // cin.get(); if (state->isSolution()) { // Found a solution! cout << "Found solution! \n"; state->print(cout); // Follow predecessors to construct path to solution. temp = state; while (temp!=NULL) { solution.push_back(temp); // Guaranteed to succeed, because these states must have been // added to dictionary already. seen.find(temp,temp); } return; } vector<PuzzleState*> nextMoves = state->getSuccessors(); for (unsigned int i=0; i < nextMoves.size(); i++) { if (!seen.find(nextMoves[i], temp)) { // Never seen this state before. Add it to 'seen' and 'active' active.add(nextMoves[i]); seen.add(nextMoves[i], state); } else { // We're not using this duplicate state; // so, we should delete it. delete nextMoves[i]; } } } // Ran out of states to explore. No solution! cout << "No solution!" << endl; solution.clear(); return; }
TEST(TodoList, Can_Get_Size) { // Arrange TodoList list; // Act list.addItem("abc"); // Assert EXPECT_EQ(1, list.size()); }
TEST(TodoList, Can_Add_By_Parameters) { // Arrange TodoList list; // Act list.addItem("abc", 2); // Assert EXPECT_NE(-1, list.search("abc")); }
TEST(TodoList, Throw_When_Add_Existing_Title_By_Parameters) { // Arrange TodoList list; // Act list.addItem("abc"); // Assert EXPECT_THROW(list.addItem("abc"), runtime_error); }
TEST(TodoList, Throws_When_Delete_By_Invalid_Pos) { // Arrange TodoList list; // Act list.addItem("abc"); // Act & Assert EXPECT_THROW(list.deleteItem(100500), out_of_range); }
TEST(TodoList, Can_Get_Item) { // Arrange TodoList list; // Act list.addItem("abc"); list.addItem("defg"); list.addItem("higk"); // Assert EXPECT_EQ(list.getItem(1).getTitle(), "defg"); }
TEST(TodoList, Can_Add_By_Item) { // Arrange TodoItem item; TodoList list; item.setTitle("abc"); // Act list.addItem(item); // Assert EXPECT_NE(-1, list.search("abc")); }
TEST(TodoList, Throw_When_Add_Existing_Title_By_Item) { // Arrange TodoItem item1; TodoItem item2; TodoList list; item1.setTitle("abc"); item2.setTitle("abc"); // Act list.addItem(item1); // Assert EXPECT_THROW(list.addItem(item2), runtime_error); }
TEST(TodoList, Can_Delete_By_Pos) { // Arrange TodoList list; vector<TodoItem> v; TodoItem temp; // Act temp.setTitle("abc"); temp.setPriority(1); list.addItem(temp); v.push_back(temp); temp.setTitle("def"); temp.setPriority(2); list.addItem(temp); temp.setTitle("gik"); temp.setPriority(1); list.addItem(temp); v.push_back(temp); list.deleteItem(1); // Assert EXPECT_EQ(list.getAll(), v); }
TEST(TodoList, Can_Get_All) { // Arrange TodoList list; vector<TodoItem> v; TodoItem temp; // Act temp.setTitle("abc"); list.addItem(temp); v.push_back(temp); temp.setTitle("def"); list.addItem(temp); v.push_back(temp); temp.setTitle("gik"); list.addItem(temp); v.push_back(temp); // Assert EXPECT_EQ(list.getAll(), v); }
TEST(TodoList, Can_Sort_By_Priority) { // Arrange TodoList list; TodoItem temp1; TodoItem temp2; vector<TodoItem> v; // Act temp1.setTitle("abc"); temp1.setPriority(0); temp2.setTitle("def"); temp2.setPriority(5); list.addItem(temp2); list.addItem(temp1); v.push_back(temp1); v.push_back(temp2); // Assert EXPECT_EQ(list.sortByPriority(), v); }
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) { std::optional<Options> maybe_opts = ParseCommandLine(pCmdLine); if (!maybe_opts) return 1; Options opts = std::move(*maybe_opts); if (opts.log_file) { log_fp = _wfopen(UTF8ToUTF16(*opts.log_file).c_str(), L"w"); if (!log_fp) log_fp = stderr; else atexit(FlushLog); } fprintf(log_fp, "Updating from: %s\n", opts.this_manifest_url.c_str()); fprintf(log_fp, "Updating to: %s\n", opts.next_manifest_url.c_str()); fprintf(log_fp, "Install path: %s\n", opts.install_base_path.c_str()); if (!File::IsDirectory(opts.install_base_path)) { fprintf(log_fp, "Cannot find install base path, or not a directory.\n"); return 1; } if (opts.parent_pid) { fprintf(log_fp, "Waiting for parent PID %d to complete...\n", *opts.parent_pid); HANDLE parent_handle = OpenProcess(SYNCHRONIZE, FALSE, *opts.parent_pid); WaitForSingleObject(parent_handle, INFINITE); CloseHandle(parent_handle); fprintf(log_fp, "Completed! Proceeding with update.\n"); } Manifest this_manifest, next_manifest; { std::optional<Manifest> maybe_manifest = FetchAndParseManifest(opts.this_manifest_url); if (!maybe_manifest) { fprintf(log_fp, "Could not fetch current manifest. Aborting.\n"); return 1; } this_manifest = std::move(*maybe_manifest); maybe_manifest = FetchAndParseManifest(opts.next_manifest_url); if (!maybe_manifest) { fprintf(log_fp, "Could not fetch next manifest. Aborting.\n"); return 1; } next_manifest = std::move(*maybe_manifest); } TodoList todo = ComputeActionsToDo(this_manifest, next_manifest); todo.Log(); std::optional<std::string> maybe_temp_dir = FindOrCreateTempDir(opts.install_base_path); if (!maybe_temp_dir) return 1; std::string temp_dir = std::move(*maybe_temp_dir); bool ok = PerformUpdate(todo, opts.install_base_path, opts.content_store_url, temp_dir); if (!ok) fprintf(log_fp, "Failed to apply the update.\n"); CleanUpTempDir(temp_dir, todo); return !ok; }
// For testing (DO NOT ALTER) void UnitTest() { string temp = "This unit test will test some of your code:\n"; cout << temp << string(temp.length() - 1, '-') << endl; // Tests string desc1 = "Go to Store"; string desc2 = "Brush Teeth @ 8PM"; cout << "*****TodoItem(\"Go to Store\")*****\n"; TodoItem item(desc1); Test(item.description() == desc1, "description()"); Test(item.priority() == 1, "priority()"); Test(item.completed() == false, "completed()"); Test(item.ToFile() == "Go to Store@1@0", "ToFile()"); cout << "Testing Overloaded <<: " << item << endl; cout << "\n*****TodoItem(\"Go to Store\", 3)*****\n"; TodoItem item2(desc1, 3); Test(item2.description() == desc1, "description()"); Test(item2.priority() == 3, "priority()"); Test(item2.completed() == false, "completed()"); Test(item2.ToFile() == "Go to Store@3@0", "ToFile()"); cout << "Testing Overloaded <<: " << item2 << endl; cout << "\n*****TodoItem(\"Go to Store\", 2, true)*****\n"; TodoItem item3(desc1, 2, true); Test(item3.description() == desc1, "description()"); Test(item3.priority() == 2, "priority()"); Test(item3.completed() == true, "completed()"); Test(item3.ToFile() == "Go to Store@2@1", "ToFile()"); cout << "Testing Overloaded <<: " << item3 << endl; cout << "\n*****TodoItem Mutators*****\n"; item.set_description(desc2); Test(item.description() == desc2, "set_description(\"Brush Teeth @ 8PM\") / description()"); item.set_priority(4); Test(item.priority() == 4, "set_priority(4) / priority()"); item.set_priority(0); Test(item.priority() == 5, "set_priority(0) / priority()"); item.set_priority(6); Test(item.priority() == 5, "set_priority(6) / priority()"); item.set_completed(true); Test(item.completed() == true, "set_completed(true) / completed()"); Test(item.ToFile() == "Brush Teeth ` 8PM@5@1", "ToFile()"); cout << "Testing Overloaded <<: " << item << endl; cout << "\n*****TodoList Constructor*****\n"; TodoList list; Test(list.GetSize() == 0, "GetSize()"); Test(list.GetCapacity() == 25, "GetCapacity()"); Test(list.ToFile() == "", "ToFile()"); cout << "\n*****TodoList Member Functions with 1 Item*****\n"; list.AddItem(new TodoItem(desc1)); Test(list.GetSize() == 1, "AddItem(TodoItem(\"Go to Store\")) / GetSize()"); Test(list.GetCapacity() == 25, "GetCapacity()"); Test(list.GetItem(1)->ToFile() == "Go to Store@1@0", "GetItem(1)->ToFile()"); Test(list.ToFile() == "Go to Store@1@0\n", "ToFile()"); cout << "Testing Overloaded <<:\n" << list << endl; cout << "\n*****TodoList Member Functions with 2 Items*****\n"; list.AddItem(new TodoItem(desc1, 2, true)); Test(list.GetSize() == 2, "AddItem(TodoItem(\"Go to Store\", 2, true)) / GetSize()"); Test(list.GetCapacity() == 25, "GetCapacity()"); Test(list.GetItem(1)->ToFile() == "Go to Store@1@0", "GetItem(1)->ToFile()"); Test(list.GetItem(2)->ToFile() == "Go to Store@2@1", "GetItem(2)->ToFile()"); Test(list.ToFile() == "Go to Store@1@0\nGo to Store@2@1\n", "ToFile()"); list.DeleteItem(1); Test(list.GetSize() == 1, "DeleteItem(1) / GetSize()"); Test(list.GetCapacity() == 25, "GetCapacity()"); cout << "Testing Overloaded <<:\n" << list << endl; cout << "\n*****TodoList Member Functions with 25 Items*****\n"; list.AddItem(new TodoItem(desc2, 4, true)); stringstream ss; for (int i = 0; i < 23; i++) { ss << "Description #" << i + 3; list.AddItem(new TodoItem(ss.str(), i % 5 + 1)); ss.str(""); } Test(list.GetSize() == 25, "AddItem(Adding 24 More Items) / GetSize()"); Test(list.GetCapacity() == 25, "GetCapacity()"); Test(list.GetItem(17)->ToFile() == "Description #17@5@0", "GetItem(17)->ToFile()"); Test(list.GetItem(25)->ToFile() == "Description #25@3@0", "GetItem(25)->ToFile()"); string to_file = "Go to Store@2@1\nBrush Teeth ` 8PM@4@1\nDescription #3@1@0\n" "Description #4@2@0\nDescription #5@3@0\nDescription #6@4@0\n" "Description #7@5@0\nDescription #8@1@0\nDescription #9@2@0\n" "Description #10@3@0\nDescription #11@4@0\nDescription #12@5@0\n" "Description #13@1@0\nDescription #14@2@0\nDescription #15@3@0\n" "Description #16@4@0\nDescription #17@5@0\nDescription #18@1@0\n" "Description #19@2@0\nDescription #20@3@0\nDescription #21@4@0\n" "Description #22@5@0\nDescription #23@1@0\nDescription #24@2@0\n" "Description #25@3@0\n"; Test(list.ToFile() == to_file, "ToFile()"); cout << "Testing Overloaded <<:\n" << list << endl; list.DeleteItem(15); Test(list.GetSize() == 24, "DeleteItem(15) / GetSize()"); Test(list.GetCapacity() == 25, "GetCapacity()"); Test(list.GetItem(10)->ToFile() == "Description #10@3@0", "GetItem(10)->ToFile()"); Test(list.GetItem(20)->ToFile() == "Description #21@4@0", "GetItem(20)->ToFile()"); to_file = "Go to Store@2@1\nBrush Teeth ` 8PM@4@1\nDescription #3@1@0\n" "Description #4@2@0\nDescription #5@3@0\nDescription #6@4@0\n" "Description #7@5@0\nDescription #8@1@0\nDescription #9@2@0\n" "Description #10@3@0\nDescription #11@4@0\nDescription #12@5@0\n" "Description #13@1@0\nDescription #14@2@0\n" "Description #16@4@0\nDescription #17@5@0\nDescription #18@1@0\n" "Description #19@2@0\nDescription #20@3@0\nDescription #21@4@0\n" "Description #22@5@0\nDescription #23@1@0\nDescription #24@2@0\n" "Description #25@3@0\n"; Test(list.ToFile() == to_file, "ToFile()"); cout << "Testing Overloaded <<:\n" << list << endl; cout << "\n*****TodoList Member Functions with 30 Items*****\n"; for (int i = 25; i <= 30; i++) { ss << "New Description #" << i; list.AddItem(new TodoItem(ss.str(), i % 5 + 1, true)); ss.str(""); } Test(list.GetSize() == 30, "AddItem(Adding 6 More Items) / GetSize()"); Test(list.GetCapacity() == 35, "GetCapacity()"); Test(list.GetItem(11)->ToFile() == "Description #11@4@0", "GetItem(11)->ToFile()"); Test(list.GetItem(30)->ToFile() == "New Description #30@1@1", "GetItem(30)->ToFile()"); to_file = "Go to Store@2@1\nBrush Teeth ` 8PM@4@1\nDescription #3@1@0\n" "Description #4@2@0\nDescription #5@3@0\nDescription #6@4@0\n" "Description #7@5@0\nDescription #8@1@0\nDescription #9@2@0\n" "Description #10@3@0\nDescription #11@4@0\nDescription #12@5@0\n" "Description #13@1@0\nDescription #14@2@0\n" "Description #16@4@0\nDescription #17@5@0\nDescription #18@1@0\n" "Description #19@2@0\nDescription #20@3@0\nDescription #21@4@0\n" "Description #22@5@0\nDescription #23@1@0\nDescription #24@2@0\n" "Description #25@3@0\nNew Description #25@1@1\nNew Description #26@2@1\n" "New Description #27@3@1\nNew Description #28@4@1\n" "New Description #29@5@1\nNew Description #30@1@1\n"; Test(list.ToFile() == to_file, "ToFile()"); cout << "Testing Overloaded <<:\n" << list << endl; cout << "\n*****Sorting TodoList with 30 Items*****\n"; list.Sort(); bool sorted = true; for (int i = 1; i <= 30; i++) { if ((i <= 7) && (list.GetItem(i)->priority()) != 1) sorted = false; else if ((i > 7 && i <= 14) && (list.GetItem(i)->priority()) != 2) sorted = false; else if ((i > 14 && i <= 19) && (list.GetItem(i)->priority()) != 3) sorted = false; else if ((i > 19 && i <= 25) && (list.GetItem(i)->priority()) != 4) sorted = false; else if ((i > 25 && i <= 30) && (list.GetItem(i)->priority()) != 5) sorted = false; } Test(sorted, "Sort()"); cout << "Testing Overloaded <<:\n" << list << endl; cout << "\n*****TodoList Member Functions with 1000 Items*****\n"; for (int i = 0; i < 970; i++) list.AddItem(new TodoItem("A", 1, true)); Test(list.GetSize() == 1000, "AddItem(Adding 970 More Items) / GetSize()"); Test(list.GetCapacity() == 1005, "GetCapacity()"); cout << "**Deleting All Items**\n"; for (int i = 1000; i >= 1; i--) list.DeleteItem(i); Test(list.GetSize() == 0, "DeleteItem() / GetSize()"); Test(list.GetCapacity() == 1005, "GetCapacity()"); //Testing Destructors cout << "\n*****Testing Destructors*****" << endl << "If the next line is the \"END Testing Destructors\" then you passed!" << endl; TodoItem *dynamic_item = new TodoItem("testing"); delete dynamic_item; dynamic_item = new TodoItem("testing2", 5); delete dynamic_item; dynamic_item = new TodoItem("Testing3", 3, true); TodoList *dynamic_list = new TodoList(); delete dynamic_list; dynamic_list = new TodoList(); for (int i = 0; i < 50; i++) dynamic_list->AddItem(new TodoItem("testing")); delete dynamic_list; cout << "*****END Testing Destructors*****" << endl; cout << string(temp.length() - 1, '-') << endl; cout << "Unit Test Complete!\n\n"; }
bool RunUpdater(std::vector<std::string> args) { std::optional<Options> maybe_opts = ParseCommandLine(args); if (!maybe_opts) { return false; } UI::Init(); Options opts = std::move(*maybe_opts); if (opts.log_file) { log_fp = fopen(opts.log_file.value().c_str(), "w"); if (!log_fp) log_fp = stderr; else atexit(FlushLog); } fprintf(log_fp, "Updating from: %s\n", opts.this_manifest_url.c_str()); fprintf(log_fp, "Updating to: %s\n", opts.next_manifest_url.c_str()); fprintf(log_fp, "Install path: %s\n", opts.install_base_path.c_str()); if (!File::IsDirectory(opts.install_base_path)) { FatalError("Cannot find install base path, or not a directory."); return false; } if (opts.parent_pid) { UI::SetDescription("Waiting for Dolphin to quit..."); fprintf(log_fp, "Waiting for parent PID %d to complete...\n", *opts.parent_pid); auto pid = opts.parent_pid.value(); UI::WaitForPID(static_cast<u32>(pid)); fprintf(log_fp, "Completed! Proceeding with update.\n"); } UI::SetVisible(true); UI::SetDescription("Fetching and parsing manifests..."); Manifest this_manifest, next_manifest; { std::optional<Manifest> maybe_manifest = FetchAndParseManifest(opts.this_manifest_url); if (!maybe_manifest) { FatalError("Could not fetch current manifest. Aborting."); return false; } this_manifest = std::move(*maybe_manifest); maybe_manifest = FetchAndParseManifest(opts.next_manifest_url); if (!maybe_manifest) { FatalError("Could not fetch next manifest. Aborting."); return false; } next_manifest = std::move(*maybe_manifest); } UI::SetDescription("Computing what to do..."); TodoList todo = ComputeActionsToDo(this_manifest, next_manifest); todo.Log(); std::optional<std::string> maybe_temp_dir = FindOrCreateTempDir(opts.install_base_path); if (!maybe_temp_dir) return false; std::string temp_dir = std::move(*maybe_temp_dir); UI::SetDescription("Performing Update..."); bool ok = PerformUpdate(todo, opts.install_base_path, opts.content_store_url, temp_dir); if (!ok) { FatalError("Failed to apply the update."); CleanUpTempDir(temp_dir, todo); return false; } UI::ResetCurrentProgress(); UI::ResetTotalProgress(); UI::SetCurrentMarquee(false); UI::SetTotalMarquee(false); UI::SetCurrentProgress(1, 1); UI::SetTotalProgress(1, 1); UI::SetDescription("Done!"); // Let the user process that we are done. UI::Sleep(1); if (opts.binary_to_restart) { UI::LaunchApplication(opts.binary_to_restart.value()); } UI::Stop(); return true; }
TEST(TodoList, Can_Not_Load_From_File_With_Empty_Name) { // Arrange TodoList listForLoad; // Act and Assert EXPECT_THROW(listForLoad.load(""), std::runtime_error); }
TEST(TodoList, Can_Not_Load_From_Non_Existing_File) { // Arrange TodoList listForLoad; // Act and Assert EXPECT_THROW(listForLoad.load("todo1.list"), std::runtime_error); }