summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdwin van Leeuwen <edwinvanl@tuta.io>2022-11-05 19:46:10 +0000
committerEdwin van Leeuwen <edwinvanl@tuta.io>2022-11-05 19:46:10 +0000
commitff2efc6e7a3e99388bf3644267f6e3de9b11b31c (patch)
tree149130f95eaeb65cbc84c0661d4200c7c0534ec1
parentcfe88a8b213ccaddc2915797344776ae69602161 (diff)
parent1fb9837d9bc1e3b8beccb0dfb6b01824dda0d68b (diff)
Merge branch 'release/1.1.2'v1.1.2
-rw-r--r--CMakeLists.txt7
-rw-r--r--src/main.cpp4
-rw-r--r--src/rttt.hpp317
-rw-r--r--src/rttt/config.hpp2
-rw-r--r--src/rttt/hackernews.hpp1
-rw-r--r--src/rttt/reddit.hpp27
-rw-r--r--src/rttt/rss.hpp11
-rw-r--r--src/rttt/thing.hpp7
-rw-r--r--src/rttt/timeline.hpp20
-rw-r--r--src/rttt/twitter.hpp1
-rw-r--r--test/catch_hackernews.cpp1
-rw-r--r--test/catch_peek.cpp69
-rw-r--r--test/catch_rss.cpp21
-rw-r--r--test/catch_rttt.cpp25
-rw-r--r--test/catch_twitter.cpp1
15 files changed, 285 insertions, 229 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7c76371..8cab78f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -113,10 +113,9 @@ set (SOURCES src/main.cpp)
# Setup executable
add_executable(${TARGET} ${SOURCES})
-target_include_directories(${TARGET} PRIVATE
- .
- src/
- test/include/
+target_include_directories(${TARGET}
+ PRIVATE src/
+ PRIVATE test/include/
)
target_link_libraries(${TARGET}
diff --git a/src/main.cpp b/src/main.cpp
index fd00e29..b26ed3f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -124,7 +124,7 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] char **argv) {
rttt::active_storage<std::string, rttt::view::item_state> item_view_states =
rttt::config::load_item_view_states_or(
rttt::active_storage<std::string, rttt::view::item_state>(
- 0, 10, 3 * 24 * 3600));
+ 0, 10, 3 * 24 * 3601));
// Drawing windows
auto screen = ftxui::ScreenInteractive::Fullscreen();
@@ -346,6 +346,8 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] char **argv) {
if (logger::size() > 100)
logger::pop_front();
if (counter % 10000 == 0) {
+ item_view_states.update();
+ window_state_cache.update();
rttt::config::save_item_view_states(item_view_states);
rttt::config::save_prompt_state(prompt_state);
}
diff --git a/src/rttt.hpp b/src/rttt.hpp
index d1efc93..62afd27 100644
--- a/src/rttt.hpp
+++ b/src/rttt.hpp
@@ -18,147 +18,133 @@
namespace rttt {
- // TODO: move to thing::type
- enum class SiteType : int {
- Unknown,
- HN,
- Reddit,
- RSS,
- Twitter,
- };
-
- // Consider moving this to view.hpp
- enum class list_mode : int {
- story,
- comment,
- feed,
- };
-
- // TODO: should work with constexpr, but might need newer g++/clang++
- inline std::vector<std::string> split(std::string_view strv,
- std::string_view delims = " ",
- size_t no_pieces = 0) {
- std::vector<std::string> output;
- size_t first = 0;
-
- while (first < strv.size()) {
- const auto second = strv.find_first_of(delims, first);
-
- if (first != second)
- output.emplace_back(strv.substr(first, second - first));
-
- if (second == std::string_view::npos) {
- break;
- } else if (no_pieces > 0 && output.size() >= no_pieces - 1) {
- output.emplace_back(strv.substr(second + 1, strv.size()));
- break;
- }
-
- first = second + 1;
+// Consider moving this to view.hpp
+enum class list_mode : int {
+ story,
+ comment,
+ feed,
+};
+
+// TODO: should work with constexpr, but might need newer g++/clang++
+inline std::vector<std::string> split(std::string_view strv,
+ std::string_view delims = " ",
+ size_t no_pieces = 0) {
+ std::vector<std::string> output;
+ size_t first = 0;
+
+ while (first < strv.size()) {
+ const auto second = strv.find_first_of(delims, first);
+
+ if (first != second)
+ output.emplace_back(strv.substr(first, second - first));
+
+ if (second == std::string_view::npos) {
+ break;
+ } else if (no_pieces > 0 && output.size() >= no_pieces - 1) {
+ output.emplace_back(strv.substr(second + 1, strv.size()));
+ break;
}
- return output;
+ first = second + 1;
}
- inline void replaceAll(std::string & s, const std::string &search,
- const std::string &replace) {
- for (size_t pos = 0;; pos += replace.length()) {
- pos = s.find(search, pos);
- if (pos == std::string::npos)
- break;
- s.erase(pos, search.length());
- s.insert(pos, replace);
- }
+ return output;
+}
+
+inline void replaceAll(std::string &s, const std::string &search,
+ const std::string &replace) {
+ for (size_t pos = 0;; pos += replace.length()) {
+ pos = s.find(search, pos);
+ if (pos == std::string::npos)
+ break;
+ s.erase(pos, search.length());
+ s.insert(pos, replace);
}
-
- inline std::string parse_html(std::string str) {
- replaceAll(str, "<p>", "\n");
-
- std::string res;
- bool inTag = false;
- for (auto &ch : str) {
- if (ch == '<') {
- inTag = true;
- } else if (ch == '>') {
- inTag = false;
- } else {
- if (inTag == false) {
- res += ch;
- }
+}
+
+inline std::string parse_html(std::string str) {
+ replaceAll(str, "<p>", "\n");
+
+ std::string res;
+ bool inTag = false;
+ for (auto &ch : str) {
+ if (ch == '<') {
+ inTag = true;
+ } else if (ch == '>') {
+ inTag = false;
+ } else {
+ if (inTag == false) {
+ res += ch;
}
}
-
- replaceAll(res, "&#x2F;", "/");
- replaceAll(res, "&#x27;", "'");
- replaceAll(res, "&gt;", ">");
- replaceAll(res, "–", "-");
- replaceAll(res, "“", "\"");
- replaceAll(res, "”", "\"");
- replaceAll(res, "‘", "'");
- replaceAll(res, "’", "'");
- replaceAll(res, "„", "'");
- replaceAll(res, "&quot;", "\"");
- replaceAll(res, "&amp;", "&");
- replaceAll(res, "—", "-");
-
- return res;
}
- inline std::tm parse_time(std::string time_string) {
- std::tm time = {};
- std::regex e("(\\d{4})-(\\d+)-(\\d+)T(\\d+):(\\d+)");
- std::smatch sm;
- std::regex_search(time_string, sm, e);
- if (sm.size() > 1) {
- time.tm_year = std::stoi(sm[1]) - 1900;
- time.tm_mon = std::stoi(sm[2]) - 1;
- time.tm_mday = std::stoi(sm[3]);
- time.tm_hour = std::stoi(sm[4]);
- time.tm_min = std::stoi(sm[5]);
- }
- return time;
+ replaceAll(res, "&#x2F;", "/");
+ replaceAll(res, "&#x27;", "'");
+ replaceAll(res, "&gt;", ">");
+ replaceAll(res, "–", "-");
+ replaceAll(res, "“", "\"");
+ replaceAll(res, "”", "\"");
+ replaceAll(res, "‘", "'");
+ replaceAll(res, "’", "'");
+ replaceAll(res, "„", "'");
+ replaceAll(res, "&quot;", "\"");
+ replaceAll(res, "&amp;", "&");
+ replaceAll(res, "—", "-");
+
+ return res;
+}
+
+inline std::tm parse_time(std::string time_string) {
+ std::tm time = {};
+ std::regex e("(\\d{4})-(\\d+)-(\\d+)T(\\d+):(\\d+)");
+ std::smatch sm;
+ std::regex_search(time_string, sm, e);
+ if (sm.size() > 1) {
+ time.tm_year = std::stoi(sm[1]) - 1900;
+ time.tm_mon = std::stoi(sm[2]) - 1;
+ time.tm_mday = std::stoi(sm[3]);
+ time.tm_hour = std::stoi(sm[4]);
+ time.tm_min = std::stoi(sm[5]);
}
-
- // TODO: Move to text.hpp and rename
- inline std::vector<std::string> extractURL(std::string text) {
- std::vector<std::string> v;
-
- // Currently we assume an url always ends with alphanum, / or _
- // ([^/_[:alnum:]]) If this turns out to be false then we could also try to
- // filter out trailing punctuation marks etc specifically ([);:.!?]
- // std::regex e("(https?://[A-z0-9$–_.+!*‘(),./?=]+?)[),;:.!?]*(\\s|$)");
- // "(https?://[[:alnum:]$-_.+!*‘(),./?=;&#]+?)[^/_[:alnum:]]*(\\s|$)");
- std::regex e("(https?://[[:alnum:]$-_+!*‘,/?=;&#]+?)(\\]\\(|[^/"
- "_[:alnum:]]*(\\s|$))");
- std::smatch sm;
- while (std::regex_search(text, sm, e)) {
- if (sm.size() > 1)
- v.push_back(sm[1]);
- text = sm.suffix().str();
- }
-
- return v;
+ return time;
+}
+
+// TODO: Move to text.hpp and rename
+inline std::vector<std::string> extractURL(std::string text) {
+ std::vector<std::string> v;
+
+ // Currently we assume an url always ends with alphanum, / or _
+ // ([^/_[:alnum:]]) If this turns out to be false then we could also try to
+ // filter out trailing punctuation marks etc specifically ([);:.!?]
+ // std::regex e("(https?://[A-z0-9$–_.+!*‘(),./?=]+?)[),;:.!?]*(\\s|$)");
+ // "(https?://[[:alnum:]$-_.+!*‘(),./?=;&#]+?)[^/_[:alnum:]]*(\\s|$)");
+ std::regex e("(https?://[[:alnum:]$-_+!*‘,/?=;&#]+?)(\\]\\(|[^/"
+ "_[:alnum:]]*(\\s|$))");
+ std::smatch sm;
+ while (std::regex_search(text, sm, e)) {
+ if (sm.size() > 1)
+ v.push_back(sm[1]);
+ text = sm.suffix().str();
}
- struct Path {
- SiteType type = SiteType::Unknown;
- std::string name;
- std::string basename;
- list_mode mode = list_mode::story;
- std::string id;
- std::vector<std::string> parts;
- };
-
- inline Path parse_path(std::string_view path_name) {
- Path path;
- path.parts = split(path_name, "/");
- auto &v = path.parts;
- if (v[0] == "hn") {
- path.type = SiteType::HN;
- } else if (v[0] == "r") {
- path.type = SiteType::Reddit;
- } else if (v[0] == "rss") {
- path.type = SiteType::RSS;
+ return v;
+}
+
+struct Path {
+ std::string name;
+ std::string basename;
+ list_mode mode = list_mode::story;
+ std::string id;
+ std::vector<std::string> parts;
+};
+
+inline Path parse_path(std::string_view path_name) {
+ Path path;
+ path.parts = split(path_name, "/");
+ auto &v = path.parts;
+ if (v.size() == 1) {
+ if (v[0] == "rss") {
path.basename = "/rss";
if (v.size() == 2 && v[1] != "front") {
path.mode = list_mode::feed;
@@ -169,43 +155,48 @@ namespace rttt {
path.mode = list_mode::story;
}
return path;
- }
- if (v.size() == 4) {
- if (v[2] == "comments") {
- path.mode = list_mode::comment;
- } else {
- logger::log_ifnot(false);
- }
- path.name = "/" + v[0] + "/" + v[1] + "/" + v[2] + "/" + v[3];
- path.id = v[3];
- }
- path.basename = "/" + v[0] + "/" + v[1];
- if (path.name.empty())
+ } else {
+ path.basename = fmt::format("/{}", v[0]);
path.name = path.basename;
- return path;
+ return path;
+ }
}
-
- inline std::string timeSince(uint64_t t) {
- auto delta = current_time() - t;
- if (delta < 60)
- return std::to_string(delta) + " seconds";
- if (delta < 3600)
- return std::to_string(delta / 60) + " minutes";
- if (delta < 24 * 3600)
- return std::to_string(delta / 3600) + " hours";
- return std::to_string(delta / 24 / 3600) + " days";
+ if (v.size() == 4) {
+ if (v[2] == "comments") {
+ path.mode = list_mode::comment;
+ } else {
+ logger::log_ifnot(false);
+ }
+ path.name = "/" + v[0] + "/" + v[1] + "/" + v[2] + "/" + v[3];
+ path.id = v[3];
}
-
- inline int openInBrowser(std::string uri) {
- auto config = rttt::config::load();
- auto base_cmd = config["open_command"].get<std::string>();
+ path.basename = "/" + v[0] + "/" + v[1];
+ if (path.name.empty())
+ path.name = path.basename;
+ return path;
+}
+
+inline std::string timeSince(uint64_t t) {
+ auto delta = current_time() - t;
+ if (delta < 60)
+ return std::to_string(delta) + " seconds";
+ if (delta < 3600)
+ return std::to_string(delta / 60) + " minutes";
+ if (delta < 24 * 3600)
+ return std::to_string(delta / 3600) + " hours";
+ return std::to_string(delta / 24 / 3600) + " days";
+}
+
+inline int openInBrowser(std::string uri) {
+ auto config = rttt::config::load();
+ auto base_cmd = config["open_command"].get<std::string>();
#ifdef __APPLE__
- if (base_command == "xdg-open")
- base_cmd = "open";
+ if (base_command == "xdg-open")
+ base_cmd = "open";
#endif
- // std::string cmd = "run-mailcap " + uri + " > /dev/null 2>&1";
- std::string cmd = base_cmd + " \"" + uri + "\" > /dev/null 2>&1 &";
- logger::push("EXECUTING: {}", cmd);
- return system(cmd.c_str());
- }
+ // std::string cmd = "run-mailcap " + uri + " > /dev/null 2>&1";
+ std::string cmd = base_cmd + " \"" + uri + "\" > /dev/null 2>&1 &";
+ logger::push("EXECUTING: {}", cmd);
+ return system(cmd.c_str());
+}
} // namespace rttt
diff --git a/src/rttt/config.hpp b/src/rttt/config.hpp
index ed8ef35..360ca99 100644
--- a/src/rttt/config.hpp
+++ b/src/rttt/config.hpp
@@ -8,7 +8,7 @@
#include "nlohmann/json.hpp"
#include "functional.hpp"
-#include "rttt/prompt.hpp"
+#include "prompt.hpp"
namespace rttt {
diff --git a/src/rttt/hackernews.hpp b/src/rttt/hackernews.hpp
index 7b2a0c1..a1e4b91 100644
--- a/src/rttt/hackernews.hpp
+++ b/src/rttt/hackernews.hpp
@@ -373,7 +373,6 @@ bool is_valid_path(const rttt::Path &path) {
Path parse_path(std::string_view name) {
auto path = rttt::parse_path(name);
- path.type = SiteType::HN;
return path;
}
diff --git a/src/rttt/reddit.hpp b/src/rttt/reddit.hpp
index db06273..76a93bd 100644
--- a/src/rttt/reddit.hpp
+++ b/src/rttt/reddit.hpp
@@ -26,6 +26,18 @@
namespace rttt {
namespace reddit {
+bool is_valid_path(std::string_view name) {
+ // TODO: Ideally we should not split it twice (here and in parse_path)
+ auto v = rttt::text::split(name, "/");
+ return (v.size() > 0 && v[0] == "r");
+}
+
+bool is_valid_path(const rttt::Path &path) {
+ // TODO: should we rely on path.type if it is present?
+ return (path.parts.size() == 2 || path.parts.size() == 4) &&
+ path.parts[0] == "r";
+}
+
struct credentials {
cpr::Header header = cpr::Header{{"User-Agent", "rttt/1.1.1"}};
std::string client_id;
@@ -385,7 +397,7 @@ bool update(state &state) {
}
inline rttt::Path updatePath(rttt::Path &&path) {
- logger::log_ifnot(path.type == rttt::SiteType::Reddit);
+ logger::log_ifnot(reddit::is_valid_path(path));
if (!items.contains(path.name)) {
items.insert({path.name, {}});
}
@@ -474,21 +486,8 @@ bool catch_ui_event(state &state, ui::state &ui_state, const rttt::Path &path,
return false;
}
-bool is_valid_path(std::string_view name) {
- // TODO: Ideally we should not split it twice (here and in parse_path)
- auto v = rttt::text::split(name, "/");
- return (v.size() > 0 && v[0] == "r");
-}
-
-bool is_valid_path(const rttt::Path &path) {
- // TODO: should we rely on path.type if it is present?
- return (path.parts.size() == 2 || path.parts.size() == 4) &&
- path.parts[0] == "r";
-}
-
Path parse_path(std::string_view name) {
auto path = rttt::parse_path(name);
- path.type = SiteType::Reddit;
return path;
}
diff --git a/src/rttt/rss.hpp b/src/rttt/rss.hpp
index 8e2fb13..9903d44 100644
--- a/src/rttt/rss.hpp
+++ b/src/rttt/rss.hpp
@@ -252,10 +252,9 @@ struct state {
};
auto &get_items(const rss::state &state, const rttt::Path &path) {
- // FIXME: use a view here or can we just return sets of stories directly?
- if (path.mode == rttt::list_mode::feed && !empty(path.id)) {
- logger::log_ifnot(state.items.contains(path.id));
- return state.items.at(path.id);
+ if (path.mode == rttt::list_mode::feed && path.parts.size() > 1) {
+ logger::log_ifnot(state.items.contains(path.parts[1]));
+ return state.items.at(path.parts[1]);
}
return state.item_cache;
}
@@ -365,7 +364,9 @@ bool is_valid_path(const rttt::Path &path) {
Path parse_path(std::string_view name) {
auto path = rttt::parse_path(name);
- path.type = SiteType::RSS;
+ path.basename = "/rss";
+ if (path.parts.size() > 1)
+ path.mode = list_mode::feed;
return path;
}
diff --git a/src/rttt/thing.hpp b/src/rttt/thing.hpp
index a84d189..eaf6e08 100644
--- a/src/rttt/thing.hpp
+++ b/src/rttt/thing.hpp
@@ -34,6 +34,7 @@ std::optional<rttt::Path> parse_path(std::string_view name) {
std::optional<rttt::Path> focus_path(rttt::Path &&path,
const ItemVariant &focus_item) {
+ // TODO: Use try_with here
auto maybe_id = try_id_string(focus_item);
if (!maybe_id || path.mode == list_mode::feed ||
path.mode == list_mode::comment)
@@ -63,9 +64,9 @@ std::optional<rttt::Path> unfocus_path(rttt::Path &&path) {
}
std::string path_url(const rttt::Path &path) {
- if (path.type == rttt::SiteType::HN) {
+ if (hackernews::is_valid_path(path)) {
return std::string("https://news.ycombinator.com/item?id=") + path.id;
- } else if (path.type == rttt::SiteType::Reddit) {
+ } else if (reddit::is_valid_path(path)) {
auto uri = reddit::getURIFromPath(path);
rttt::replaceAll(uri, "oauth", "www");
return uri;
@@ -96,7 +97,7 @@ bool catch_ui_event(state &state, ui::state &ui_state, const rttt::Path &path,
std::string window_header(const state &state, const rttt::Path &path) {
// TODO: Header should be responsibility of sources. Then we also don't have
// to pass username anymore
- if (path.type == rttt::SiteType::Reddit) {
+ if (reddit::is_valid_path(path)) {
if (!state.reddit_state.username.empty())
return fmt::format("[R] Reddit ({} on {})", state.reddit_state.username,
path.name);
diff --git a/src/rttt/timeline.hpp b/src/rttt/timeline.hpp
new file mode 100644
index 0000000..5c634b8
--- /dev/null
+++ b/src/rttt/timeline.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <memory>
+#include <vector>
+
+namespace rttt {
+namespace timeline {
+
+template<typename T>
+struct timeline_state {
+ std::vector<std::string> paths = {"/r/front", "/rss/Mike Blumenkrantz",
+ "/hn/top", "/r/funny"};
+ T *thing_state;
+};
+
+template<typename T>
+using state = std::shared_ptr<timeline_state<T>>;
+
+}; // namespace timeline
+}; // namespace rttt
diff --git a/src/rttt/twitter.hpp b/src/rttt/twitter.hpp
index 43b870b..0e173d8 100644
--- a/src/rttt/twitter.hpp
+++ b/src/rttt/twitter.hpp
@@ -387,7 +387,6 @@ bool is_valid_path(const rttt::Path &path) {
Path parse_path(std::string_view name) {
auto path = rttt::parse_path(name);
- path.type = SiteType::Twitter;
return path;
}
diff --git a/test/catch_hackernews.cpp b/test/catch_hackernews.cpp
index eae4718..46e8b16 100644
--- a/test/catch_hackernews.cpp
+++ b/test/catch_hackernews.cpp
@@ -62,7 +62,6 @@ SCENARIO("We can use the path API", "[.,api]") {
auto path = hackernews::parse_path(pth);
REQUIRE(path.parts[1] == "top");
- REQUIRE(path.type == SiteType::HN);
size_t count = 5000;
rttt::active_storage<std::string, view::item_state> dummy;
diff --git a/test/catch_peek.cpp b/test/catch_peek.cpp
new file mode 100644
index 0000000..2397212
--- /dev/null
+++ b/test/catch_peek.cpp
@@ -0,0 +1,69 @@
+#define CATCH_CONFIG_MAIN
+
+#include "catch2/catch.hpp"
+
+#include "rttt.hpp"
+#include "rttt/thing.hpp"
+
+namespace rttt {
+namespace peek {
+
+struct peek_state {
+ std::vector<std::string> paths = {"/r/front", "/rss/Mike Blumenkrantz",
+ "/hn/top", "/r/funny", "/tw/awesomekling"};
+ thing::state *thing_state;
+};
+
+using state = std::shared_ptr<peek_state>;
+
+bool is_valid_path(std::string_view path) {
+ return path == "/peek";
+}
+
+bool is_valid_path(const rttt::Path &path) {
+ return path.basename == "/peek";
+}
+
+std::optional<rttt::Path> parse_path(std::string_view path) {
+ if (peek::is_valid_path(path)) {
+ return rttt::parse_path(path);
+ }
+ return std::nullopt;
+}
+
+auto setup(state state, nlohmann::json config, thing::state * tstate) {
+ if (!state)
+ state = std::make_shared<peek_state>();
+ state->thing_state = tstate;
+ if (config.contains("peek") && config["peek"].contains("paths")) {
+ state->paths = config["peek"]["paths"].get<std::vector<std::string>>();
+ }
+ return state;
+}
+} // namespace peek
+} // namespace rttt
+
+using namespace rttt;
+
+// TODO: should we add a thing::is_valid_path(state, path), which uses the state to
+// infer which type to test for?
+//
+SCENARIO("We can parse peek path") {
+ REQUIRE(peek::is_valid_path("/peek"));
+ REQUIRE(!peek::is_valid_path("/r/peek"));
+
+ auto pth = peek::parse_path("/peek");
+ REQUIRE(pth.has_value());
+ REQUIRE(pth.value().parts[0] == "peek");
+ REQUIRE(peek::is_valid_path(pth.value()));
+
+ pth = peek::parse_path("/r/peek");
+ REQUIRE(!pth.has_value());
+}
+
+SCENARIO("We can use peek state") {
+ thing::state thing_state;
+ peek::state state;
+ nlohmann::json config;
+ peek::setup(state, config, &thing_state);
+}
diff --git a/test/catch_rss.cpp b/test/catch_rss.cpp
index 718eb5e..25fa840 100644
--- a/test/catch_rss.cpp
+++ b/test/catch_rss.cpp
@@ -14,16 +14,17 @@
using namespace rttt;
-// https://github.com/zeux/pugixml
-
-/*
- * Design notes:
- * use /rss/front as the main path
- *
- * Either have /rss/feedname as sub paths, or /rss/front/comments/feedname?
- * We want two views. one with the title etc, other with the full text included
- * (if available)
- */
+SCENARIO("Parse path works as expected") {
+ auto p = rss::parse_path("/rss");
+ REQUIRE(p.mode == rttt::list_mode::story);
+ REQUIRE(p.name == "/rss");
+ REQUIRE(p.basename == "/rss");
+
+ p = rss::parse_path("/rss/x1");
+ REQUIRE(p.mode == rttt::list_mode::feed);
+ REQUIRE(p.name == "/rss/x1");
+ REQUIRE(p.basename == "/rss");
+}
// rename to parse_opml?
std::map<std::string, std::string> parse_opml(const std::string &filename) {
diff --git a/test/catch_rttt.cpp b/test/catch_rttt.cpp
index 15be3f5..7cca304 100644
--- a/test/catch_rttt.cpp
+++ b/test/catch_rttt.cpp
@@ -6,59 +6,36 @@
#include "rttt/config.hpp"
SCENARIO("We can parse a path correctly") {
+ // TODO: Move this to the source specific tests
auto p = rttt::parse_path("/hn/news");
REQUIRE(p.mode == rttt::list_mode::story);
- REQUIRE(p.type == rttt::SiteType::HN);
REQUIRE(p.name == "/hn/news");
p = rttt::parse_path("/hn/top");
REQUIRE(p.mode == rttt::list_mode::story);
- REQUIRE(p.type == rttt::SiteType::HN);
REQUIRE(p.basename == "/hn/top");
REQUIRE(p.name == "/hn/top");
p = rttt::parse_path("/hn/news/comments/x1");
REQUIRE(p.mode == rttt::list_mode::comment);
- REQUIRE(p.type == rttt::SiteType::HN);
REQUIRE(p.basename == "/hn/news");
REQUIRE(p.name == "/hn/news/comments/x1");
REQUIRE(p.id == "x1");
p = rttt::parse_path("/r/news");
REQUIRE(p.mode == rttt::list_mode::story);
- REQUIRE(p.type == rttt::SiteType::Reddit);
REQUIRE(p.name == "/r/news");
p = rttt::parse_path("r/news");
REQUIRE(p.mode == rttt::list_mode::story);
- REQUIRE(p.type == rttt::SiteType::Reddit);
REQUIRE(p.name == "/r/news");
p = rttt::parse_path("/r/news/comments/x1");
REQUIRE(p.mode == rttt::list_mode::comment);
- REQUIRE(p.type == rttt::SiteType::Reddit);
REQUIRE(p.name == "/r/news/comments/x1");
REQUIRE(p.basename == "/r/news");
REQUIRE(p.id == "x1");
- p = rttt::parse_path("/rss/front");
- REQUIRE(p.mode == rttt::list_mode::story);
- REQUIRE(p.type == rttt::SiteType::RSS);
- REQUIRE(p.name == "/rss");
- REQUIRE(p.basename == "/rss");
-
- p = rttt::parse_path("/rss");
- REQUIRE(p.mode == rttt::list_mode::story);
- REQUIRE(p.type == rttt::SiteType::RSS);
- REQUIRE(p.name == "/rss");
- REQUIRE(p.basename == "/rss");
-
- p = rttt::parse_path("/rss/x1");
- REQUIRE(p.mode == rttt::list_mode::feed);
- REQUIRE(p.type == rttt::SiteType::RSS);
- REQUIRE(p.name == "/rss/x1");
- REQUIRE(p.basename == "/rss");
- REQUIRE(p.id == "x1");
}
SCENARIO("We can extract urls from text") {
diff --git a/test/catch_twitter.cpp b/test/catch_twitter.cpp
index 637baad..774a3e1 100644
--- a/test/catch_twitter.cpp
+++ b/test/catch_twitter.cpp
@@ -102,7 +102,6 @@ SCENARIO("We can use the path API", "[.api]") {
auto path = twitter::parse_path(pth);
REQUIRE(path.parts[1] == "awesomekling");
- REQUIRE(path.type == SiteType::Twitter);
size_t count = 5000;
rttt::active_storage<std::string, view::item_state> dummy;