Home | History | Annotate | Download | only in cctest
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include "src/v8.h"
     29 
     30 #include "test/cctest/cctest.h"
     31 
     32 using namespace v8;
     33 namespace i = v8::internal;
     34 
     35 namespace {
     36 class HarmonyIsolate {
     37  public:
     38   HarmonyIsolate() {
     39     isolate_ = Isolate::New();
     40     isolate_->Enter();
     41   }
     42 
     43   ~HarmonyIsolate() {
     44     isolate_->Exit();
     45     isolate_->Dispose();
     46   }
     47 
     48   Isolate* GetIsolate() const { return isolate_; }
     49 
     50  private:
     51   Isolate* isolate_;
     52 };
     53 }
     54 
     55 
     56 TEST(MicrotaskDeliverySimple) {
     57   HarmonyIsolate isolate;
     58   HandleScope scope(isolate.GetIsolate());
     59   LocalContext context(isolate.GetIsolate());
     60   CompileRun(
     61       "var ordering = [];"
     62       "var resolver = {};"
     63       "function handler(resolve) { resolver.resolve = resolve; }"
     64       "var obj = {};"
     65       "var observeOrders = [1, 4];"
     66       "function observer() {"
     67         "ordering.push(observeOrders.shift());"
     68         "resolver.resolve();"
     69       "}"
     70       "var p = new Promise(handler);"
     71       "p.then(function() {"
     72         "ordering.push(2);"
     73       "}).then(function() {"
     74         "ordering.push(3);"
     75         "obj.id++;"
     76         "return new Promise(handler);"
     77       "}).then(function() {"
     78         "ordering.push(5);"
     79       "}).then(function() {"
     80         "ordering.push(6);"
     81       "});"
     82       "Object.observe(obj, observer);"
     83       "obj.id = 1;");
     84   CHECK_EQ(6, CompileRun("ordering.length")->Int32Value());
     85   CHECK_EQ(1, CompileRun("ordering[0]")->Int32Value());
     86   CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value());
     87   CHECK_EQ(3, CompileRun("ordering[2]")->Int32Value());
     88   CHECK_EQ(4, CompileRun("ordering[3]")->Int32Value());
     89   CHECK_EQ(5, CompileRun("ordering[4]")->Int32Value());
     90   CHECK_EQ(6, CompileRun("ordering[5]")->Int32Value());
     91 }
     92 
     93 
     94 TEST(MicrotaskPerIsolateState) {
     95   HarmonyIsolate isolate;
     96   HandleScope scope(isolate.GetIsolate());
     97   LocalContext context1(isolate.GetIsolate());
     98   isolate.GetIsolate()->SetAutorunMicrotasks(false);
     99   CompileRun(
    100       "var obj = { calls: 0 };");
    101   Handle<Value> obj = CompileRun("obj");
    102   {
    103     LocalContext context2(isolate.GetIsolate());
    104     context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
    105                             obj);
    106     CompileRun(
    107         "var resolver = {};"
    108         "new Promise(function(resolve) {"
    109           "resolver.resolve = resolve;"
    110         "}).then(function() {"
    111           "obj.calls++;"
    112         "});"
    113         "(function() {"
    114           "resolver.resolve();"
    115         "})();");
    116   }
    117   {
    118     LocalContext context3(isolate.GetIsolate());
    119     context3->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
    120                             obj);
    121     CompileRun(
    122         "var foo = { id: 1 };"
    123         "Object.observe(foo, function() {"
    124           "obj.calls++;"
    125         "});"
    126         "foo.id++;");
    127   }
    128   {
    129     LocalContext context4(isolate.GetIsolate());
    130     context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
    131                             obj);
    132     isolate.GetIsolate()->RunMicrotasks();
    133     CHECK_EQ(2, CompileRun("obj.calls")->Int32Value());
    134   }
    135 }
    136