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