Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "Common/Cpp/TestRunners/UnitTestDatabase.h"
#include "Common/Qt/QtThreadPool_Tests.h"
#include "Kernels/Kernels_Tests.h"
#include "Pokemon/AutoStory/Pokemon_AutoStorySelect_Tests.h"
#include "CommonFramework/AudioPipeline/AudioInfo_Tests.h"
#include "CommonFramework/AudioPipeline/Tools/ChannelMixer.h"
#include "CommonFramework/AudioPipeline/SinkPipeline_Tests.h"
Expand Down Expand Up @@ -48,7 +49,7 @@



UnitTestDatabase make_UNIT_TESTS_ALL(){

Check warning on line 52 in SerialPrograms/Source/ComputerPrograms/ComputerPrograms_UnitTestRunner.cpp

View workflow job for this annotation

GitHub Actions / code-health

Code health (advisory)

PokemonAutomation::ComputerPrograms::make_UNIT_TESTS_ALL(): function_lines=31 (advisory above 25, limit 50)
UnitTestDatabase ret;

add_tests_QtEventThreadPool(ret, GlobalThreadPools::computation_normal());
Expand All @@ -64,6 +65,7 @@
add_tests_LabControl(ret);
OCR::add_tests(ret);
Kernels::add_tests(ret);
Pokemon::add_tests_AutoStorySelect(ret);
NintendoSwitch::add_tests_CheckOnlineDetector(ret);
NintendoSwitch::add_tests_FailedToConnectDetector(ret);
NintendoSwitch::add_tests_UpdatePopupDetector(ret);
Expand Down
12 changes: 12 additions & 0 deletions SerialPrograms/Source/Pokemon/AutoStory/Pokemon_AutoStorySelect.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ StringSelectDatabase make_story_select_database(
}


// The index in the whole story list of entry `index_in_section` of the
// tutorial or the main story, whose first entry is `first_main_story_index`.
// NOTE: a section ends where the user must step in (e.g. level up the
// Pokemon between the tutorial and the main story). SV has two sections.
// Later content (postgame, DLC) appends to the last section, run only after
// the main story; if it needs its own break (e.g. grinding before a DLC),
// it becomes a third section and `main_story` here becomes a section index.
inline size_t story_index(bool main_story, size_t index_in_section, size_t first_main_story_index){
return main_story ? first_main_story_index + index_in_section : index_in_section;
}


}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/* AutoStory Select Tests
*
* From: https://github.com/PokemonAutomation/
*
*/

#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "Pokemon_AutoStorySelect.h"
#include "Pokemon_AutoStorySelect_Tests.h"

