blob: 651efd1e45e96ec645c29e19678cdc785693453f [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.h"
#include <initializer_list>
#include <vector>
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/html/custom/custom_element_reaction.h"
#include "third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
TEST(CustomElementReactionQueueTest, invokeReactions_one) {
std::vector<char> log;
CustomElementReactionQueue* queue = new CustomElementReactionQueue();
HeapVector<Member<Command>>* commands =
MakeGarbageCollected<HeapVector<Member<Command>>>();
commands->push_back(MakeGarbageCollected<Log>('a', log));
queue->Add(MakeGarbageCollected<TestReaction>(commands));
queue->InvokeReactions(nullptr);
EXPECT_EQ(log, std::vector<char>({'a'}))
<< "the reaction should have been invoked";
}
TEST(CustomElementReactionQueueTest, invokeReactions_many) {
std::vector<char> log;
CustomElementReactionQueue* queue = new CustomElementReactionQueue();
{
HeapVector<Member<Command>>* commands =
MakeGarbageCollected<HeapVector<Member<Command>>>();
commands->push_back(MakeGarbageCollected<Log>('a', log));
queue->Add(MakeGarbageCollected<TestReaction>(commands));
}
{
HeapVector<Member<Command>>* commands =
MakeGarbageCollected<HeapVector<Member<Command>>>();
commands->push_back(MakeGarbageCollected<Log>('b', log));
queue->Add(MakeGarbageCollected<TestReaction>(commands));
}
{
HeapVector<Member<Command>>* commands =
MakeGarbageCollected<HeapVector<Member<Command>>>();
commands->push_back(MakeGarbageCollected<Log>('c', log));
queue->Add(MakeGarbageCollected<TestReaction>(commands));
}
queue->InvokeReactions(nullptr);
EXPECT_EQ(log, std::vector<char>({'a', 'b', 'c'}))
<< "the reaction should have been invoked";
}
TEST(CustomElementReactionQueueTest, invokeReactions_recursive) {
std::vector<char> log;
CustomElementReactionQueue* queue = new CustomElementReactionQueue();
HeapVector<Member<Command>>* third_commands =
MakeGarbageCollected<HeapVector<Member<Command>>>();
third_commands->push_back(MakeGarbageCollected<Log>('c', log));
third_commands->push_back(MakeGarbageCollected<Recurse>(queue));
CustomElementReaction* third =
MakeGarbageCollected<TestReaction>(third_commands); // "Empty" recursion
HeapVector<Member<Command>>* second_commands =
MakeGarbageCollected<HeapVector<Member<Command>>>();
second_commands->push_back(MakeGarbageCollected<Log>('b', log));
second_commands->push_back(MakeGarbageCollected<Enqueue>(queue, third));
CustomElementReaction* second = MakeGarbageCollected<TestReaction>(
second_commands); // Unwinds one level of recursion
HeapVector<Member<Command>>* first_commands =
MakeGarbageCollected<HeapVector<Member<Command>>>();
first_commands->push_back(MakeGarbageCollected<Log>('a', log));
first_commands->push_back(MakeGarbageCollected<Enqueue>(queue, second));
first_commands->push_back(MakeGarbageCollected<Recurse>(queue));
CustomElementReaction* first = MakeGarbageCollected<TestReaction>(
first_commands); // Non-empty recursion
queue->Add(first);
queue->InvokeReactions(nullptr);
EXPECT_EQ(log, std::vector<char>({'a', 'b', 'c'}))
<< "the reactions should have been invoked";
}
TEST(CustomElementReactionQueueTest, clear_duringInvoke) {
std::vector<char> log;
CustomElementReactionQueue* queue = new CustomElementReactionQueue();
{
HeapVector<Member<Command>>* commands =
MakeGarbageCollected<HeapVector<Member<Command>>>();
commands->push_back(MakeGarbageCollected<Log>('a', log));
queue->Add(MakeGarbageCollected<TestReaction>(commands));
}
{
HeapVector<Member<Command>>* commands =
MakeGarbageCollected<HeapVector<Member<Command>>>();
commands->push_back(new Call(WTF::Bind(
[](CustomElementReactionQueue* queue, Element*) { queue->Clear(); },
WrapPersistent(queue))));
queue->Add(MakeGarbageCollected<TestReaction>(commands));
}
{
HeapVector<Member<Command>>* commands =
MakeGarbageCollected<HeapVector<Member<Command>>>();
commands->push_back(MakeGarbageCollected<Log>('b', log));
queue->Add(MakeGarbageCollected<TestReaction>(commands));
}
queue->InvokeReactions(nullptr);
EXPECT_EQ(log, std::vector<char>({'a'}))
<< "only 'a' should be logged; the second log should have been cleared";
}
} // namespace blink