diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2011-09-15 09:41:08 -0700 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2011-09-15 09:42:06 -0700 |
commit | 1b15af9dd2bf4adb7a2e73ae17a12e2e98a88f72 (patch) | |
tree | feede6d06b8c99b92e29a9fdcf0e9ade05b981d0 /deps/v8/test | |
parent | f8b90946aec53b453d82dd66a4d812ec86487629 (diff) | |
download | node-new-1b15af9dd2bf4adb7a2e73ae17a12e2e98a88f72.tar.gz |
Upgrade V8 to 3.6.4
Diffstat (limited to 'deps/v8/test')
23 files changed, 1339 insertions, 145 deletions
diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h index b0b8eb720a..c04d893c10 100644 --- a/deps/v8/test/cctest/cctest.h +++ b/deps/v8/test/cctest/cctest.h @@ -110,6 +110,7 @@ class ApiTestFuzzer: public v8::internal::Thread { // This method switches threads if we are running the Threading test. // Otherwise it does nothing. static void Fuzz(); + private: static bool fuzzing_; static int tests_being_run_; diff --git a/deps/v8/test/cctest/log-eq-of-logging-and-traversal.js b/deps/v8/test/cctest/log-eq-of-logging-and-traversal.js index cd52da545a..05643bfb8a 100644 --- a/deps/v8/test/cctest/log-eq-of-logging-and-traversal.js +++ b/deps/v8/test/cctest/log-eq-of-logging-and-traversal.js @@ -43,8 +43,7 @@ function LogProcessor() { processor: this.processCodeCreation }, 'code-move': { parsers: [parseInt, parseInt], processor: this.processCodeMove }, - 'code-delete': { parsers: [parseInt], - processor: this.processCodeDelete }, + 'code-delete': null, 'sfi-move': { parsers: [parseInt, parseInt], processor: this.processFunctionMove }, 'shared-library': null, @@ -73,10 +72,6 @@ LogProcessor.prototype.processCodeMove = function(from, to) { this.profile.moveCode(from, to); }; -LogProcessor.prototype.processCodeDelete = function(start) { - this.profile.deleteCode(start); -}; - LogProcessor.prototype.processFunctionMove = function(from, to) { this.profile.moveFunc(from, to); }; @@ -132,8 +127,8 @@ function RunTest() { "Script", "String", "RegExp", "Date", "Error"]; function entitiesEqual(entityA, entityB) { - if (entityA === null && entityB !== null) return true; - if (entityA !== null && entityB === null) return false; + if ((entityA === null && entityB !== null) || + (entityA !== null && entityB === null)) return true; return entityA.size === entityB.size && entityNamesEqual(entityA, entityB); } @@ -145,6 +140,8 @@ function RunTest() { // find the same entries. We skip builtins during log parsing, but compiled // functions traversal may erroneously recognize them as functions, so we are // expecting more functions in traversal vs. logging. + // Since we don't track code deletions, logging can also report more entries + // than traversal. while (l_pos < l_len && t_pos < t_len) { var entryA = logging_entries[l_pos]; var entryB = traversal_entries[t_pos]; @@ -166,11 +163,6 @@ function RunTest() { if (!entities_equal) equal = false; comparison.push([entities_equal, address, entityA, entityB]); } - if (l_pos < l_len) equal = false; - while (l_pos < l_len) { - var entryA = logging_entries[l_pos++]; - comparison.push([false, entryA[0], entryA[1], null]); - } return [equal, comparison]; } diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc index 81c487da8a..f567a0f770 100644 --- a/deps/v8/test/cctest/test-cpu-profiler.cc +++ b/deps/v8/test/cctest/test-cpu-profiler.cc @@ -107,7 +107,7 @@ TEST(CodeEvents) { 0x80); processor.CodeMoveEvent(ToAddress(0x1400), ToAddress(0x1500)); processor.CodeCreateEvent(i::Logger::STUB_TAG, 3, ToAddress(0x1600), 0x10); - processor.CodeDeleteEvent(ToAddress(0x1600)); + processor.CodeCreateEvent(i::Logger::STUB_TAG, 4, ToAddress(0x1605), 0x10); // Enqueue a tick event to enable code events processing. EnqueueTickSampleEvent(&processor, ToAddress(0x1000)); diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc index b7962de2e9..45da6dc0bd 100644 --- a/deps/v8/test/cctest/test-debug.cc +++ b/deps/v8/test/cctest/test-debug.cc @@ -157,6 +157,7 @@ class DebugLocalContext { Handle<Object>(debug->debug_context()->global_proxy()), DONT_ENUM, ::v8::internal::kNonStrictMode); } + private: v8::Persistent<v8::Context> context_; }; @@ -5916,7 +5917,7 @@ class DebuggerAgentProtocolServerThread : public i::Thread { private: int port_; - i::SmartPointer<char> body_; + i::SmartArrayPointer<char> body_; i::Socket* server_; // Server socket used for bind/accept. i::Socket* client_; // Single client connection used by the test. i::Semaphore* listening_; // Signalled when the server is in listen mode. diff --git a/deps/v8/test/cctest/test-func-name-inference.cc b/deps/v8/test/cctest/test-func-name-inference.cc index 4d993af4a3..bfae4d1360 100644 --- a/deps/v8/test/cctest/test-func-name-inference.cc +++ b/deps/v8/test/cctest/test-func-name-inference.cc @@ -41,7 +41,7 @@ using ::v8::internal::JSFunction; using ::v8::internal::Object; using ::v8::internal::Runtime; using ::v8::internal::Script; -using ::v8::internal::SmartPointer; +using ::v8::internal::SmartArrayPointer; using ::v8::internal::SharedFunctionInfo; using ::v8::internal::String; @@ -96,7 +96,7 @@ static void CheckFunctionName(v8::Handle<v8::Script> script, SharedFunctionInfo::cast(shared_func_info_ptr)); // Verify inferred function name. - SmartPointer<char> inferred_name = + SmartArrayPointer<char> inferred_name = shared_func_info->inferred_name()->ToCString(); CHECK_EQ(ref_inferred_name, *inferred_name); #endif // ENABLE_DEBUGGER_SUPPORT diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc index 24d96193a2..1769c1b7d5 100644 --- a/deps/v8/test/cctest/test-heap-profiler.cc +++ b/deps/v8/test/cctest/test-heap-profiler.cc @@ -892,7 +892,7 @@ TEST(NodesIteration) { static int StringCmp(const char* ref, i::String* act) { - i::SmartPointer<char> s_act = act->ToCString(); + i::SmartArrayPointer<char> s_act = act->ToCString(); int result = strcmp(ref, *s_act); if (result != 0) fprintf(stderr, "Expected: \"%s\", Actual: \"%s\"\n", ref, *s_act); diff --git a/deps/v8/test/cctest/test-lockers.cc b/deps/v8/test/cctest/test-lockers.cc index d61fde250c..7360da52b1 100644 --- a/deps/v8/test/cctest/test-lockers.cc +++ b/deps/v8/test/cctest/test-lockers.cc @@ -142,6 +142,7 @@ class JoinableThread { } virtual void Run() = 0; + private: class ThreadWithSemaphore : public i::Thread { public: @@ -377,6 +378,7 @@ class LockerUnlockerThread : public JoinableThread { CalcFibAndCheck(); } } + private: v8::Isolate* isolate_; }; @@ -429,6 +431,7 @@ class LockTwiceAndUnlockThread : public JoinableThread { CalcFibAndCheck(); } } + private: v8::Isolate* isolate_; }; @@ -498,6 +501,7 @@ class LockAndUnlockDifferentIsolatesThread : public JoinableThread { thread.Join(); } } + private: v8::Isolate* isolate1_; v8::Isolate* isolate2_; diff --git a/deps/v8/test/cctest/test-log.cc b/deps/v8/test/cctest/test-log.cc index dfbc733e0d..72e663c462 100644 --- a/deps/v8/test/cctest/test-log.cc +++ b/deps/v8/test/cctest/test-log.cc @@ -25,6 +25,7 @@ using v8::internal::StrLength; namespace { + class ScopedLoggerInitializer { public: explicit ScopedLoggerInitializer(bool prof_lazy) @@ -470,8 +471,9 @@ TEST(IsLoggingPreserved) { typedef i::NativesCollection<i::TEST> TestSources; -// Test that logging of code create / move / delete events -// is equivalent to traversal of a resulting heap. + +// Test that logging of code create / move events is equivalent to traversal of +// a resulting heap. TEST(EquivalenceOfLoggingAndTraversal) { // This test needs to be run on a "clean" V8 to ensure that snapshot log // is loaded. This is always true when running using tools/test.py because diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc index 160c9b11be..f5aed96d7d 100755 --- a/deps/v8/test/cctest/test-parsing.cc +++ b/deps/v8/test/cctest/test-parsing.cc @@ -345,7 +345,7 @@ TEST(PreParseOverflow) { reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); size_t kProgramSize = 1024 * 1024; - i::SmartPointer<char> program( + i::SmartArrayPointer<char> program( reinterpret_cast<char*>(malloc(kProgramSize + 1))); memset(*program, '(', kProgramSize); program[kProgramSize] = '\0'; @@ -398,7 +398,7 @@ void TestCharacterStream(const char* ascii_source, if (end == 0) end = length; unsigned sub_length = end - start; i::HandleScope test_scope; - i::SmartPointer<i::uc16> uc16_buffer(new i::uc16[length]); + i::SmartArrayPointer<i::uc16> uc16_buffer(new i::uc16[length]); for (unsigned i = 0; i < length; i++) { uc16_buffer[i] = static_cast<i::uc16>(ascii_source[i]); } diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc index 4a29e59c56..76fd244e97 100644 --- a/deps/v8/test/cctest/test-profile-generator.cc +++ b/deps/v8/test/cctest/test-profile-generator.cc @@ -549,13 +549,14 @@ TEST(CodeMapMoveAndDeleteCode) { code_map.AddCode(ToAddress(0x1700), &entry2, 0x100); CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500))); CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700))); - code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1800)); + code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1700)); // Deprecate bbb. CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500))); - CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700))); - CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1800))); - code_map.DeleteCode(ToAddress(0x1700)); + CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1700))); + CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0, + TokenEnumerator::kNoSecurityToken); + code_map.AddCode(ToAddress(0x1750), &entry3, 0x100); CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700))); - CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1800))); + CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1750))); } diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc index 46ac88cd92..89a911274b 100644 --- a/deps/v8/test/cctest/test-regexp.cc +++ b/deps/v8/test/cctest/test-regexp.cc @@ -79,7 +79,7 @@ static bool CheckParse(const char* input) { } -static SmartPointer<const char> Parse(const char* input) { +static SmartArrayPointer<const char> Parse(const char* input) { V8::Initialize(NULL); v8::HandleScope scope; ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); @@ -88,7 +88,7 @@ static SmartPointer<const char> Parse(const char* input) { CHECK(v8::internal::RegExpParser::ParseRegExp(&reader, false, &result)); CHECK(result.tree != NULL); CHECK(result.error.is_null()); - SmartPointer<const char> output = result.tree->ToString(); + SmartArrayPointer<const char> output = result.tree->ToString(); return output; } @@ -391,7 +391,7 @@ static void ExpectError(const char* input, CHECK(!v8::internal::RegExpParser::ParseRegExp(&reader, false, &result)); CHECK(result.tree == NULL); CHECK(!result.error.is_null()); - SmartPointer<char> str = result.error->ToCString(ALLOW_NULLS); + SmartArrayPointer<char> str = result.error->ToCString(ALLOW_NULLS); CHECK_EQ(expected, *str); } @@ -423,7 +423,7 @@ TEST(Errors) { for (int i = 0; i <= kMaxCaptures; i++) { accumulator.Add("()"); } - SmartPointer<const char> many_captures(accumulator.ToCString()); + SmartArrayPointer<const char> many_captures(accumulator.ToCString()); ExpectError(*many_captures, kTooManyCaptures); } diff --git a/deps/v8/test/cctest/test-reloc-info.cc b/deps/v8/test/cctest/test-reloc-info.cc index 0378fb3413..5bdc4c3e6a 100644 --- a/deps/v8/test/cctest/test-reloc-info.cc +++ b/deps/v8/test/cctest/test-reloc-info.cc @@ -45,7 +45,7 @@ TEST(Positions) { const int code_size = 10 * KB; int relocation_info_size = 10 * KB; const int buffer_size = code_size + relocation_info_size; - SmartPointer<byte> buffer(new byte[buffer_size]); + SmartArrayPointer<byte> buffer(new byte[buffer_size]); byte* pc = *buffer; byte* buffer_end = *buffer + buffer_size; diff --git a/deps/v8/test/cctest/test-threads.cc b/deps/v8/test/cctest/test-threads.cc index 59d27ab7c0..985b9e5b99 100644 --- a/deps/v8/test/cctest/test-threads.cc +++ b/deps/v8/test/cctest/test-threads.cc @@ -161,6 +161,7 @@ class ThreadIdValidationThread : public v8::internal::Thread { } semaphore_->Signal(); } + private: i::List<i::ThreadId>* refs_; int thread_no_; diff --git a/deps/v8/test/mjsunit/debug-scopes.js b/deps/v8/test/mjsunit/debug-scopes.js index 40adf5b2d2..1c23b0bf99 100644 --- a/deps/v8/test/mjsunit/debug-scopes.js +++ b/deps/v8/test/mjsunit/debug-scopes.js @@ -418,6 +418,27 @@ with_5(); EndTest(); +// Nested with blocks using existing object in global code. +BeginTest("With 6"); +listener_delegate = function(exec_state) { + CheckScopeChain([debug.ScopeType.With, + debug.ScopeType.With, + debug.ScopeType.Global], exec_state); + CheckScopeContent(with_object, 0, exec_state); + CheckScopeContent(with_object, 1, exec_state); + assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject()); + assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value()); +}; + +var with_object = {c:3,d:4}; +with(with_object) { + with(with_object) { + debugger; + } +} +EndTest(); + + // Simple closure formed by returning an inner function referering the outer // functions arguments. BeginTest("Closure 1"); @@ -771,6 +792,23 @@ closure_in_with_3(); EndTest(); +BeginTest("Closure inside With 4"); +listener_delegate = function(exec_state) { + CheckScopeChain([debug.ScopeType.Local, + debug.ScopeType.With, + debug.ScopeType.Global], exec_state); + CheckScopeContent({x: 2}, 0, exec_state); + CheckScopeContent({x: 1}, 1, exec_state); +}; + +with({x:1}) { + (function(x) { + debugger; + })(2); +} +EndTest(); + + // Test global scope. BeginTest("Global"); listener_delegate = function(exec_state) { @@ -875,6 +913,43 @@ catch_block_4(); EndTest(); +// Test catch in global scope. +BeginTest("Catch block 5"); +listener_delegate = function(exec_state) { + CheckScopeChain([debug.ScopeType.Catch, + debug.ScopeType.Global], exec_state); + CheckScopeContent({e:'Exception'}, 0, exec_state); +}; + +try { + throw 'Exception'; +} catch (e) { + debugger; +} + +EndTest(); + + +// Closure inside catch in global code. +BeginTest("Catch block 6"); +listener_delegate = function(exec_state) { + CheckScopeChain([debug.ScopeType.Local, + debug.ScopeType.Catch, + debug.ScopeType.Global], exec_state); + CheckScopeContent({x: 2}, 0, exec_state); + CheckScopeContent({e:'Exception'}, 1, exec_state); +}; + +try { + throw 'Exception'; +} catch (e) { + (function(x) { + debugger; + })(2); +} +EndTest(); + + assertEquals(begin_test_count, break_count, 'one or more tests did not enter the debugger'); assertEquals(begin_test_count, end_test_count, diff --git a/deps/v8/test/mjsunit/debug-step-2.js b/deps/v8/test/mjsunit/debug-step-2.js new file mode 100644 index 0000000000..502b426ee2 --- /dev/null +++ b/deps/v8/test/mjsunit/debug-step-2.js @@ -0,0 +1,89 @@ +// Copyright 2011 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --expose-debug-as debug + +// This test tests that full code compiled without debug break slots +// is recompiled with debug break slots when debugging is started. + +// Get the Debug object exposed from the debug context global object. +Debug = debug.Debug + +var bp; +var done = false; +var step_count = 0; + +// Debug event listener which steps until the global variable done is true. +function listener(event, exec_state, event_data, data) { + if (event == Debug.DebugEvent.Break) { + if (!done) exec_state.prepareStep(Debug.StepAction.StepNext); + step_count++; + } +}; + +// Set the global variables state to prpare the stepping test. +function prepare_step_test() { + done = false; + step_count = 0; +} + +// Test function to step through. +function f() { + var i = 1; + var j = 2; + done = true; +}; + +prepare_step_test(); +f(); + +// Add the debug event listener. +Debug.setListener(listener); + +bp = Debug.setBreakPoint(f, 1); + +prepare_step_test(); +f(); +assertEquals(4, step_count); +Debug.clearBreakPoint(bp); + +// Set a breakpoint on the first var statement (line 1). +bp = Debug.setBreakPoint(f, 1); + +// Step through the function ensuring that the var statements are hit as well. +prepare_step_test(); +f(); +assertEquals(4, step_count); + +// Clear the breakpoint and check that no stepping happens. +Debug.clearBreakPoint(bp); +prepare_step_test(); +f(); +assertEquals(0, step_count); + +// Get rid of the debug event listener. +Debug.setListener(null); diff --git a/deps/v8/test/mjsunit/external-array.js b/deps/v8/test/mjsunit/external-array.js index d7e9de0291..81c6cfe8b4 100644 --- a/deps/v8/test/mjsunit/external-array.js +++ b/deps/v8/test/mjsunit/external-array.js @@ -81,6 +81,19 @@ assertEquals(2.5, get(array, 0)); assertEquals(3.5, get(array, 1)); } +// Test non-number parameters. +var array_with_length_from_non_number = new Int32Array("2"); +assertEquals(2, array_with_length_from_non_number.length); +array_with_length_from_non_number = new Int32Array(undefined); +assertEquals(0, array_with_length_from_non_number.length); +var foo = { valueOf: function() { return 3; } }; +array_with_length_from_non_number = new Int32Array(foo); +assertEquals(3, array_with_length_from_non_number.length); +foo = { toString: function() { return "4"; } }; +array_with_length_from_non_number = new Int32Array(foo); +assertEquals(4, array_with_length_from_non_number.length); + + // Test loads and stores. types = [Array, Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, PixelArray, Float32Array, Float64Array]; diff --git a/deps/v8/test/mjsunit/fuzz-natives.js b/deps/v8/test/mjsunit/fuzz-natives.js index f8f0a28e70..ff6677e6ad 100644 --- a/deps/v8/test/mjsunit/fuzz-natives.js +++ b/deps/v8/test/mjsunit/fuzz-natives.js @@ -163,6 +163,9 @@ var knownProblems = { "PromoteScheduledException": true, "DeleteHandleScopeExtensions": true, + // Requires integer arguments to be non-negative. + "Apply": true, + // That can only be invoked on Array.prototype. "FinishArrayPrototypeSetup": true, diff --git a/deps/v8/test/mjsunit/harmony/proxies.js b/deps/v8/test/mjsunit/harmony/proxies.js index 640033d9cc..3c4e5f61c5 100644 --- a/deps/v8/test/mjsunit/harmony/proxies.js +++ b/deps/v8/test/mjsunit/harmony/proxies.js @@ -1,5 +1,3 @@ -// Flags: --harmony-proxies - // Copyright 2008 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -27,16 +25,39 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Flags: --harmony-proxies + -// TODO(rossberg): test exception cases. +// TODO(rossberg): for-in for proxies not implemented. +// TODO(rossberg): inheritance from proxies not implemented. +// TODO(rossberg): function proxies as constructors not implemented. + + +// Helper. + +function TestWithProxies(test, handler) { + test(handler, Proxy.create) + test(handler, function(h) {return Proxy.createFunction(h, function() {})}) +} // Getters. function TestGet(handler) { - var o = Proxy.create(handler) - assertEquals(42, o.a) - assertEquals(42, o["b"]) + TestWithProxies(TestGet2, handler) +} + +function TestGet2(handler, create) { + var p = create(handler) + assertEquals(42, p.a) + assertEquals(42, p["b"]) + + // TODO(rossberg): inheritance from proxies not yet implemented. + // var o = Object.create(p, {x: {value: 88}}) + // assertEquals(42, o.a) + // assertEquals(42, o["b"]) + // assertEquals(88, o.x) + // assertEquals(88, o["x"]) } TestGet({ @@ -76,7 +97,11 @@ TestGet(Proxy.create({ function TestGetCall(handler) { - var p = Proxy.create(handler) + TestWithProxies(TestGetCall2, handler) +} + +function TestGetCall2(handler, create) { + var p = create(handler) assertEquals(55, p.f()) assertEquals(55, p.f("unused", "arguments")) assertEquals(55, p.f.call(p)) @@ -139,17 +164,72 @@ TestGetCall(Proxy.create({ })) +function TestGetThrow(handler) { + TestWithProxies(TestGetThrow2, handler) +} + +function TestGetThrow2(handler, create) { + var p = create(handler) + assertThrows(function(){ p.a }, "myexn") + assertThrows(function(){ p["b"] }, "myexn") +} + +TestGetThrow({ + get: function(r, k) { throw "myexn" } +}) + +TestGetThrow({ + get: function(r, k) { return this.get2(r, k) }, + get2: function(r, k) { throw "myexn" } +}) + +TestGetThrow({ + getPropertyDescriptor: function(k) { throw "myexn" } +}) + +TestGetThrow({ + getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) }, + getPropertyDescriptor2: function(k) { throw "myexn" } +}) + +TestGetThrow({ + getPropertyDescriptor: function(k) { + return {get value() { throw "myexn" }} + } +}) + +TestGetThrow({ + get: undefined, + getPropertyDescriptor: function(k) { throw "myexn" } +}) + +TestGetThrow(Proxy.create({ + get: function(pr, pk) { throw "myexn" } +})) + +TestGetThrow(Proxy.create({ + get: function(pr, pk) { + return function(r, k) { throw "myexn" } + } +})) + + // Setters. var key var val -function TestSet(handler) { - var o = Proxy.create(handler) - assertEquals(42, o.a = 42) + +function TestSet(handler, create) { + TestWithProxies(TestSet2, handler) +} + +function TestSet2(handler, create) { + var p = create(handler) + assertEquals(42, p.a = 42) assertEquals("a", key) assertEquals(42, val) - assertEquals(43, o["b"] = 43) + assertEquals(43, p["b"] = 43) assertEquals("b", key) assertEquals(43, val) } @@ -225,31 +305,156 @@ TestSet(Proxy.create({ +function TestSetThrow(handler, create) { + TestWithProxies(TestSetThrow2, handler) +} + +function TestSetThrow2(handler, create) { + var p = create(handler) + assertThrows(function(){ p.a = 42 }, "myexn") + assertThrows(function(){ p["b"] = 42 }, "myexn") +} + +TestSetThrow({ + set: function(r, k, v) { throw "myexn" } +}) + +TestSetThrow({ + set: function(r, k, v) { return this.set2(r, k, v) }, + set2: function(r, k, v) { throw "myexn" } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { throw "myexn" }, + defineProperty: function(k, desc) { key = k; val = desc.value } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { return {writable: true} }, + defineProperty: function(k, desc) { throw "myexn" } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { + return this.getOwnPropertyDescriptor2(k) + }, + getOwnPropertyDescriptor2: function(k) { throw "myexn" }, + defineProperty: function(k, desc) { this.defineProperty2(k, desc) }, + defineProperty2: function(k, desc) { key = k; val = desc.value } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { + return this.getOwnPropertyDescriptor2(k) + }, + getOwnPropertyDescriptor2: function(k) { return {writable: true} }, + defineProperty: function(k, desc) { this.defineProperty2(k, desc) }, + defineProperty2: function(k, desc) { throw "myexn" } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { throw "myexn" }, + defineProperty: function(k, desc) { key = k; val = desc.value } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { + return {get writable() { return true }} + }, + defineProperty: function(k, desc) { throw "myexn" } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { throw "myexn" } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { + return {set: function(v) { throw "myexn" }} + } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { throw "myexn" }, + getPropertyDescriptor: function(k) { return {writable: true} }, + defineProperty: function(k, desc) { key = k; val = desc.value } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { return null }, + getPropertyDescriptor: function(k) { throw "myexn" }, + defineProperty: function(k, desc) { key = k; val = desc.value } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { return null }, + getPropertyDescriptor: function(k) { return {writable: true} }, + defineProperty: function(k, desc) { throw "myexn" } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { return null }, + getPropertyDescriptor: function(k) { + return {get writable() { throw "myexn" }} + }, + defineProperty: function(k, desc) { key = k; val = desc.value } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { return null }, + getPropertyDescriptor: function(k) { + return {set: function(v) { throw "myexn" }} + } +}) + +TestSetThrow({ + getOwnPropertyDescriptor: function(k) { return null }, + getPropertyDescriptor: function(k) { return null }, + defineProperty: function(k, desc) { throw "myexn" } +}) + +TestSetThrow(Proxy.create({ + get: function(pr, pk) { throw "myexn" } +})) + +TestSetThrow(Proxy.create({ + get: function(pr, pk) { + return function(r, k, v) { throw "myexn" } + } +})) + + + // Property definition (Object.defineProperty and Object.defineProperties). var key var desc + function TestDefine(handler) { - var o = Proxy.create(handler) - assertEquals(o, Object.defineProperty(o, "a", {value: 44})) + TestWithProxies(TestDefine2, handler) +} + +function TestDefine2(handler, create) { + var p = create(handler) + assertEquals(p, Object.defineProperty(p, "a", {value: 44})) assertEquals("a", key) assertEquals(1, Object.getOwnPropertyNames(desc).length) assertEquals(44, desc.value) - assertEquals(o, Object.defineProperty(o, "b", {value: 45, writable: false})) + assertEquals(p, Object.defineProperty(p, "b", {value: 45, writable: false})) assertEquals("b", key) assertEquals(2, Object.getOwnPropertyNames(desc).length) assertEquals(45, desc.value) assertEquals(false, desc.writable) - assertEquals(o, Object.defineProperty(o, "c", {value: 46, enumerable: false})) + assertEquals(p, Object.defineProperty(p, "c", {value: 46, enumerable: false})) assertEquals("c", key) assertEquals(2, Object.getOwnPropertyNames(desc).length) assertEquals(46, desc.value) assertEquals(false, desc.enumerable) var attributes = {configurable: true, mine: 66, minetoo: 23} - assertEquals(o, Object.defineProperty(o, "d", attributes)) + assertEquals(p, Object.defineProperty(p, "d", attributes)) assertEquals("d", key) // Modifying the attributes object after the fact should have no effect. attributes.configurable = false @@ -260,23 +465,23 @@ function TestDefine(handler) { assertEquals(66, desc.mine) assertEquals(23, desc.minetoo) - assertEquals(o, Object.defineProperty(o, "e", {get: function(){ return 5 }})) + assertEquals(p, Object.defineProperty(p, "e", {get: function(){ return 5 }})) assertEquals("e", key) assertEquals(1, Object.getOwnPropertyNames(desc).length) assertEquals(5, desc.get()) - assertEquals(o, Object.defineProperty(o, "zzz", {})) + assertEquals(p, Object.defineProperty(p, "zzz", {})) assertEquals("zzz", key) assertEquals(0, Object.getOwnPropertyNames(desc).length) -// TODO(rossberg): This test requires [s in proxy] to be implemented first. -// var d = Proxy.create({ +// TODO(rossberg): This test requires for-in on proxies. +// var d = create({ // get: function(r, k) { return (k === "value") ? 77 : void 0 }, // getOwnPropertyNames: function() { return ["value"] } // }) // assertEquals(1, Object.getOwnPropertyNames(d).length) // assertEquals(77, d.value) -// assertEquals(o, Object.defineProperty(o, "p", d)) +// assertEquals(p, Object.defineProperty(p, "p", d)) // assertEquals("p", key) // assertEquals(1, Object.getOwnPropertyNames(desc).length) // assertEquals(77, desc.value) @@ -288,12 +493,15 @@ function TestDefine(handler) { last: {value: 21, configurable: true, mine: "eyes"} } Object.defineProperty(props, "hidden", {value: "hidden", enumerable: false}) - assertEquals(o, Object.defineProperties(o, props)) + assertEquals(p, Object.defineProperties(p, props)) assertEquals("last", key) assertEquals(2, Object.getOwnPropertyNames(desc).length) assertEquals(21, desc.value) assertEquals(true, desc.configurable) assertEquals(undefined, desc.mine) // Arguably a bug in the spec... + + var props = {bla: {get value() { throw "myexn" }}} + assertThrows(function(){ Object.defineProperties(p, props) }, "myexn") } TestDefine({ @@ -312,42 +520,91 @@ TestDefine(Proxy.create({ })) +function TestDefineThrow(handler) { + TestWithProxies(TestDefineThrow2, handler) +} + +function TestDefineThrow2(handler, create) { + var p = create(handler) + assertThrows(function(){ Object.defineProperty(p, "a", {value: 44})}, "myexn") + +// TODO(rossberg): These tests require for-in on proxies. +// var d1 = create({ +// get: function(r, k) { throw "myexn" }, +// getOwnPropertyNames: function() { return ["value"] } +// }) +// assertThrows(function(){ Object.defineProperty(p, "p", d1) }, "myexn") +// var d2 = create({ +// get: function(r, k) { return 77 }, +// getOwnPropertyNames: function() { throw "myexn" } +// }) +// assertThrows(function(){ Object.defineProperty(p, "p", d2) }, "myexn") + + var props = {bla: {get value() { throw "otherexn" }}} + assertThrows(function(){ Object.defineProperties(p, props) }, "otherexn") +} + +TestDefineThrow({ + defineProperty: function(k, d) { throw "myexn" } +}) + +TestDefineThrow({ + defineProperty: function(k, d) { return this.defineProperty2(k, d) }, + defineProperty2: function(k, d) { throw "myexn" } +}) + +TestDefineThrow(Proxy.create({ + get: function(pr, pk) { throw "myexn" } +})) + +TestDefineThrow(Proxy.create({ + get: function(pr, pk) { + return function(k, d) { throw "myexn" } + } +})) + + // Property deletion (delete). var key + function TestDelete(handler) { - var o = Proxy.create(handler) - assertEquals(true, delete o.a) + TestWithProxies(TestDelete2, handler) +} + +function TestDelete2(handler, create) { + var p = create(handler) + assertEquals(true, delete p.a) assertEquals("a", key) - assertEquals(true, delete o["b"]) + assertEquals(true, delete p["b"]) assertEquals("b", key) - assertEquals(false, delete o.z1) + assertEquals(false, delete p.z1) assertEquals("z1", key) - assertEquals(false, delete o["z2"]) + assertEquals(false, delete p["z2"]) assertEquals("z2", key); (function() { "use strict" - assertEquals(true, delete o.c) + assertEquals(true, delete p.c) assertEquals("c", key) - assertEquals(true, delete o["d"]) + assertEquals(true, delete p["d"]) assertEquals("d", key) - assertThrows(function() { delete o.z3 }, TypeError) + assertThrows(function(){ delete p.z3 }, TypeError) assertEquals("z3", key) - assertThrows(function() { delete o["z4"] }, TypeError) + assertThrows(function(){ delete p["z4"] }, TypeError) assertEquals("z4", key) })() } TestDelete({ - 'delete': function(k) { key = k; return k < "z" } + delete: function(k) { key = k; return k < "z" } }) TestDelete({ - 'delete': function(k) { return this.delete2(k) }, + delete: function(k) { return this.delete2(k) }, delete2: function(k) { key = k; return k < "z" } }) @@ -358,11 +615,51 @@ TestDelete(Proxy.create({ })) +function TestDeleteThrow(handler) { + TestWithProxies(TestDeleteThrow2, handler) +} + +function TestDeleteThrow2(handler, create) { + var p = create(handler) + assertThrows(function(){ delete p.a }, "myexn") + assertThrows(function(){ delete p["b"] }, "myexn"); + + (function() { + "use strict" + assertThrows(function(){ delete p.c }, "myexn") + assertThrows(function(){ delete p["d"] }, "myexn") + })() +} + +TestDeleteThrow({ + delete: function(k) { throw "myexn" } +}) + +TestDeleteThrow({ + delete: function(k) { return this.delete2(k) }, + delete2: function(k) { throw "myexn" } +}) + +TestDeleteThrow(Proxy.create({ + get: function(pr, pk) { throw "myexn" } +})) + +TestDeleteThrow(Proxy.create({ + get: function(pr, pk) { + return function(k) { throw "myexn" } + } +})) + + // Property descriptors (Object.getOwnPropertyDescriptor). function TestDescriptor(handler) { - var o = Proxy.create(handler) + TestWithProxies(TestDescriptor2, handler) +} + +function TestDescriptor2(handler, create) { + var p = create(handler) var descs = [ {configurable: true}, {value: 34, enumerable: true, configurable: true}, @@ -371,18 +668,17 @@ function TestDescriptor(handler) { {get: function() { "get" }, set: function() { "set" }, configurable: true} ] for (var i = 0; i < descs.length; ++i) { - assertEquals(o, Object.defineProperty(o, i, descs[i])) - var desc = Object.getOwnPropertyDescriptor(o, i) - for (p in descs[i]) { + assertEquals(p, Object.defineProperty(p, i, descs[i])) + var desc = Object.getOwnPropertyDescriptor(p, i) + for (prop in descs[i]) { // TODO(rossberg): Ignore user attributes as long as the spec isn't // fixed suitably. - if (p != "mine") assertEquals(descs[i][p], desc[p]) + if (prop != "mine") assertEquals(descs[i][prop], desc[prop]) } - assertEquals(undefined, Object.getOwnPropertyDescriptor(o, "absent")) + assertEquals(undefined, Object.getOwnPropertyDescriptor(p, "absent")) } } - TestDescriptor({ defineProperty: function(k, d) { this["__" + k] = d; return true }, getOwnPropertyDescriptor: function(k) { return this["__" + k] } @@ -397,18 +693,43 @@ TestDescriptor({ }) +function TestDescriptorThrow(handler) { + TestWithProxies(TestDescriptorThrow2, handler) +} + +function TestDescriptorThrow2(handler, create) { + var p = create(handler) + assertThrows(function(){ Object.getOwnPropertyDescriptor(p, "a") }, "myexn") +} + +TestDescriptorThrow({ + getOwnPropertyDescriptor: function(k) { throw "myexn" } +}) + +TestDescriptorThrow({ + getOwnPropertyDescriptor: function(k) { + return this.getOwnPropertyDescriptor2(k) + }, + getOwnPropertyDescriptor2: function(k) { throw "myexn" } +}) + + // Comparison. function TestComparison(eq) { - var o1 = Proxy.create({}) - var o2 = Proxy.create({}) - - assertTrue(eq(o1, o1)) - assertTrue(eq(o2, o2)) - assertTrue(!eq(o1, o2)) - assertTrue(!eq(o1, {})) - assertTrue(!eq({}, o2)) + TestWithProxies(TestComparison2, eq) +} + +function TestComparison2(eq, create) { + var p1 = create({}) + var p2 = create({}) + + assertTrue(eq(p1, p1)) + assertTrue(eq(p2, p2)) + assertTrue(!eq(p1, p2)) + assertTrue(!eq(p1, {})) + assertTrue(!eq({}, p2)) assertTrue(!eq({}, {})) } @@ -419,45 +740,61 @@ TestComparison(function(o1, o2) { return !(o1 !== o2) }) -// Type. +// Type (typeof). -assertEquals("object", typeof Proxy.create({})) -assertTrue(typeof Proxy.create({}) == "object") -assertTrue("object" == typeof Proxy.create({})) +function TestTypeof() { + assertEquals("object", typeof Proxy.create({})) + assertTrue(typeof Proxy.create({}) == "object") + assertTrue("object" == typeof Proxy.create({})) -// No function proxies yet. + assertEquals("function", typeof Proxy.createFunction({}, function() {})) + assertTrue(typeof Proxy.createFunction({}, function() {}) == "function") + assertTrue("function" == typeof Proxy.createFunction({}, function() {})) +} + +TestTypeof() // Membership test (in). var key + function TestIn(handler) { - var o = Proxy.create(handler) - assertTrue("a" in o) + TestWithProxies(TestIn2, handler) +} + +function TestIn2(handler, create) { + var p = create(handler) + assertTrue("a" in p) assertEquals("a", key) - assertTrue(99 in o) + assertTrue(99 in p) assertEquals("99", key) - assertFalse("z" in o) + assertFalse("z" in p) assertEquals("z", key) - if ("b" in o) { + assertEquals(2, ("a" in p) ? 2 : 0) + assertEquals(0, !("a" in p) ? 2 : 0) + assertEquals(0, ("zzz" in p) ? 2 : 0) + assertEquals(2, !("zzz" in p) ? 2 : 0) + + if ("b" in p) { } else { assertTrue(false) } assertEquals("b", key) - if ("zz" in o) { + if ("zz" in p) { assertTrue(false) } assertEquals("zz", key) - if (!("c" in o)) { + if (!("c" in p)) { assertTrue(false) } assertEquals("c", key) - if (!("zzz" in o)) { + if (!("zzz" in p)) { } else { assertTrue(false) } @@ -506,17 +843,70 @@ TestIn(Proxy.create({ })) +function TestInThrow(handler) { + TestWithProxies(TestInThrow2, handler) +} + +function TestInThrow2(handler, create) { + var p = create(handler) + assertThrows(function(){ return "a" in o }, "myexn") + assertThrows(function(){ return !("a" in o) }, "myexn") + assertThrows(function(){ return ("a" in o) ? 2 : 3 }, "myexn") + assertThrows(function(){ if ("b" in o) {} }, "myexn") + assertThrows(function(){ if (!("b" in o)) {} }, "myexn") + assertThrows(function(){ if ("zzz" in o) {} }, "myexn") +} + +TestInThrow({ + has: function(k) { throw "myexn" } +}) + +TestInThrow({ + has: function(k) { return this.has2(k) }, + has2: function(k) { throw "myexn" } +}) + +TestInThrow({ + getPropertyDescriptor: function(k) { throw "myexn" } +}) + +TestInThrow({ + getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) }, + getPropertyDescriptor2: function(k) { throw "myexn" } +}) + +TestInThrow({ + get: undefined, + getPropertyDescriptor: function(k) { throw "myexn" } +}) + +TestInThrow(Proxy.create({ + get: function(pr, pk) { throw "myexn" } +})) + +TestInThrow(Proxy.create({ + get: function(pr, pk) { + return function(k) { throw "myexn" } + } +})) + + // Own Properties (Object.prototype.hasOwnProperty). var key + function TestHasOwn(handler) { - var o = Proxy.create(handler) - assertTrue(Object.prototype.hasOwnProperty.call(o, "a")) + TestWithProxies(TestHasOwn2, handler) +} + +function TestHasOwn2(handler, create) { + var p = create(handler) + assertTrue(Object.prototype.hasOwnProperty.call(p, "a")) assertEquals("a", key) - assertTrue(Object.prototype.hasOwnProperty.call(o, 99)) + assertTrue(Object.prototype.hasOwnProperty.call(p, 99)) assertEquals("99", key) - assertFalse(Object.prototype.hasOwnProperty.call(o, "z")) + assertFalse(Object.prototype.hasOwnProperty.call(p, "z")) assertEquals("z", key) } @@ -564,6 +954,54 @@ TestHasOwn(Proxy.create({ })) +function TestHasOwnThrow(handler) { + TestWithProxies(TestHasOwnThrow2, handler) +} + +function TestHasOwnThrow2(handler, create) { + var p = create(handler) + assertThrows(function(){ Object.prototype.hasOwnProperty.call(p, "a")}, + "myexn") + assertThrows(function(){ Object.prototype.hasOwnProperty.call(p, 99)}, + "myexn") +} + +TestHasOwnThrow({ + hasOwn: function(k) { throw "myexn" } +}) + +TestHasOwnThrow({ + hasOwn: function(k) { return this.hasOwn2(k) }, + hasOwn2: function(k) { throw "myexn" } +}) + +TestHasOwnThrow({ + getOwnPropertyDescriptor: function(k) { throw "myexn" } +}) + +TestHasOwnThrow({ + getOwnPropertyDescriptor: function(k) { + return this.getOwnPropertyDescriptor2(k) + }, + getOwnPropertyDescriptor2: function(k) { throw "myexn" } +}) + +TestHasOwnThrow({ + hasOwn: undefined, + getOwnPropertyDescriptor: function(k) { throw "myexn" } +}) + +TestHasOwnThrow(Proxy.create({ + get: function(pr, pk) { throw "myexn" } +})) + +TestHasOwnThrow(Proxy.create({ + get: function(pr, pk) { + return function(k) { throw "myexn" } + } +})) + + // Instanceof (instanceof) @@ -573,29 +1011,32 @@ function TestInstanceof() { var p2 = Proxy.create({}, o) var p3 = Proxy.create({}, p2) - var f = function() {} - f.prototype = o + var f0 = function() {} + f0.prototype = o var f1 = function() {} f1.prototype = p1 var f2 = function() {} f2.prototype = p2 assertTrue(o instanceof Object) - assertFalse(o instanceof f) + assertFalse(o instanceof f0) assertFalse(o instanceof f1) assertFalse(o instanceof f2) assertFalse(p1 instanceof Object) - assertFalse(p1 instanceof f) + assertFalse(p1 instanceof f0) assertFalse(p1 instanceof f1) assertFalse(p1 instanceof f2) assertTrue(p2 instanceof Object) - assertTrue(p2 instanceof f) + assertTrue(p2 instanceof f0) assertFalse(p2 instanceof f1) assertFalse(p2 instanceof f2) assertTrue(p3 instanceof Object) - assertTrue(p3 instanceof f) + assertTrue(p3 instanceof f0) assertFalse(p3 instanceof f1) assertTrue(p3 instanceof f2) + + var f = Proxy.createFunction({}, function() {}) + assertTrue(f instanceof Function) } TestInstanceof() @@ -642,6 +1083,11 @@ function TestPrototype() { assertTrue(Object.prototype.isPrototypeOf.call(p2, p3)) assertFalse(Object.prototype.isPrototypeOf.call(p2, p4)) assertFalse(Object.prototype.isPrototypeOf.call(p3, p2)) + + var f = Proxy.createFunction({}, function() {}) + assertSame(Object.getPrototypeOf(f), Function.prototype) + assertTrue(Object.prototype.isPrototypeOf(f)) + assertTrue(Object.prototype.isPrototypeOf.call(Function.prototype, f)) } TestPrototype() @@ -651,8 +1097,12 @@ TestPrototype() // Property names (Object.getOwnPropertyNames, Object.keys). function TestPropertyNames(names, handler) { - var p = Proxy.create(handler) - assertArrayEquals(names, Object.getOwnPropertyNames(p)) + TestWithProxies(TestPropertyNames2, [names, handler]) +} + +function TestPropertyNames2(names_handler, create) { + var p = create(names_handler[1]) + assertArrayEquals(names_handler[0], Object.getOwnPropertyNames(p)) } TestPropertyNames([], { @@ -675,9 +1125,32 @@ TestPropertyNames(["[object Object]"], { }) +function TestPropertyNamesThrow(handler) { + TestWithProxies(TestPropertyNamesThrow2, handler) +} + +function TestPropertyNamesThrow2(handler, create) { + var p = create(handler) + assertThrows(function(){ Object.getOwnPropertyNames(p) }, "myexn") +} + +TestPropertyNamesThrow({ + getOwnPropertyNames: function() { throw "myexn" } +}) + +TestPropertyNamesThrow({ + getOwnPropertyNames: function() { return this.getOwnPropertyNames2() }, + getOwnPropertyNames2: function() { throw "myexn" } +}) + + function TestKeys(names, handler) { - var p = Proxy.create(handler) - assertArrayEquals(names, Object.keys(p)) + TestWithProxies(TestKeys2, [names, handler]) +} + +function TestKeys2(names_handler, create) { + var p = create(names_handler[1]) + assertArrayEquals(names_handler[0], Object.keys(p)) } TestKeys([], { @@ -730,10 +1203,71 @@ TestKeys([], { }) +function TestKeysThrow(handler) { + TestWithProxies(TestKeysThrow2, handler) +} + +function TestKeysThrow2(handler, create) { + var p = create(handler) + assertThrows(function(){ Object.keys(p) }, "myexn") +} + +TestKeysThrow({ + keys: function() { throw "myexn" } +}) + +TestKeysThrow({ + keys: function() { return this.keys2() }, + keys2: function() { throw "myexn" } +}) + +TestKeysThrow({ + getOwnPropertyNames: function() { throw "myexn" }, + getOwnPropertyDescriptor: function(k) { return true } +}) + +TestKeysThrow({ + getOwnPropertyNames: function() { return [1, 2] }, + getOwnPropertyDescriptor: function(k) { throw "myexn" } +}) + +TestKeysThrow({ + getOwnPropertyNames: function() { return this.getOwnPropertyNames2() }, + getOwnPropertyNames2: function() { throw "myexn" }, +}) + +TestKeysThrow({ + getOwnPropertyNames: function() { return this.getOwnPropertyNames2() }, + getOwnPropertyNames2: function() { return [1, 2] }, + getOwnPropertyDescriptor: function(k) { + return this.getOwnPropertyDescriptor2(k) + }, + getOwnPropertyDescriptor2: function(k) { throw "myexn" } +}) + +TestKeysThrow({ + get getOwnPropertyNames() { throw "myexn" } +}) + +TestKeysThrow({ + get getOwnPropertyNames() { + return function() { throw "myexn" } + }, +}) + +TestKeysThrow([], { + get getOwnPropertyNames() { + return function() { return [1, 2] } + }, + getOwnPropertyDescriptor: function(k) { throw "myexn" } +}) + + // Fixing (Object.freeze, Object.seal, Object.preventExtensions, // Object.isFrozen, Object.isSealed, Object.isExtensible) +// TODO(rossberg): use TestWithProxies to include funciton proxies function TestFix(names, handler) { var proto = {p: 77} var assertFixing = function(o, s, f, e) { @@ -742,44 +1276,44 @@ function TestFix(names, handler) { assertEquals(e, Object.isExtensible(o)) } - var o1 = Proxy.create(handler, proto) - assertFixing(o1, false, false, true) - Object.seal(o1) - assertFixing(o1, true, names.length === 0, false) - assertArrayEquals(names.sort(), Object.getOwnPropertyNames(o1).sort()) + var p1 = Proxy.create(handler, proto) + assertFixing(p1, false, false, true) + Object.seal(p1) + assertFixing(p1, true, names.length === 0, false) + assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p1).sort()) assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(), - Object.keys(o1).sort()) - assertEquals(proto, Object.getPrototypeOf(o1)) - assertEquals(77, o1.p) - for (var n in o1) { - var desc = Object.getOwnPropertyDescriptor(o1, n) + Object.keys(p1).sort()) + assertEquals(proto, Object.getPrototypeOf(p1)) + assertEquals(77, p1.p) + for (var n in p1) { + var desc = Object.getOwnPropertyDescriptor(p1, n) if (desc !== undefined) assertFalse(desc.configurable) } - var o2 = Proxy.create(handler, proto) - assertFixing(o2, false, false, true) - Object.freeze(o2) - assertFixing(o2, true, true, false) - assertArrayEquals(names.sort(), Object.getOwnPropertyNames(o2).sort()) + var p2 = Proxy.create(handler, proto) + assertFixing(p2, false, false, true) + Object.freeze(p2) + assertFixing(p2, true, true, false) + assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p2).sort()) assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(), - Object.keys(o2).sort()) - assertEquals(proto, Object.getPrototypeOf(o2)) - assertEquals(77, o2.p) - for (var n in o2) { - var desc = Object.getOwnPropertyDescriptor(o2, n) + Object.keys(p2).sort()) + assertEquals(proto, Object.getPrototypeOf(p2)) + assertEquals(77, p2.p) + for (var n in p2) { + var desc = Object.getOwnPropertyDescriptor(p2, n) if (desc !== undefined) assertFalse(desc.writable) if (desc !== undefined) assertFalse(desc.configurable) } - var o3 = Proxy.create(handler, proto) - assertFixing(o3, false, false, true) - Object.preventExtensions(o3) - assertFixing(o3, names.length === 0, names.length === 0, false) - assertArrayEquals(names.sort(), Object.getOwnPropertyNames(o3).sort()) + var p3 = Proxy.create(handler, proto) + assertFixing(p3, false, false, true) + Object.preventExtensions(p3) + assertFixing(p3, names.length === 0, names.length === 0, false) + assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p3).sort()) assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(), - Object.keys(o3).sort()) - assertEquals(proto, Object.getPrototypeOf(o3)) - assertEquals(77, o3.p) + Object.keys(p3).sort()) + assertEquals(proto, Object.getPrototypeOf(p3)) + assertEquals(77, p3.p) } TestFix([], { @@ -814,17 +1348,84 @@ TestFix(["b"], { }) +function TestFixFunction(fix) { + var f1 = Proxy.createFunction({ + fix: function() { return {} } + }, function() {}) + fix(f1) + assertEquals(0, f1.length) + + var f2 = Proxy.createFunction({ + fix: function() { return {length: {value: 3}} } + }, function() {}) + fix(f2) + assertEquals(3, f2.length) + + var f3 = Proxy.createFunction({ + fix: function() { return {length: {value: "huh"}} } + }, function() {}) + fix(f3) + assertEquals(0, f1.length) +} -// String conversion (Object.prototype.toString, Object.prototype.toLocaleString) +TestFixFunction(Object.seal) +TestFixFunction(Object.freeze) +TestFixFunction(Object.preventExtensions) + + +function TestFixThrow(handler) { + TestWithProxies(TestFixThrow2, handler) +} + +function TestFixThrow2(handler) { + var p = Proxy.create(handler, {}) + assertThrows(function(){ Object.seal(p) }, "myexn") + assertThrows(function(){ Object.freeze(p) }, "myexn") + assertThrows(function(){ Object.preventExtensions(p) }, "myexn") +} + +TestFixThrow({ + fix: function() { throw "myexn" } +}) + +TestFixThrow({ + fix: function() { return this.fix2() }, + fix2: function() { throw "myexn" } +}) + +TestFixThrow({ + get fix() { throw "myexn" } +}) + +TestFixThrow({ + get fix() { + return function() { throw "myexn" } + } +}) + + + +// String conversion (Object.prototype.toString, +// Object.prototype.toLocaleString, +// Function.prototype.toString) var key + function TestToString(handler) { - var o = Proxy.create(handler) + var p = Proxy.create(handler) key = "" - assertEquals("[object Object]", Object.prototype.toString.call(o)) + assertEquals("[object Object]", Object.prototype.toString.call(p)) assertEquals("", key) - assertEquals("my_proxy", Object.prototype.toLocaleString.call(o)) + assertEquals("my_proxy", Object.prototype.toLocaleString.call(p)) assertEquals("toString", key) + + var f = Proxy.createFunction(handler, function() {}) + key = "" + assertEquals("[object Function]", Object.prototype.toString.call(f)) + assertEquals("", key) + assertEquals("my_proxy", Object.prototype.toLocaleString.call(f)) + assertEquals("toString", key) + assertDoesNotThrow(function(){ Function.prototype.toString.call(f) }) } TestToString({ @@ -843,12 +1444,50 @@ TestToString(Proxy.create({ })) +function TestToStringThrow(handler) { + var p = Proxy.create(handler) + assertEquals("[object Object]", Object.prototype.toString.call(p)) + assertThrows(function(){ Object.prototype.toLocaleString.call(p) }, "myexn") + + var f = Proxy.createFunction(handler, function() {}) + assertEquals("[object Function]", Object.prototype.toString.call(f)) + assertThrows(function(){ Object.prototype.toLocaleString.call(f) }, "myexn") +} + +TestToStringThrow({ + get: function(r, k) { throw "myexn" } +}) + +TestToStringThrow({ + get: function(r, k) { return function() { throw "myexn" } } +}) + +TestToStringThrow({ + get: function(r, k) { return this.get2(r, k) }, + get2: function(r, k) { throw "myexn" } +}) + +TestToStringThrow(Proxy.create({ + get: function(pr, pk) { throw "myexn" } +})) + +TestToStringThrow(Proxy.create({ + get: function(pr, pk) { + return function(r, k) { throw "myexn" } + } +})) + + // Value conversion (Object.prototype.toValue) function TestValueOf(handler) { - var o = Proxy.create(handler) - assertSame(o, Object.prototype.valueOf.call(o)) + TestWithProxies(TestValueOf2, handler) +} + +function TestValueOf2(handler, create) { + var p = create(handler) + assertSame(p, Object.prototype.valueOf.call(p)) } TestValueOf({}) @@ -858,13 +1497,18 @@ TestValueOf({}) // Enumerability (Object.prototype.propertyIsEnumerable) var key + function TestIsEnumerable(handler) { - var o = Proxy.create(handler) - assertTrue(Object.prototype.propertyIsEnumerable.call(o, "a")) + TestWithProxies(TestIsEnumerable2, handler) +} + +function TestIsEnumerable2(handler, create) { + var p = create(handler) + assertTrue(Object.prototype.propertyIsEnumerable.call(p, "a")) assertEquals("a", key) - assertTrue(Object.prototype.propertyIsEnumerable.call(o, 2)) + assertTrue(Object.prototype.propertyIsEnumerable.call(p, 2)) assertEquals("2", key) - assertFalse(Object.prototype.propertyIsEnumerable.call(o, "z")) + assertFalse(Object.prototype.propertyIsEnumerable.call(p, "z")) assertEquals("z", key) } @@ -896,3 +1540,143 @@ TestIsEnumerable(Proxy.create({ } } })) + + +function TestIsEnumerableThrow(handler) { + TestWithProxies(TestIsEnumerableThrow2, handler) +} + +function TestIsEnumerableThrow2(handler, create) { + var p = create(handler) + assertThrows(function(){ Object.prototype.propertyIsEnumerable.call(p, "a") }, + "myexn") + assertThrows(function(){ Object.prototype.propertyIsEnumerable.call(p, 11) }, + "myexn") +} + +TestIsEnumerableThrow({ + getOwnPropertyDescriptor: function(k) { throw "myexn" } +}) + +TestIsEnumerableThrow({ + getOwnPropertyDescriptor: function(k) { + return this.getOwnPropertyDescriptor2(k) + }, + getOwnPropertyDescriptor2: function(k) { throw "myexn" } +}) + +TestIsEnumerableThrow({ + getOwnPropertyDescriptor: function(k) { + return {get enumerable() { throw "myexn" }, configurable: true} + }, +}) + +TestIsEnumerableThrow(Proxy.create({ + get: function(pr, pk) { throw "myexn" } +})) + +TestIsEnumerableThrow(Proxy.create({ + get: function(pr, pk) { + return function(k) { throw "myexn" } + } +})) + + + +// Calling (call, Function.prototype.call, Function.prototype.apply, +// Function.prototype.bind). + +var global = this +var receiver + +function TestCall(isStrict, callTrap) { + assertEquals(42, callTrap(5, 37)) +// TODO(rossberg): unrelated bug: this does not succeed for optimized code. +// assertEquals(isStrict ? undefined : global, receiver) + + var f = Proxy.createFunction({fix: function() { return {} }}, callTrap) + receiver = 333 + assertEquals(42, f(11, 31)) + assertEquals(isStrict ? undefined : global, receiver) + var o = {} + assertEquals(42, Function.prototype.call.call(f, o, 20, 22)) + assertEquals(o, receiver) + assertEquals(43, Function.prototype.call.call(f, null, 20, 23)) + assertEquals(isStrict ? null : global, receiver) + assertEquals(44, Function.prototype.call.call(f, 2, 21, 23)) + assertEquals(2, receiver.valueOf()) + receiver = 333 + assertEquals(32, Function.prototype.apply.call(f, o, [17, 15])) + assertEquals(o, receiver) + var ff = Function.prototype.bind.call(f, o, 12) + receiver = 333 + assertEquals(42, ff(30)) + assertEquals(o, receiver) + receiver = 333 + assertEquals(32, Function.prototype.apply.call(ff, {}, [20])) + assertEquals(o, receiver) + + Object.freeze(f) + receiver = 333 + assertEquals(42, f(11, 31)) +// TODO(rossberg): unrelated bug: this does not succeed for optimized code. +// assertEquals(isStrict ? undefined : global, receiver) + receiver = 333 + assertEquals(42, Function.prototype.call.call(f, o, 20, 22)) + assertEquals(o, receiver) + receiver = 333 + assertEquals(32, Function.prototype.apply.call(f, o, [17, 15])) + assertEquals(o, receiver) + receiver = 333 + assertEquals(42, ff(30)) + assertEquals(o, receiver) + receiver = 333 + assertEquals(32, Function.prototype.apply.call(ff, {}, [20])) + assertEquals(o, receiver) +} + +TestCall(false, function(x, y) { + receiver = this; return x + y +}) + +TestCall(true, function(x, y) { + "use strict"; + receiver = this; return x + y +}) + +TestCall(false, Proxy.createFunction({}, function(x, y) { + receiver = this; return x + y +})) + +TestCall(true, Proxy.createFunction({}, function(x, y) { + "use strict"; + receiver = this; return x + y +})) + +var p = Proxy.createFunction({fix: function() {return {}}}, function(x, y) { + receiver = this; return x + y +}) +TestCall(false, p) +Object.freeze(p) +TestCall(false, p) + + +function TestCallThrow(callTrap) { + var f = Proxy.createFunction({fix: function() {return {}}}, callTrap) + assertThrows(function(){ f(11) }, "myexn") + assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn") + assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn") + + Object.freeze(f) + assertThrows(function(){ f(11) }, "myexn") + assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn") + assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn") +} + +TestCallThrow(function() { throw "myexn" }) +TestCallThrow(Proxy.createFunction({}, function() { throw "myexn" })) + +var p = Proxy.createFunction( + {fix: function() {return {}}}, function() { throw "myexn" }) +Object.freeze(p) +TestCallThrow(p) diff --git a/deps/v8/test/mjsunit/harmony/weakmaps.js b/deps/v8/test/mjsunit/harmony/weakmaps.js index e43f9167e6..7b5dcaf0c1 100644 --- a/deps/v8/test/mjsunit/harmony/weakmaps.js +++ b/deps/v8/test/mjsunit/harmony/weakmaps.js @@ -137,7 +137,11 @@ assertTrue(WeakMap.prototype.set instanceof Function) assertTrue(WeakMap.prototype.get instanceof Function) assertTrue(WeakMap.prototype.has instanceof Function) assertTrue(WeakMap.prototype.delete instanceof Function) + + +// Regression test for WeakMap prototype. assertTrue(WeakMap.prototype.constructor === WeakMap) +assertTrue(Object.getPrototypeOf(WeakMap.prototype) === Object.prototype) // Regression test for issue 1617: The prototype of the WeakMap constructor diff --git a/deps/v8/test/mjsunit/regress/regress-1639.js b/deps/v8/test/mjsunit/regress/regress-1639.js new file mode 100644 index 0000000000..ed68c97df8 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-1639.js @@ -0,0 +1,85 @@ +// Copyright 2011 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --expose-debug-as debug +// Get the Debug object exposed from the debug context global object. +Debug = debug.Debug +var breaks = 0; + +function sendCommand(state, cmd) { + // Get the debug command processor in paused state. + var dcp = state.debugCommandProcessor(false); + var request = JSON.stringify(cmd); + var response = dcp.processDebugJSONRequest(request); +} + +function listener(event, exec_state, event_data, data) { + try { + if (event == Debug.DebugEvent.Break) { + var line = event_data.sourceLineText(); + print('break: ' + line); + + assertEquals(-1, line.indexOf('NOBREAK'), + "should not break on unexpected lines") + assertEquals('BREAK ' + breaks, line.substr(-7)); + breaks++; + sendCommand(exec_state, { + seq: 0, + type: "request", + command: "continue", + arguments: { stepaction: "next" } + }); + } + } catch (e) { + print(e); + } +} + +// Add the debug event listener. +Debug.setListener(listener); + +function a(f) { + if (f) { // NOBREAK: should not break here! + try { + f(); + } catch(e) { + } + } +} // BREAK 2 + +function b() { + c(); // BREAK 0 +} // BREAK 1 + +function c() { + a(); +} + +// Set a break point and call to invoke the debug event listener. +Debug.setBreakPoint(b, 0, 0); +a(b); +// BREAK 3 diff --git a/deps/v8/test/mjsunit/regress/regress-95920.js b/deps/v8/test/mjsunit/regress/regress-95920.js new file mode 100644 index 0000000000..20e73fbc40 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-95920.js @@ -0,0 +1,58 @@ +// Copyright 2011 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Tests that objects with external arrays cannot be sealed or have their +// properties redefined. + +(function() { + assertThrows(function() { + [0].every(function(){ Object.seal((new Int8Array(42))); }); + assertUnreable(); + }, TypeError) +})(); + +(function() { + assertThrows(function() { + [0].every(function(){ Object.freeze((new Int8Array(42))); }); + assertUnreable(); + }, TypeError) +})(); + +(function() { + assertThrows(function() { + [0].every(function(){ Object.preventExtensions((new Int8Array(42))); }); + assertUnreable(); + }, TypeError) +})(); + +(function() { + assertThrows(function() { + Object.defineProperty(new Int8Array(42), "1", + { writable: false, value: "1" }); + assertUnreable(); + }) +})(); diff --git a/deps/v8/test/mjsunit/regress/regress-96523.js b/deps/v8/test/mjsunit/regress/regress-96523.js new file mode 100644 index 0000000000..e611ce3660 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-96523.js @@ -0,0 +1,37 @@ +// Copyright 2011 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +with ({x:'outer'}) { + (function() { + var x = 'inner'; + try { + throw 'Exception'; + } catch (e) { + assertEquals('inner', x); + } + })() +} diff --git a/deps/v8/test/mjsunit/regress/regress-bind-receiver.js b/deps/v8/test/mjsunit/regress/regress-bind-receiver.js new file mode 100644 index 0000000000..fc83a4e5d9 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-bind-receiver.js @@ -0,0 +1,44 @@ +// Copyright 2011 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +function strict() { 'use strict'; return this; } +function lenient() { return this; } +var obj = {}; + +assertEquals(true, strict.bind(true)()); +assertEquals(42, strict.bind(42)()); +assertEquals("", strict.bind("")()); +assertEquals(null, strict.bind(null)()); +assertEquals(undefined, strict.bind(undefined)()); +assertEquals(obj, strict.bind(obj)()); + +assertEquals(true, lenient.bind(true)() instanceof Boolean); +assertEquals(true, lenient.bind(42)() instanceof Number); +assertEquals(true, lenient.bind("")() instanceof String); +assertEquals(this, lenient.bind(null)()); +assertEquals(this, lenient.bind(undefined)()); +assertEquals(obj, lenient.bind(obj)()); |