namespace PokemonAutomation{
namespace Pokemon{

namespace{

// An entry of a story section, its index in the whole story list, and the
// index of the first main story entry.
struct AutoStoryIndexScenario{
std::string name;
bool main_story;
size_t index_in_section;
size_t first_main_story_index;
size_t expected;
};

class Test_AutoStoryIndex : public UnitTest{
public:
Test_AutoStoryIndex(AutoStoryIndexScenario scenario)
: UnitTest("Pokemon::AutoStoryIndex - " + scenario.name)
, m_scenario(std::move(scenario))
{}

virtual UnitTestResult run(Logger&, CancellableScope&) const override{
const size_t got = story_index(
m_scenario.main_story, m_scenario.index_in_section, m_scenario.first_main_story_index
);
if (got != m_scenario.expected){
return "Expected index " + std::to_string(m_scenario.expected) + ", got " + std::to_string(got);
}
return true;
}

private:
const AutoStoryIndexScenario m_scenario;
};

// A stand-in for a story segment or checkpoint: only its name is read.
struct NamedEntry{
std::string label;
std::string name() const{ return label; }
};

// A dropdown built from [begin, end) of a story list of two tutorial entries,
// then two of the main story (which starts at index 2), as SV's lists are
// laid out, and its (slug, label) entries: slugs are indices in the whole
// list, not in the dropdown.
struct AutoStorySelectScenario{
std::string name;
size_t begin;
size_t end;
std::vector<std::pair<std::string, std::string>> expected;
};

class Test_AutoStorySelectDatabase : public UnitTest{
public:
Test_AutoStorySelectDatabase(AutoStorySelectScenario scenario)
: UnitTest("Pokemon::AutoStorySelectDatabase - " + scenario.name)
, m_scenario(std::move(scenario))
{}

virtual UnitTestResult run(Logger&, CancellableScope&) const override{
// unique_ptr cannot be copied out of a braced list: build it in place.
const std::vector<std::unique_ptr<NamedEntry>> list = []{
std::vector<std::unique_ptr<NamedEntry>> list;
for (const char* label : {"tutorial 0", "tutorial 1", "main story 0", "main story 1"}){
list.emplace_back(std::make_unique<NamedEntry>(NamedEntry{label}));
}
return list;
}();
const StringSelectDatabase database = make_story_select_database(list, m_scenario.begin, m_scenario.end);
std::vector<std::pair<std::string, std::string>> got;
for (const StringSelectEntry& entry : database.case_list()){
got.emplace_back(entry.slug, entry.display_name);
}
if (got != m_scenario.expected){
return "Expected " + describe(m_scenario.expected) + ", got " + describe(got);
}
return true;
}

private:
static std::string describe(const std::vector<std::pair<std::string, std::string>>& entries){
std::string text;
for (const auto& [slug, label] : entries){
text += (text.empty() ? "" : ", ") + slug + " \"" + label + "\"";
}
return "[" + text + "]";
}

const AutoStorySelectScenario m_scenario;
};

void add_index_tests(UnitTestDatabase& database){

Check warning on line 106 in SerialPrograms/Source/Pokemon/AutoStory/Pokemon_AutoStorySelect_Tests.cpp

View workflow job for this annotation

GitHub Actions / code-health

Code health (advisory)

PokemonAutomation::Pokemon::add_index_tests( UnitTestDatabase & database): function_lines=30 (advisory above 25, limit 50)
const AutoStoryIndexScenario scenarios[] = {
{
.name = "a tutorial entry is its own index",
.main_story = false,
.index_in_section = 3,
.first_main_story_index = 10,
.expected = 3,
},
{
// SV: segment 10 is the first of the main story.
.name = "the first main story entry follows the tutorial",
.main_story = true,
.index_in_section = 0,
.first_main_story_index = 10,
.expected = 10,
},
{
// SV: checkpoint 21 is the first of the main story.
.name = "a later main story checkpoint",
.main_story = true,
.index_in_section = 5,
.first_main_story_index = 21,
.expected = 26,
},
};
for (const AutoStoryIndexScenario& scenario : scenarios){
database.add<Test_AutoStoryIndex>(scenario);
}
}

void add_select_database_tests(UnitTestDatabase& database){
const AutoStorySelectScenario select_scenarios[] = {
{
.name = "the tutorial dropdown",
.begin = 0,
.end = 2,
.expected = {{"0", "tutorial 0"}, {"1", "tutorial 1"}},
},
{
.name = "the main story dropdown keeps whole-list slugs",
.begin = 2,
.end = 4,
.expected = {{"2", "main story 0"}, {"3", "main story 1"}},
},
{
.name = "an end past the list is clamped to it",
.begin = 2,
.end = 10,
.expected = {{"2", "main story 0"}, {"3", "main story 1"}},
},
};
for (const AutoStorySelectScenario& scenario : select_scenarios){
database.add<Test_AutoStorySelectDatabase>(scenario);
}
}

}

void add_tests_AutoStorySelect(UnitTestDatabase& database){
add_index_tests(database);
add_select_database_tests(database);
}



}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* AutoStory Select Tests
*
* From: https://github.com/PokemonAutomation/
*
*/

#ifndef PokemonAutomation_Pokemon_AutoStorySelect_Tests_H
#define PokemonAutomation_Pokemon_AutoStorySelect_Tests_H

#include "Common/Cpp/TestRunners/UnitTestDatabase.h"

namespace PokemonAutomation{
namespace Pokemon{


void add_tests_AutoStorySelect(UnitTestDatabase& database);



}
}
#endif
40 changes: 0 additions & 40 deletions SerialPrograms/Source/VideoGames/PokemonSV/PokemonSV_Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/

#include "Common/Cpp/TestRunners/UnitTestDatabase.h"
#include "Pokemon/AutoStory/Pokemon_AutoStorySelect.h"
#include "Inference/PokemonSV_WhiteButtonDetector.h"
#include "Inference/Boxes/PokemonSV_BoxDetection.h"
#include "Inference/Boxes/PokemonSV_BoxEggDetector.h"
Expand Down Expand Up @@ -149,46 +148,7 @@

}

namespace{

// A stand-in for a story segment or checkpoint: only its name is read.
struct NamedEntry{
std::string label;
std::string name() const{ return label; }
};

class Test_AutoStorySelectDatabase : public UnitTest{
public:
Test_AutoStorySelectDatabase()
: UnitTest("Pokemon::AutoStorySelectDatabase - a section keeps whole-list slugs")
{}

virtual UnitTestResult run(Logger&, CancellableScope&) const override{
std::vector<std::unique_ptr<NamedEntry>> list;
for (const char* label : {"a", "b", "c", "d"}){
list.emplace_back(std::make_unique<NamedEntry>(NamedEntry{label}));
}
const StringSelectDatabase database = Pokemon::make_story_select_database(list, 2, 10);
const std::vector<StringSelectEntry>& entries = database.case_list();
if (entries.size() != 2){
return "Expected 2 entries (the end is clamped to the list), got " + std::to_string(entries.size());
}
if (entries[0].slug != "2" || entries[0].display_name != "c" || entries[1].slug != "3" || entries[1].display_name != "d"){
return "Expected slugs 2, 3 labeled c, d; got " + entries[0].slug + " " + entries[0].display_name
+ ", " + entries[1].slug + " " + entries[1].display_name;
}
return true;
}
};

void add_tests_AutoStory(UnitTestDatabase& database){
database.add<Test_AutoStorySelectDatabase>();
}

}

void add_tests(UnitTestDatabase& database){

Check warning on line 151 in SerialPrograms/Source/VideoGames/PokemonSV/PokemonSV_Tests.cpp

View workflow job for this annotation

GitHub Actions / code-health

Code health (advisory)

PokemonAutomation::NintendoSwitch::PokemonSV::add_tests( UnitTestDatabase & database): function_lines=33 (advisory above 25, limit 50)
add_tests_AutoStory(database);
database.add<Test_BBQuestsSlugs>();

// Full-frame references, in the CommandLineTests repo: they exercise the production
Expand Down
Loading
Loading