• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
18 namespace gin {
19 
20 namespace {
21 
22 class Result : public Wrappable<Result> {
23  public:
24   static WrapperInfo kWrapperInfo;
Create(v8::Isolate * isolate)25   static Handle<Result> Create(v8::Isolate* isolate) {
26     return CreateHandle(isolate, new Result());
27   }
28 
count() const29   int count() const { return count_; }
set_count(int count)30   void set_count(int count) { count_ = count; }
31 
Quit()32   void Quit() {
33     base::MessageLoop::current()->QuitNow();
34   }
35 
36  private:
Result()37   Result() : count_(0) {
38   }
39 
~Result()40   virtual ~Result() {
41   }
42 
GetObjectTemplateBuilder(v8::Isolate * isolate)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 
53 WrapperInfo Result::kWrapperInfo = { gin::kEmbedderNativeGin };
54 
55 struct TestHelper {
TestHelpergin::__anonab299e8b0111::TestHelper56   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 
QuitSoongin::__anonab299e8b0111::TestHelper68   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 
83 typedef V8Test TimerUnittest;
84 
TEST_F(TimerUnittest,OneShot)85 TEST_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 
TEST_F(TimerUnittest,OneShotCancel)100 TEST_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 
TEST_F(TimerUnittest,Repeating)116 TEST_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 
TEST_F(TimerUnittest,TimerCallbackToDestroyedRunner)136 TEST_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