feat(plugins): add basic message construction (#5754)

This commit is contained in:
nerix
2025-07-31 15:36:39 +02:00
committed by GitHub
parent 7e7c4112d7
commit a4478748f7
29 changed files with 2070 additions and 36 deletions
@@ -0,0 +1,24 @@
{
"input": "msg = {}",
"output": {
"badgeInfos": {
},
"badges": [
],
"channelName": "",
"count": 1,
"displayName": "",
"elements": [
],
"flags": "",
"id": "",
"localizedName": "",
"loginName": "",
"messageText": "",
"searchText": "",
"serverReceivedTime": "",
"timeoutUser": "",
"userID": "",
"usernameColor": "#ff000000"
}
}
@@ -0,0 +1,71 @@
{
"input": [
"msg = {elements={",
" { type = 'linebreak' },",
" { type = 'linebreak', flags = c2.MessageElementFlag.BttvEmoteImage },",
" { type = 'linebreak', tooltip = 't' },",
" { type = 'linebreak', trailing_space = false },",
"}}"
],
"output": {
"badgeInfos": {
},
"badges": [
],
"channelName": "",
"count": 1,
"displayName": "",
"elements": [
{
"flags": "",
"link": {
"type": "None",
"value": ""
},
"tooltip": "",
"trailingSpace": true,
"type": "LinebreakElement"
},
{
"flags": "BttvEmoteImage",
"link": {
"type": "None",
"value": ""
},
"tooltip": "",
"trailingSpace": true,
"type": "LinebreakElement"
},
{
"flags": "",
"link": {
"type": "None",
"value": ""
},
"tooltip": "t",
"trailingSpace": true,
"type": "LinebreakElement"
},
{
"flags": "",
"link": {
"type": "None",
"value": ""
},
"tooltip": "",
"trailingSpace": false,
"type": "LinebreakElement"
}
],
"flags": "",
"id": "",
"localizedName": "",
"loginName": "",
"messageText": "",
"searchText": "",
"serverReceivedTime": "",
"timeoutUser": "",
"userID": "",
"usernameColor": "#ff000000"
}
}
@@ -0,0 +1,103 @@
{
"input": [
"msg = {elements={",
" { type = 'mention', display_name = 'd', login_name = 'l', fallback_color = 'red', user_color = 'green' },",
" { type = 'mention', display_name = 'd', login_name = 'l', fallback_color = 'red', user_color = 'green', flags = c2.MessageElementFlag.BttvEmote },",
" { type = 'mention', display_name = 'd', login_name = 'l', fallback_color = 'red', user_color = 'green', tooltip = 't' },",
" { type = 'mention', display_name = 'd', login_name = 'l', fallback_color = 'red', user_color = 'green', trailing_space = false },",
"}}"
],
"output": {
"badgeInfos": {
},
"badges": [
],
"channelName": "",
"count": 1,
"displayName": "",
"elements": [
{
"color": "Text",
"fallbackColor": "#ffff0000",
"flags": "Text|Mention",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "MentionElement",
"userColor": "#ff008000",
"userLoginName": "l",
"words": [
"d"
]
},
{
"color": "Text",
"fallbackColor": "#ffff0000",
"flags": "Text|Mention",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "MentionElement",
"userColor": "#ff008000",
"userLoginName": "l",
"words": [
"d"
]
},
{
"color": "Text",
"fallbackColor": "#ffff0000",
"flags": "Text|Mention",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "t",
"trailingSpace": true,
"type": "MentionElement",
"userColor": "#ff008000",
"userLoginName": "l",
"words": [
"d"
]
},
{
"color": "Text",
"fallbackColor": "#ffff0000",
"flags": "Text|Mention",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": false,
"type": "MentionElement",
"userColor": "#ff008000",
"userLoginName": "l",
"words": [
"d"
]
}
],
"flags": "",
"id": "",
"localizedName": "",
"loginName": "",
"messageText": "",
"searchText": "",
"serverReceivedTime": "",
"timeoutUser": "",
"userID": "",
"usernameColor": "#ff000000"
}
}
@@ -0,0 +1,60 @@
{
"input": [
"msg = {",
" flags = c2.MessageFlag.System | c2.MessageFlag.Disabled,",
" id = 'foo-bar',",
" parse_time = 420000,",
" search_text = 'search',",
" message_text = 'message',",
" login_name = 'login',",
" display_name = 'display',",
" localized_name = 'local',",
" user_id = 'user-id',",
" username_color = 'blue',",
" server_received_time = 1230000,",
" highlight_color = '#12345678',",
" channel_name = 'channel',",
" elements = {",
" { type = 'text', text = 'aliens walking' }",
" }",
"}"
],
"output": {
"badgeInfos": {
},
"badges": [
],
"channelName": "channel",
"count": 1,
"displayName": "display",
"elements": [
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"aliens",
"walking"
]
}
],
"flags": "System|Disabled",
"highlightColor": "#12345678",
"id": "foo-bar",
"localizedName": "local",
"loginName": "login",
"messageText": "message",
"searchText": "search",
"serverReceivedTime": "1970-01-01T00:20:30Z",
"timeoutUser": "",
"userID": "user-id",
"usernameColor": "#ff0000ff"
}
}
@@ -0,0 +1,71 @@
{
"input": [
"msg = {elements={",
" { type = 'reply-curve' },",
" { type = 'reply-curve', flags = c2.MessageElementFlag.BttvEmote },",
" { type = 'reply-curve', tooltip = 't' },",
" { type = 'reply-curve', trailing_space = false },",
"}}"
],
"output": {
"badgeInfos": {
},
"badges": [
],
"channelName": "",
"count": 1,
"displayName": "",
"elements": [
{
"flags": "RepliedMessage",
"link": {
"type": "None",
"value": ""
},
"tooltip": "",
"trailingSpace": true,
"type": "ReplyCurveElement"
},
{
"flags": "RepliedMessage",
"link": {
"type": "None",
"value": ""
},
"tooltip": "",
"trailingSpace": true,
"type": "ReplyCurveElement"
},
{
"flags": "RepliedMessage",
"link": {
"type": "None",
"value": ""
},
"tooltip": "t",
"trailingSpace": true,
"type": "ReplyCurveElement"
},
{
"flags": "RepliedMessage",
"link": {
"type": "None",
"value": ""
},
"tooltip": "",
"trailingSpace": false,
"type": "ReplyCurveElement"
}
],
"flags": "",
"id": "",
"localizedName": "",
"loginName": "",
"messageText": "",
"searchText": "",
"serverReceivedTime": "",
"timeoutUser": "",
"userID": "",
"usernameColor": "#ff000000"
}
}
@@ -0,0 +1,188 @@
{
"input": [
"msg = {elements={",
" { type = 'single-line-text', text = '' },",
" { type = 'single-line-text', text = 'foo' },",
" { type = 'single-line-text', text = 'foo bar' },",
" { type = 'single-line-text', text = 'foo\\nbar' },",
" { type = 'single-line-text', text = 'foo', flags = c2.MessageElementFlag.Text | c2.MessageElementFlag.Timestamp },",
" { type = 'single-line-text', text = 'foo', color = 'text' },",
" { type = 'single-line-text', text = 'foo', color = 'system' },",
" { type = 'single-line-text', text = 'foo', color = 'link' },",
" { type = 'single-line-text', text = 'foo', color = 'green' },",
" { type = 'single-line-text', text = 'foo', style = c2.FontStyle.ChatSmall },",
"}}"
],
"output": {
"badgeInfos": {
},
"badges": [
],
"channelName": "",
"count": 1,
"displayName": "",
"elements": [
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "SingleLineTextElement",
"words": [
""
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "SingleLineTextElement",
"words": [
"foo"
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "SingleLineTextElement",
"words": [
"foo",
"bar"
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "SingleLineTextElement",
"words": [
"foo\nbar"
]
},
{
"color": "Text",
"flags": "Text|Timestamp",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "SingleLineTextElement",
"words": [
"foo"
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "SingleLineTextElement",
"words": [
"foo"
]
},
{
"color": "System",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "SingleLineTextElement",
"words": [
"foo"
]
},
{
"color": "Link",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "SingleLineTextElement",
"words": [
"foo"
]
},
{
"color": "#ff008000",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "SingleLineTextElement",
"words": [
"foo"
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatSmall",
"tooltip": "",
"trailingSpace": true,
"type": "SingleLineTextElement",
"words": [
"foo"
]
}
],
"flags": "",
"id": "",
"localizedName": "",
"loginName": "",
"messageText": "",
"searchText": "",
"serverReceivedTime": "",
"timeoutUser": "",
"userID": "",
"usernameColor": "#ff000000"
}
}
@@ -0,0 +1,188 @@
{
"input": [
"msg = {elements={",
" { type = 'text', text = '' },",
" { type = 'text', text = 'foo' },",
" { type = 'text', text = 'foo bar' },",
" { type = 'text', text = 'foo\\nbar' },",
" { type = 'text', text = 'foo', flags = c2.MessageElementFlag.Text | c2.MessageElementFlag.Timestamp },",
" { type = 'text', text = 'foo', color = 'text' },",
" { type = 'text', text = 'foo', color = 'system' },",
" { type = 'text', text = 'foo', color = 'link' },",
" { type = 'text', text = 'foo', color = 'green' },",
" { type = 'text', text = 'foo', style = c2.FontStyle.ChatSmall },",
"}}"
],
"output": {
"badgeInfos": {
},
"badges": [
],
"channelName": "",
"count": 1,
"displayName": "",
"elements": [
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
""
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"foo"
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"foo",
"bar"
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"foo\nbar"
]
},
{
"color": "Text",
"flags": "Text|Timestamp",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"foo"
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"foo"
]
},
{
"color": "System",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"foo"
]
},
{
"color": "Link",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"foo"
]
},
{
"color": "#ff008000",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"foo"
]
},
{
"color": "Text",
"flags": "Text",
"link": {
"type": "None",
"value": ""
},
"style": "ChatSmall",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"foo"
]
}
],
"flags": "",
"id": "",
"localizedName": "",
"loginName": "",
"messageText": "",
"searchText": "",
"serverReceivedTime": "",
"timeoutUser": "",
"userID": "",
"usernameColor": "#ff000000"
}
}
@@ -0,0 +1,139 @@
{
"input": [
"msg = {elements={",
" { type = 'timestamp' },",
" { type = 'timestamp', time = 1230000, flags = c2.MessageElementFlag.BttvEmote },",
" { type = 'timestamp', tooltip = 't' },",
" { type = 'timestamp', trailing_space = false },",
"}}"
],
"output": {
"badgeInfos": {
},
"badges": [
],
"channelName": "",
"count": 1,
"displayName": "",
"elements": [
{
"element": {
"color": "System",
"flags": "Timestamp",
"link": {
"type": "None",
"value": ""
},
"style": "TimestampMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"0:00"
]
},
"flags": "Timestamp",
"format": "",
"link": {
"type": "None",
"value": ""
},
"time": "00:00:00",
"tooltip": "",
"trailingSpace": true,
"type": "TimestampElement"
},
{
"element": {
"color": "System",
"flags": "Timestamp",
"link": {
"type": "None",
"value": ""
},
"style": "TimestampMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"0:20"
]
},
"flags": "Timestamp",
"format": "",
"link": {
"type": "None",
"value": ""
},
"time": "00:20:30",
"tooltip": "",
"trailingSpace": true,
"type": "TimestampElement"
},
{
"element": {
"color": "System",
"flags": "Timestamp",
"link": {
"type": "None",
"value": ""
},
"style": "TimestampMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"0:00"
]
},
"flags": "Timestamp",
"format": "",
"link": {
"type": "None",
"value": ""
},
"time": "00:00:00",
"tooltip": "t",
"trailingSpace": true,
"type": "TimestampElement"
},
{
"element": {
"color": "System",
"flags": "Timestamp",
"link": {
"type": "None",
"value": ""
},
"style": "TimestampMedium",
"tooltip": "",
"trailingSpace": true,
"type": "TextElement",
"words": [
"0:00"
]
},
"flags": "Timestamp",
"format": "",
"link": {
"type": "None",
"value": ""
},
"time": "00:00:00",
"tooltip": "",
"trailingSpace": false,
"type": "TimestampElement"
}
],
"flags": "",
"id": "",
"localizedName": "",
"loginName": "",
"messageText": "",
"searchText": "",
"serverReceivedTime": "",
"timeoutUser": "",
"userID": "",
"usernameColor": "#ff000000"
}
}
@@ -0,0 +1,71 @@
{
"input": [
"msg = {elements={",
" { type = 'twitch-moderation' },",
" { type = 'twitch-moderation', flags = c2.MessageElementFlag.BttvEmote },",
" { type = 'twitch-moderation', tooltip = 't' },",
" { type = 'twitch-moderation', trailing_space = false },",
"}}"
],
"output": {
"badgeInfos": {
},
"badges": [
],
"channelName": "",
"count": 1,
"displayName": "",
"elements": [
{
"flags": "ModeratorTools",
"link": {
"type": "None",
"value": ""
},
"tooltip": "",
"trailingSpace": true,
"type": "TwitchModerationElement"
},
{
"flags": "ModeratorTools",
"link": {
"type": "None",
"value": ""
},
"tooltip": "",
"trailingSpace": true,
"type": "TwitchModerationElement"
},
{
"flags": "ModeratorTools",
"link": {
"type": "None",
"value": ""
},
"tooltip": "t",
"trailingSpace": true,
"type": "TwitchModerationElement"
},
{
"flags": "ModeratorTools",
"link": {
"type": "None",
"value": ""
},
"tooltip": "",
"trailingSpace": false,
"type": "TwitchModerationElement"
}
],
"flags": "",
"id": "",
"localizedName": "",
"loginName": "",
"messageText": "",
"searchText": "",
"serverReceivedTime": "",
"timeoutUser": "",
"userID": "",
"usernameColor": "#ff000000"
}
}
+151 -1
View File
@@ -10,6 +10,8 @@
# include "controllers/plugins/PluginController.hpp"
# include "controllers/plugins/PluginPermission.hpp"
# include "controllers/plugins/SolTypes.hpp" // IWYU pragma: keep
# include "lib/Snapshot.hpp"
# include "messages/Message.hpp"
# include "mocks/BaseApplication.hpp"
# include "mocks/Channel.hpp"
# include "mocks/Emotes.hpp"
@@ -32,6 +34,8 @@ using chatterino::mock::MockChannel;
namespace {
constexpr bool UPDATE_SNAPSHOTS = false;
const QString TEST_SETTINGS = R"(
{
"plugins": {
@@ -104,7 +108,7 @@ public:
}
PluginController plugins;
mock::EmptyLogging logging;
mock::Logging logging;
CommandController commands;
mock::Emotes emotes;
MockTwitch twitch;
@@ -861,4 +865,150 @@ TEST_F(PluginTest, testWebSocketUnsetFns)
waiter.waitForRequest();
}
TEST_F(PluginTest, MessageElementFlag)
{
configure();
lua->script(R"lua(
values = {}
for k, v in pairs(c2.MessageElementFlag) do
table.insert(values, ("%s=0x%x"):format(k, v))
end
table.sort(values, function(a, b) return a:lower() < b:lower() end)
out = table.concat(values, ",")
)lua");
const char *VALUES = "AlwaysShow=0x2000000,"
"BadgeChannelAuthority=0x8000,"
"BadgeChatterino=0x40000,"
"BadgeFfz=0x80000,"
"BadgeGlobalAuthority=0x2000,"
"BadgePredictions=0x4000,"
"BadgeSevenTV=0x1000000000,"
"BadgeSharedChannel=0x2000000000,"
"BadgeSubscription=0x10000,"
"BadgeVanity=0x20000,"
"BitsAmount=0x200000,"
"BitsAnimated=0x1000,"
"BitsStatic=0x800,"
"BttvEmoteImage=0x40,"
"BttvEmoteText=0x80,"
"ChannelName=0x100000,"
"ChannelPointReward=0x100,"
"Collapsed=0x4000000,"
"EmojiImage=0x800000,"
"EmojiText=0x1000000,"
"FfzEmoteImage=0x200,"
"FfzEmoteText=0x400,"
"LowercaseLinks=0x20000000,"
"Mention=0x8000000,"
"Misc=0x1,"
"ModeratorTools=0x400000,"
"RepliedMessage=0x100000000,"
"ReplyButton=0x200000000,"
"SevenTVEmoteImage=0x400000000,"
"SevenTVEmoteText=0x800000000,"
"Text=0x2,"
"Timestamp=0x8,"
"TwitchEmoteImage=0x10,"
"TwitchEmoteText=0x20,"
"Username=0x4";
std::string got = (*lua)["out"];
ASSERT_EQ(got, VALUES);
}
TEST_F(PluginTest, ChannelAddMessage)
{
configure();
lua->script(R"lua(
function do_it(chan)
local Repost = c2.MessageContext.Repost
local Original = c2.MessageContext.Original
chan:add_message(c2.Message.new({ id = "1" }))
chan:add_message(c2.Message.new({ id = "2" }), Repost)
chan:add_message(c2.Message.new({ id = "3" }), Original, nil)
chan:add_message(c2.Message.new({ id = "4" }), Repost, c2.MessageFlag.DoNotLog)
chan:add_message(c2.Message.new({ id = "5" }), Original, c2.MessageFlag.DoNotLog)
chan:add_message(c2.Message.new({ id = "6" }), Original, c2.MessageFlag.System)
end
)lua");
auto chan = std::make_shared<MockChannel>("mock");
std::vector<MessagePtr> logged;
EXPECT_CALL(this->app->logging, addMessage)
.Times(3)
.WillRepeatedly(
[&](const auto &, const auto &msg, const auto &, const auto &) {
logged.emplace_back(msg);
});
std::vector<std::pair<MessagePtr, std::optional<MessageFlags>>> added;
std::ignore = chan->messageAppended.connect([&](auto &&...args) {
added.emplace_back(std::forward<decltype(args)>(args)...);
});
(*lua)["do_it"](lua::api::ChannelRef(chan));
ASSERT_EQ(added.size(), 6);
ASSERT_EQ(added[0].first->id, "1");
ASSERT_FALSE(added[0].second.has_value());
ASSERT_EQ(added[1].first->id, "2");
ASSERT_FALSE(added[1].second.has_value());
ASSERT_EQ(added[2].first->id, "3");
ASSERT_FALSE(added[2].second.has_value());
ASSERT_EQ(added[3].first->id, "4");
ASSERT_EQ(added[3].second, MessageFlags{MessageFlag::DoNotLog});
ASSERT_EQ(added[4].first->id, "5");
ASSERT_EQ(added[4].second, MessageFlags{MessageFlag::DoNotLog});
ASSERT_EQ(added[5].first->id, "6");
ASSERT_EQ(added[5].second, MessageFlags{MessageFlag::System});
ASSERT_EQ(logged.size(), 3);
ASSERT_EQ(added[0].first, logged[0]);
ASSERT_EQ(added[2].first, logged[1]);
ASSERT_EQ(added[5].first, logged[2]);
}
class PluginMessageConstructionTest
: public PluginTest,
public ::testing::WithParamInterface<QString>
{
};
TEST_P(PluginMessageConstructionTest, Run)
{
auto fixture = testlib::Snapshot::read("PluginMessageCtor", GetParam());
configure();
std::string script;
if (fixture->input().isArray())
{
for (auto line : fixture->input().toArray())
{
script += line.toString().toStdString() + '\n';
}
}
else
{
script = fixture->inputString().toStdString() + '\n';
}
script += "out = c2.Message.new(msg)";
lua->script(script);
Message *got = (*lua)["out"];
ASSERT_TRUE(fixture->run(got->toJson(), UPDATE_SNAPSHOTS));
}
INSTANTIATE_TEST_SUITE_P(
PluginMessageConstruction, PluginMessageConstructionTest,
testing::ValuesIn(testlib::Snapshot::discover("PluginMessageCtor")));
// verify that all snapshots are included
TEST(PluginMessageConstructionTest, Integrity)
{
ASSERT_FALSE(UPDATE_SNAPSHOTS); // make sure fixtures are actually tested
}
#endif
+2 -2
View File
@@ -41,9 +41,9 @@ namespace chatterino::testlib {
///
/// TEST_P(ExampleTest, Run) {
/// auto fixture = testlib::Snapshot::read("category", GetParam());
/// auto output = functionToTest(fixture.input()); // or input{String,Utf8}
/// auto output = functionToTest(fixture->input()); // or input{String,Utf8}
/// // if snapshots are supposed to be updated, this will write the output
/// ASSERT_TRUE(fixture.run(output, UPDATE_SNAPSHOTS));
/// ASSERT_TRUE(fixture->run(output, UPDATE_SNAPSHOTS));
/// }
///
/// INSTANTIATE_TEST_SUITE_P(ExampleInstance, ExampleTest,