blob: 705bdc5697864c1072740cb86a4186e34533e2d9 [file] [log] [blame]
James Robinsona9763132014-10-06 11:18:13 -07001// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "gin/modules/timer.h"
6
7#include "base/memory/scoped_ptr.h"
8#include "base/message_loop/message_loop.h"
9#include "gin/handle.h"
10#include "gin/object_template_builder.h"
11#include "gin/public/isolate_holder.h"
12#include "gin/shell_runner.h"
13#include "gin/test/v8_test.h"
14#include "gin/try_catch.h"
15#include "gin/wrappable.h"
16#include "v8/include/v8.h"
17
18namespace gin {
19
20namespace {
21
22class Result : public Wrappable<Result> {
23 public:
24 static WrapperInfo kWrapperInfo;
25 static Handle<Result> Create(v8::Isolate* isolate) {
26 return CreateHandle(isolate, new Result());
27 }
28
29 int count() const { return count_; }
30 void set_count(int count) { count_ = count; }
31
32 void Quit() {
33 base::MessageLoop::current()->QuitNow();
34 }
35
36 private:
37 Result() : count_(0) {
38 }
39
James Robinson30d547e2014-10-23 18:20:06 -070040 ~Result() override {}
James Robinsona9763132014-10-06 11:18:13 -070041
James Robinson30d547e2014-10-23 18:20:06 -070042 ObjectTemplateBuilder GetObjectTemplateBuilder(
James Robinsone2ac7e82014-10-15 13:21:59 -070043 v8::Isolate* isolate) override {
James Robinsona9763132014-10-06 11:18:13 -070044 return Wrappable<Result>::GetObjectTemplateBuilder(isolate)
45 .SetProperty("count", &Result::count, &Result::set_count)
46 .SetMethod("quit", &Result::Quit);
47 }
48
49 int count_;
50};
51
52WrapperInfo Result::kWrapperInfo = { gin::kEmbedderNativeGin };
53
54struct TestHelper {
55 TestHelper(v8::Isolate* isolate)
56 : runner(new ShellRunner(&delegate, isolate)),
57 scope(runner.get()),
58 timer_module(TimerModule::Create(isolate)),
59 result(Result::Create(isolate)) {
60 EXPECT_FALSE(runner->global().IsEmpty());
61 runner->global()->Set(StringToV8(isolate, "timer"),
62 timer_module->GetWrapper(isolate));
63 runner->global()->Set(StringToV8(isolate, "result"),
64 result->GetWrapper(isolate));
65 }
66
67 void QuitSoon() {
68 loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
69 base::TimeDelta::FromMilliseconds(0));
70 }
71
72 ShellRunnerDelegate delegate;
73 scoped_ptr<ShellRunner> runner;
74 Runner::Scope scope;
75 Handle<TimerModule> timer_module;
76 Handle<Result> result;
77 base::MessageLoop loop;
78};
79
80} // namespace
81
82typedef V8Test TimerUnittest;
83
84TEST_F(TimerUnittest, OneShot) {
85 TestHelper helper(instance_->isolate());
86 std::string source =
87 "timer.createOneShot(0, function() {"
88 " result.count++;"
89 "});";
90
91 helper.runner->Run(source, "script");
92 EXPECT_EQ(0, helper.result->count());
93
94 helper.QuitSoon();
95 helper.loop.Run();
96 EXPECT_EQ(1, helper.result->count());
97}
98
99TEST_F(TimerUnittest, OneShotCancel) {
100 TestHelper helper(instance_->isolate());
101 std::string source =
102 "var t = timer.createOneShot(0, function() {"
103 " result.count++;"
104 "});"
105 "t.cancel()";
106
107 helper.runner->Run(source, "script");
108 EXPECT_EQ(0, helper.result->count());
109
110 helper.QuitSoon();
111 helper.loop.Run();
112 EXPECT_EQ(0, helper.result->count());
113}
114
115TEST_F(TimerUnittest, Repeating) {
116 TestHelper helper(instance_->isolate());
117
118 // TODO(aa): Cannot do: if (++result.count == 3) because of v8 bug. Create
119 // test case and report.
120 std::string source =
121 "timer.createRepeating(0, function() {"
122 " result.count++;"
123 " if (result.count == 3) {"
124 " result.quit();"
125 " }"
126 "});";
127
128 helper.runner->Run(source, "script");
129 EXPECT_EQ(0, helper.result->count());
130
131 helper.loop.Run();
132 EXPECT_EQ(3, helper.result->count());
133}
134
135TEST_F(TimerUnittest, TimerCallbackToDestroyedRunner) {
136 TestHelper helper(instance_->isolate());
137 std::string source =
138 "timer.createOneShot(0, function() {"
139 " result.count++;"
140 "});";
141
142 helper.runner->Run(source, "script");
143 EXPECT_EQ(0, helper.result->count());
144
145 // Destroy runner, which should destroy the timer object we created.
146 helper.QuitSoon();
147 helper.runner.reset(NULL);
148 helper.loop.Run();
149
150 // Timer should not have run because it was deleted.
151 EXPECT_EQ(0, helper.result->count());
152}
153
154} // namespace gin