diff options
author | Ben Murdoch <benm@google.com> | 2011-08-04 19:25:22 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-08-04 19:25:22 +0100 |
commit | 6d7cb000ed533f52d745e60663019ff891bb19a8 (patch) | |
tree | 42903ccb2153c0a9dba45ed01c567940b2b6b3c6 /test | |
parent | 18a6f57610d404676fb0db2114fd7ad91e0402b0 (diff) | |
download | v8-6d7cb000ed533f52d745e60663019ff891bb19a8.tar.gz |
Merge V8 at r8836: Pick up V8 3.2.10.34
Bug: 5095592
Change-Id: I955924aac6e0bdba591798526c33c4d59fd3dc4f
Diffstat (limited to 'test')
-rw-r--r-- | test/cctest/test-alloc.cc | 13 | ||||
-rw-r--r-- | test/cctest/test-debug.cc | 1 | ||||
-rw-r--r-- | test/cctest/test-heap.cc | 8 | ||||
-rw-r--r-- | test/cctest/test-log.cc | 2 | ||||
-rwxr-xr-x | test/cctest/test-parsing.cc | 14 | ||||
-rw-r--r-- | test/cctest/test-serialize.cc | 8 | ||||
-rw-r--r-- | test/cctest/test-spaces.cc | 125 | ||||
-rw-r--r-- | test/mjsunit/compiler/regress-lbranch-double.js | 40 | ||||
-rw-r--r-- | test/mjsunit/regress/regress-91517.js | 112 |
9 files changed, 263 insertions, 60 deletions
diff --git a/test/cctest/test-alloc.cc b/test/cctest/test-alloc.cc index 0ccf4b8b..83ab1a9c 100644 --- a/test/cctest/test-alloc.cc +++ b/test/cctest/test-alloc.cc @@ -186,7 +186,9 @@ class Block { TEST(CodeRange) { const int code_range_size = 16*MB; OS::Setup(); - Isolate::Current()->code_range()->Setup(code_range_size); + Isolate::Current()->InitializeLoggingAndCounters(); + CodeRange* code_range = new CodeRange(Isolate::Current()); + code_range->Setup(code_range_size); int current_allocated = 0; int total_allocated = 0; List<Block> blocks(1000); @@ -198,8 +200,7 @@ TEST(CodeRange) { size_t requested = (Page::kPageSize << (Pseudorandom() % 6)) + Pseudorandom() % 5000 + 1; size_t allocated = 0; - void* base = Isolate::Current()->code_range()-> - AllocateRawMemory(requested, &allocated); + void* base = code_range->AllocateRawMemory(requested, &allocated); CHECK(base != NULL); blocks.Add(Block(base, static_cast<int>(allocated))); current_allocated += static_cast<int>(allocated); @@ -207,8 +208,7 @@ TEST(CodeRange) { } else { // Free a block. int index = Pseudorandom() % blocks.length(); - Isolate::Current()->code_range()->FreeRawMemory( - blocks[index].base, blocks[index].size); + code_range->FreeRawMemory(blocks[index].base, blocks[index].size); current_allocated -= blocks[index].size; if (index < blocks.length() - 1) { blocks[index] = blocks.RemoveLast(); @@ -218,5 +218,6 @@ TEST(CodeRange) { } } - Isolate::Current()->code_range()->TearDown(); + code_range->TearDown(); + delete code_range; } diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc index b81129e6..7f506dba 100644 --- a/test/cctest/test-debug.cc +++ b/test/cctest/test-debug.cc @@ -5819,6 +5819,7 @@ TEST(DebuggerDebugMessageDispatch) { TEST(DebuggerAgent) { + v8::V8::Initialize(); i::Debugger* debugger = i::Isolate::Current()->debugger(); // Make sure these ports is not used by other tests to allow tests to run in // parallel. diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc index 09aa613e..d25f39fa 100644 --- a/test/cctest/test-heap.cc +++ b/test/cctest/test-heap.cc @@ -291,8 +291,8 @@ TEST(LocalHandles) { TEST(GlobalHandles) { - GlobalHandles* global_handles = Isolate::Current()->global_handles(); InitializeVM(); + GlobalHandles* global_handles = Isolate::Current()->global_handles(); Handle<Object> h1; Handle<Object> h2; @@ -339,8 +339,8 @@ static void TestWeakGlobalHandleCallback(v8::Persistent<v8::Value> handle, TEST(WeakGlobalHandlesScavenge) { - GlobalHandles* global_handles = Isolate::Current()->global_handles(); InitializeVM(); + GlobalHandles* global_handles = Isolate::Current()->global_handles(); WeakPointerCleared = false; @@ -377,8 +377,8 @@ TEST(WeakGlobalHandlesScavenge) { TEST(WeakGlobalHandlesMark) { - GlobalHandles* global_handles = Isolate::Current()->global_handles(); InitializeVM(); + GlobalHandles* global_handles = Isolate::Current()->global_handles(); WeakPointerCleared = false; @@ -416,8 +416,8 @@ TEST(WeakGlobalHandlesMark) { } TEST(DeleteWeakGlobalHandle) { - GlobalHandles* global_handles = Isolate::Current()->global_handles(); InitializeVM(); + GlobalHandles* global_handles = Isolate::Current()->global_handles(); WeakPointerCleared = false; diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc index 17c73874..b43e0cdf 100644 --- a/test/cctest/test-log.cc +++ b/test/cctest/test-log.cc @@ -29,6 +29,7 @@ static void SetUp() { // Log to memory buffer. i::FLAG_logfile = "*"; i::FLAG_log = true; + ISOLATE->InitializeLoggingAndCounters(); LOGGER->Setup(); } @@ -120,6 +121,7 @@ TEST(MemoryLoggingTurnedOff) { // Log to stdout i::FLAG_logfile = "-"; i::FLAG_log = true; + ISOLATE->InitializeLoggingAndCounters(); LOGGER->Setup(); CHECK_EQ(0, LOGGER->GetLogLines(0, NULL, 0)); CHECK_EQ(0, LOGGER->GetLogLines(100, NULL, 0)); diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index 39856b67..2b06a5c1 100755 --- a/test/cctest/test-parsing.cc +++ b/test/cctest/test-parsing.cc @@ -134,6 +134,8 @@ TEST(KeywordMatcher) { TEST(ScanHTMLEndComments) { + v8::V8::Initialize(); + // Regression test. See: // http://code.google.com/p/chromium/issues/detail?id=53548 // Tests that --> is correctly interpreted as comment-to-end-of-line if there @@ -245,6 +247,8 @@ TEST(Preparsing) { TEST(StandAlonePreParser) { + v8::V8::Initialize(); + int marker; i::Isolate::Current()->stack_guard()->SetStackLimit( reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); @@ -281,6 +285,8 @@ TEST(StandAlonePreParser) { TEST(RegressChromium62639) { + v8::V8::Initialize(); + int marker; i::Isolate::Current()->stack_guard()->SetStackLimit( reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); @@ -302,6 +308,8 @@ TEST(RegressChromium62639) { TEST(Regress928) { + v8::V8::Initialize(); + // Preparsing didn't consider the catch clause of a try statement // as with-content, which made it assume that a function inside // the block could be lazily compiled, and an extra, unexpected, @@ -342,6 +350,8 @@ TEST(Regress928) { TEST(PreParseOverflow) { + v8::V8::Initialize(); + int marker; i::Isolate::Current()->stack_guard()->SetStackLimit( reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); @@ -592,6 +602,8 @@ void TestStreamScanner(i::UC16CharacterStream* stream, } TEST(StreamScanner) { + v8::V8::Initialize(); + const char* str1 = "{ foo get for : */ <- \n\n /*foo*/ bib"; i::Utf8ToUC16CharacterStream stream1(reinterpret_cast<const i::byte*>(str1), static_cast<unsigned>(strlen(str1))); @@ -672,6 +684,8 @@ void TestScanRegExp(const char* re_source, const char* expected) { TEST(RegExpScanning) { + v8::V8::Initialize(); + // RegExp token with added garbage at the end. The scanner should only // scan the RegExp until the terminating slash just before "flipperwald". TestScanRegExp("/b/flipperwald", "b"); diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc index 730d72a9..4767fc6b 100644 --- a/test/cctest/test-serialize.cc +++ b/test/cctest/test-serialize.cc @@ -99,10 +99,10 @@ static int make_code(TypeCode type, int id) { TEST(ExternalReferenceEncoder) { - OS::Setup(); Isolate* isolate = i::Isolate::Current(); isolate->stats_table()->SetCounterFunction(counter_function); - HEAP->Setup(false); + v8::V8::Initialize(); + ExternalReferenceEncoder encoder; CHECK_EQ(make_code(BUILTIN, Builtins::kArrayCode), Encode(encoder, Builtins::kArrayCode)); @@ -139,10 +139,10 @@ TEST(ExternalReferenceEncoder) { TEST(ExternalReferenceDecoder) { - OS::Setup(); Isolate* isolate = i::Isolate::Current(); isolate->stats_table()->SetCounterFunction(counter_function); - HEAP->Setup(false); + v8::V8::Initialize(); + ExternalReferenceDecoder decoder; CHECK_EQ(AddressOf(Builtins::kArrayCode), decoder.Decode(make_code(BUILTIN, Builtins::kArrayCode))); diff --git a/test/cctest/test-spaces.cc b/test/cctest/test-spaces.cc index de0c41e2..0f22ce1a 100644 --- a/test/cctest/test-spaces.cc +++ b/test/cctest/test-spaces.cc @@ -91,46 +91,74 @@ TEST(Page) { } +namespace v8 { +namespace internal { + +// Temporarily sets a given allocator in an isolate. +class TestMemoryAllocatorScope { + public: + TestMemoryAllocatorScope(Isolate* isolate, MemoryAllocator* allocator) + : isolate_(isolate), + old_allocator_(isolate->memory_allocator_) { + isolate->memory_allocator_ = allocator; + } + + ~TestMemoryAllocatorScope() { + isolate_->memory_allocator_ = old_allocator_; + } + + private: + Isolate* isolate_; + MemoryAllocator* old_allocator_; + + DISALLOW_COPY_AND_ASSIGN(TestMemoryAllocatorScope); +}; + +} } // namespace v8::internal + + TEST(MemoryAllocator) { OS::Setup(); Isolate* isolate = Isolate::Current(); - CHECK(HEAP->ConfigureHeapDefault()); - CHECK(isolate->memory_allocator()->Setup(HEAP->MaxReserved(), - HEAP->MaxExecutableSize())); - - OldSpace faked_space(HEAP, - HEAP->MaxReserved(), + isolate->InitializeLoggingAndCounters(); + Heap* heap = isolate->heap(); + CHECK(heap->ConfigureHeapDefault()); + MemoryAllocator* memory_allocator = new MemoryAllocator(isolate); + CHECK(memory_allocator->Setup(heap->MaxReserved(), + heap->MaxExecutableSize())); + TestMemoryAllocatorScope test_scope(isolate, memory_allocator); + + OldSpace faked_space(heap, + heap->MaxReserved(), OLD_POINTER_SPACE, NOT_EXECUTABLE); int total_pages = 0; int requested = MemoryAllocator::kPagesPerChunk; int allocated; // If we request n pages, we should get n or n - 1. - Page* first_page = - isolate->memory_allocator()->AllocatePages( - requested, &allocated, &faked_space); + Page* first_page = memory_allocator->AllocatePages( + requested, &allocated, &faked_space); CHECK(first_page->is_valid()); CHECK(allocated == requested || allocated == requested - 1); total_pages += allocated; Page* last_page = first_page; for (Page* p = first_page; p->is_valid(); p = p->next_page()) { - CHECK(isolate->memory_allocator()->IsPageInSpace(p, &faked_space)); + CHECK(memory_allocator->IsPageInSpace(p, &faked_space)); last_page = p; } // Again, we should get n or n - 1 pages. - Page* others = - isolate->memory_allocator()->AllocatePages( - requested, &allocated, &faked_space); + Page* others = memory_allocator->AllocatePages( + requested, &allocated, &faked_space); CHECK(others->is_valid()); CHECK(allocated == requested || allocated == requested - 1); total_pages += allocated; - isolate->memory_allocator()->SetNextPage(last_page, others); + memory_allocator->SetNextPage(last_page, others); int page_count = 0; for (Page* p = first_page; p->is_valid(); p = p->next_page()) { - CHECK(isolate->memory_allocator()->IsPageInSpace(p, &faked_space)); + CHECK(memory_allocator->IsPageInSpace(p, &faked_space)); page_count++; } CHECK(total_pages == page_count); @@ -141,34 +169,39 @@ TEST(MemoryAllocator) { // Freeing pages at the first chunk starting at or after the second page // should free the entire second chunk. It will return the page it was passed // (since the second page was in the first chunk). - Page* free_return = isolate->memory_allocator()->FreePages(second_page); + Page* free_return = memory_allocator->FreePages(second_page); CHECK(free_return == second_page); - isolate->memory_allocator()->SetNextPage(first_page, free_return); + memory_allocator->SetNextPage(first_page, free_return); // Freeing pages in the first chunk starting at the first page should free // the first chunk and return an invalid page. - Page* invalid_page = isolate->memory_allocator()->FreePages(first_page); + Page* invalid_page = memory_allocator->FreePages(first_page); CHECK(!invalid_page->is_valid()); - isolate->memory_allocator()->TearDown(); + memory_allocator->TearDown(); + delete memory_allocator; } TEST(NewSpace) { OS::Setup(); - CHECK(HEAP->ConfigureHeapDefault()); - CHECK(Isolate::Current()->memory_allocator()->Setup( - HEAP->MaxReserved(), HEAP->MaxExecutableSize())); + Isolate* isolate = Isolate::Current(); + isolate->InitializeLoggingAndCounters(); + Heap* heap = isolate->heap(); + CHECK(heap->ConfigureHeapDefault()); + MemoryAllocator* memory_allocator = new MemoryAllocator(isolate); + CHECK(memory_allocator->Setup(heap->MaxReserved(), + heap->MaxExecutableSize())); + TestMemoryAllocatorScope test_scope(isolate, memory_allocator); - NewSpace new_space(HEAP); + NewSpace new_space(heap); void* chunk = - Isolate::Current()->memory_allocator()->ReserveInitialChunk( - 4 * HEAP->ReservedSemiSpaceSize()); + memory_allocator->ReserveInitialChunk(4 * heap->ReservedSemiSpaceSize()); CHECK(chunk != NULL); Address start = RoundUp(static_cast<Address>(chunk), - 2 * HEAP->ReservedSemiSpaceSize()); - CHECK(new_space.Setup(start, 2 * HEAP->ReservedSemiSpaceSize())); + 2 * heap->ReservedSemiSpaceSize()); + CHECK(new_space.Setup(start, 2 * heap->ReservedSemiSpaceSize())); CHECK(new_space.HasBeenSetup()); while (new_space.Available() >= Page::kMaxHeapObjectSize) { @@ -178,28 +211,33 @@ TEST(NewSpace) { } new_space.TearDown(); - Isolate::Current()->memory_allocator()->TearDown(); + memory_allocator->TearDown(); + delete memory_allocator; } TEST(OldSpace) { OS::Setup(); - CHECK(HEAP->ConfigureHeapDefault()); - CHECK(Isolate::Current()->memory_allocator()->Setup( - HEAP->MaxReserved(), HEAP->MaxExecutableSize())); - - OldSpace* s = new OldSpace(HEAP, - HEAP->MaxOldGenerationSize(), + Isolate* isolate = Isolate::Current(); + isolate->InitializeLoggingAndCounters(); + Heap* heap = isolate->heap(); + CHECK(heap->ConfigureHeapDefault()); + MemoryAllocator* memory_allocator = new MemoryAllocator(isolate); + CHECK(memory_allocator->Setup(heap->MaxReserved(), + heap->MaxExecutableSize())); + TestMemoryAllocatorScope test_scope(isolate, memory_allocator); + + OldSpace* s = new OldSpace(heap, + heap->MaxOldGenerationSize(), OLD_POINTER_SPACE, NOT_EXECUTABLE); CHECK(s != NULL); - void* chunk = - Isolate::Current()->memory_allocator()->ReserveInitialChunk( - 4 * HEAP->ReservedSemiSpaceSize()); + void* chunk = memory_allocator->ReserveInitialChunk( + 4 * heap->ReservedSemiSpaceSize()); CHECK(chunk != NULL); Address start = static_cast<Address>(chunk); - size_t size = RoundUp(start, 2 * HEAP->ReservedSemiSpaceSize()) - start; + size_t size = RoundUp(start, 2 * heap->ReservedSemiSpaceSize()) - start; CHECK(s->Setup(start, size)); @@ -209,13 +247,13 @@ TEST(OldSpace) { s->TearDown(); delete s; - Isolate::Current()->memory_allocator()->TearDown(); + memory_allocator->TearDown(); + delete memory_allocator; } TEST(LargeObjectSpace) { - OS::Setup(); - CHECK(HEAP->Setup(false)); + v8::V8::Initialize(); LargeObjectSpace* lo = HEAP->lo_space(); CHECK(lo != NULL); @@ -247,9 +285,4 @@ TEST(LargeObjectSpace) { CHECK(!lo->IsEmpty()); CHECK(lo->AllocateRaw(lo_size)->IsFailure()); - - lo->TearDown(); - delete lo; - - Isolate::Current()->memory_allocator()->TearDown(); } diff --git a/test/mjsunit/compiler/regress-lbranch-double.js b/test/mjsunit/compiler/regress-lbranch-double.js new file mode 100644 index 00000000..dca6d5ba --- /dev/null +++ b/test/mjsunit/compiler/regress-lbranch-double.js @@ -0,0 +1,40 @@ +// 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: --allow-natives-syntax + +// ARM's code generator for LBranch had a bug, swapping the true/false +// branches when the representation of the condition is a double. + +function foo() { + return Math.sqrt(2.6415) ? 88 : 99; +} + +assertEquals(88, foo()); +assertEquals(88, foo()); +%OptimizeFunctionOnNextCall(foo) +assertEquals(88, foo()); diff --git a/test/mjsunit/regress/regress-91517.js b/test/mjsunit/regress/regress-91517.js new file mode 100644 index 00000000..68a768c4 --- /dev/null +++ b/test/mjsunit/regress/regress-91517.js @@ -0,0 +1,112 @@ +// 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. + +// Getting property names of an object with a prototype chain that +// triggers dictionary elements in GetLocalPropertyNames() shouldn't +// crash the runtime + +// Flags: --allow-natives-syntax + +function Object1() { + this.foo = 1; +} + +function Object2() { + this.fuz = 2; + this.objects = new Object(); + this.fuz1 = 2; + this.fuz2 = 2; + this.fuz3 = 2; + this.fuz4 = 2; + this.fuz5 = 2; + this.fuz6 = 2; + this.fuz7 = 2; + this.fuz8 = 2; + this.fuz9 = 2; + this.fuz10 = 2; + this.fuz11 = 2; + this.fuz12 = 2; + this.fuz13 = 2; + this.fuz14 = 2; + this.fuz15 = 2; + this.fuz16 = 2; + this.fuz17 = 2; + // Force dictionary-based properties + for (x=1;x<1000;x++) { + this["sdf" + x] = 2; + } +} + +function Object3() { + this.boo = 3; +} + +function Object4() { + this.baz = 4; +} + +obj1 = new Object1(); +obj2 = new Object2(); +obj3 = new Object3(); +obj4 = new Object4(); + +%SetHiddenPrototype(obj4, obj3); +%SetHiddenPrototype(obj3, obj2); +%SetHiddenPrototype(obj2, obj1); + +function contains(a, obj) { + for(var i = 0; i < a.length; i++) { + if(a[i] === obj){ + return true; + } + } + return false; +} +names = %GetLocalPropertyNames(obj4); +assertEquals(1021, names.length); +assertTrue(contains(names, "baz")); +assertTrue(contains(names, "boo")); +assertTrue(contains(names, "foo")); +assertTrue(contains(names, "fuz")); +assertTrue(contains(names, "fuz1")); +assertTrue(contains(names, "fuz2")); +assertTrue(contains(names, "fuz3")); +assertTrue(contains(names, "fuz4")); +assertTrue(contains(names, "fuz5")); +assertTrue(contains(names, "fuz6")); +assertTrue(contains(names, "fuz7")); +assertTrue(contains(names, "fuz8")); +assertTrue(contains(names, "fuz9")); +assertTrue(contains(names, "fuz10")); +assertTrue(contains(names, "fuz11")); +assertTrue(contains(names, "fuz12")); +assertTrue(contains(names, "fuz13")); +assertTrue(contains(names, "fuz14")); +assertTrue(contains(names, "fuz15")); +assertTrue(contains(names, "fuz16")); +assertTrue(contains(names, "fuz17")); +assertFalse(names[1020] == undefined); |