Merge pull request #184 from bocoup/iteration-semantics-2

Import tests from Google V8 (iteration semantics)
This commit is contained in:
Brian Terlson 2015-03-19 13:39:20 -07:00
commit ceeefa3196
20 changed files with 734 additions and 0 deletions

View File

@ -0,0 +1,29 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13 S5.n
description: >
Control flow during body evaluation should honor `break` statements within
the `catch` block of `try` statements.
---*/
function* values() {
yield 1;
yield 1;
}
var iterable = values();
var i = 0;
for (var x of iterable) {
i++;
try {
throw new Error();
} catch (err) {
break;
}
$ERROR('This code is unreachable.');
}
assert.sameValue(i, 1);

View File

@ -0,0 +1,28 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13 S5.n
description: >
Control flow during body evaluation should honor `break` statements within
`try` blocks.
---*/
function* values() {
yield 1;
yield 1;
}
var iterable = values();
var i = 0;
for (var x of iterable) {
i++;
try {
break;
$ERROR('This code is unreachable.');
} catch (err) {}
$ERROR('This code is unreachable.');
}
assert.sameValue(i, 1);

View File

@ -0,0 +1,28 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13 S5.n
description: >
Control flow during body evaluation should honor labeled `break`
statements.
---*/
function* values() {
yield 1;
yield 1;
}
var iterable = values();
var i = 0;
outer:
while (true) {
for (var x of iterable) {
i++;
break outer;
$ERROR('This code is unreachable.');
}
$ERROR('This code is unreachable.');
}
assert.sameValue(i, 1);

View File

@ -0,0 +1,23 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13 S5.n
description: >
Control flow during body evaluation should honor `break` statements.
---*/
function* values() {
yield 1;
yield 1;
}
var iterable = values();
var i = 0;
for (var x of iterable) {
i++;
break;
$ERROR('This code is unreachable.');
}
assert.sameValue(i, 1);

View File

@ -0,0 +1,28 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13 S5.n
description: >
Control flow during body evaluation should honor `continue` statements
within the `catch` block of `try` statements.
---*/
function* values() {
yield 1;
yield 1;
}
var iterable = values();
var i = 0;
for (var x of iterable) {
i++;
try {
throw new Error();
} catch (err) {
continue;
}
$ERROR('This code is unreachable.');
}
assert.sameValue(i, 2);

View File

@ -0,0 +1,27 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13 S5.n
description: >
Control flow during body evaluation should honor `continue` statements
within `try` blocks.
---*/
function* values() {
yield 1;
yield 1;
}
var iterable = values();
var i = 0;
for (var x of iterable) {
i++;
try {
continue;
$ERROR('This code is unreachable.');
} catch (err) {}
$ERROR('This code is unreachable.');
}
assert.sameValue(i, 2);

View File

@ -0,0 +1,30 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13 S5.n
description: >
Control flow during body evaluation should honor labeled `continue`
statements.
---*/
function* values() {
yield 1;
}
var iterable = values();
var i = 0;
var loop = true;
outer:
while (loop) {
loop = false;
for (var x of iterable) {
i++;
continue outer;
$ERROR('This code is unreachable (inside for-of).');
}
$ERROR('This code is unreachable (inside while).');
}
assert.sameValue(i, 1);

View File

@ -0,0 +1,23 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13 S5.n
description: >
Control flow during body evaluation should honor `continue` statements.
---*/
function* values() {
yield 1;
yield 1;
}
var iterable = values();
var i = 0;
for (var x of iterable) {
i++;
continue;
$ERROR('This code is unreachable.');
}
assert.sameValue(i, 2);

View File

@ -0,0 +1,23 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13
description: >
Generator function should return valid iterable objects.
---*/
function* values() {
yield 2;
yield 4;
yield 8;
}
var iterable = values();
var expected = [2, 4, 8];
var i = 0;
for (var x of iterable) {
assert.sameValue(x, expected[i]);
i++;
}
assert.sameValue(i, 3);

View File

@ -0,0 +1,27 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13
description: >
Generic objects with `@@iterator` protocols should function as iterables.
---*/
var iterable = {};
iterable[Symbol.iterator] = function() {
var j = 0;
return {
next: function() {
j = j + 2;
return { value: j, done: j === 8 };
}
}
};
var expected = [2, 4, 6];
var i = 0;
for (var x of iterable) {
assert.sameValue(x, expected[i]);
i++;
}
assert.sameValue(i, 3);

View File

@ -0,0 +1,13 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.12 S8.b
description: >
The value of the expression in a for-of statement's head must have an
`@@iterator` method.
---*/
var x;
assert.throws(TypeError, function() {
for (x of {}) {}
});

View File

@ -0,0 +1,17 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.12 S8.b
description: >
The value of the expression in a for-of statement's head must have an
`@@iterator` method.
---*/
var x;
assert.throws(TypeError, function() {
for (x of false) {}
});
assert.throws(TypeError, function() {
for (x of 37) {}
});

View File

@ -0,0 +1,17 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.12 S8.b
description: >
The value of the expression in a for-of statement's head is subject to the
semantics of the ToObject abstract operation.
---*/
var x;
assert.throws(TypeError, function() {
for (x of null) {}
});
assert.throws(TypeError, function() {
for (x of undefined) {}
});

View File

@ -0,0 +1,35 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13
description: >
Iterators that are implemented as proxies should behave identically to
non-proxy versions.
---*/
var iterable = {};
var nextResult = { value: 23, done: false };
var lastResult = { value: null, done: true };
var i;
var iterator = {
next: function() {
var result = nextResult;
nextResult = lastResult;
return result;
}
};
var proxiedIterator = new Proxy(iterator, {
get: function(target, name) {
return target[name];
}
});
iterable[Symbol.iterator] = function() { return proxiedIterator; };
i = 0;
for (var x of iterable) {
assert.sameValue(x, 23);
i++;
}
assert.sameValue(i, 1);

View File

@ -0,0 +1,40 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13 S5.c
description: >
The iterator's `next` method should be accessed with each iteration as per
the `IteratorStep` abstract operation (7.4.5).
---*/
var iterable = {};
var iterator = {};
var firstIterResult = { done: false };
var iterationCount, invocationCount;
iterable[Symbol.iterator] = function() {
return iterator;
};
iterator.next = function() { return { value: 45, done: false }; };
iterationCount = 0;
invocationCount = 0;
for (var x of iterable) {
assert.sameValue(x, 45);
iterator.next = function() {
invocationCount++;
Object.defineProperty(iterator, 'next', {
get: function() {
$ERROR('Should not access the `next` method after iteration ' +
'is complete.');
}
});
return { value: null, done: true };
};
iterationCount++;
}
assert.sameValue(iterationCount, 1);
assert.sameValue(invocationCount, 1);

View File

@ -0,0 +1,129 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 7.4.3
description: >
The `done` value of iteration result objects should be interpreted as
incomplete as per `ToBoolean` (7.1.2).
---*/
var iterable = {};
var i, firstIterResult;
iterable[Symbol.iterator] = function() {
var finalIterResult = { value: null, done: true };
var nextIterResult = firstIterResult;
return {
next: function() {
var iterResult = nextIterResult;
nextIterResult = finalIterResult;
return iterResult;
}
};
};
firstIterResult = { value: null, done: undefined };
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 1);
firstIterResult = { value: null };
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 1);
firstIterResult = { value: null, done: null };
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 1);
firstIterResult = { value: null, done: false };
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 1);
firstIterResult = { value: null, done: true };
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 0);
firstIterResult = { value: null, done: 1 };
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 0);
firstIterResult = { value: null, done: 0 };
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 1);
firstIterResult = { value: null, done: -0 };
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 1);
firstIterResult = { value: null, done: NaN };
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 1);
firstIterResult = { value: null, done: '' };
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 1);
firstIterResult = { value: null, done: '0' };
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 0);
firstIterResult = { value: null, done: Symbol() };
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 0);
firstIterResult = { value: null, done: {} };
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 0);
firstIterResult = { value: null };
Object.defineProperty(firstIterResult, 'done', {
get: function() {
return true;
}
});
i = 0;
for (var x of iterable) {
i++;
}
assert.sameValue(i, 0);

View File

@ -0,0 +1,105 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13 S5.c
description: >
If Type(result) is not Object, throw a TypeError exception as per
`IteratorNext` (7.4.2 S4)
---*/
var iterable = {};
var firstIterResult;
iterable[Symbol.iterator] = function() {
var finalIterResult = { value: null, done: true };
var nextIterResult = firstIterResult;
return {
next: function() {
var iterResult = nextIterResult;
nextIterResult = finalIterResult;
return iterResult;
}
};
};
firstIterResult = true;
assert.throws(TypeError, function() {
for (var x of iterable) {}
});
firstIterResult = false;
assert.throws(TypeError, function() {
for (var x of iterable) {}
});
firstIterResult = 'string';
assert.throws(TypeError, function() {
for (var x of iterable) {}
});
firstIterResult = undefined;
assert.throws(TypeError, function() {
for (var x of iterable) {}
});
firstIterResult = null;
assert.throws(TypeError, function() {
for (var x of iterable) {}
});
firstIterResult = 4;
assert.throws(TypeError, function() {
for (var x of iterable) {}
});
firstIterResult = NaN;
assert.throws(TypeError, function() {
for (var x of iterable) {}
});
firstIterResult = Symbol('s');
assert.throws(TypeError, function() {
for (var x of iterable) {}
});
firstIterResult = /regexp/;
for (var x of iterable) {}
firstIterResult = {};
for (var x of iterable) {}
firstIterResult = new Proxy({}, {
get: function(receiver, name) {
if (name === 'done') {
return true;
}
if (name === 'value') {
return null;
}
$ERROR('This code is unreachable.');
}
});
for (var x of iterable) {
$ERROR('This code is unreachable.');
}
firstIterResult = new Proxy({}, {
get: function(receiver, name) {
if (name === 'done') {
return false;
}
if (name === 'value') {
return 23;
}
$ERROR('This code is unreachable.');
}
});
i = 0;
for (var x of iterable) {
assert.sameValue(x, 23);
i++;
}
assert.sameValue(i, 1);

View File

@ -0,0 +1,47 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13 S5.c
description: >
The `done` value of iteration result objects should be interpreted as
incomplete as per `ToBoolean` (7.1.2).
---*/
var iterable = {};
var i, firstIterResult;
iterable[Symbol.iterator] = function() {
var finalIterResult = { value: null, done: true };
var nextIterResult = firstIterResult;
return {
next: function() {
var iterResult = nextIterResult;
nextIterResult = finalIterResult;
return iterResult;
}
};
};
firstIterResult = { value: 45, done: false };
i = 0;
for (var x of iterable) {
assert.sameValue(x, 45);
i++;
}
assert.sameValue(i, 1);
firstIterResult = { done: false };
Object.defineProperty(firstIterResult, 'value', {
get: function() {
return 23;
}
});
i = 0;
for (var x of iterable) {
assert.sameValue(x, 23);
i++;
}
assert.sameValue(i, 1);

View File

@ -0,0 +1,37 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13
description: >
Nested statements should operate independently.
---*/
function* values() {
yield 3;
yield 7;
}
var outerIterable, expectedOuter, i, innerIterable, expectedInner, j;
outerIterable = values();
expectedOuter = 3;
i = 0;
for (var x of outerIterable) {
assert.sameValue(x, expectedOuter);
expectedOuter = 7;
i++;
innerIterable = values();
expectedInner = 3;
j = 0;
for (var y of innerIterable) {
assert.sameValue(y, expectedInner);
expectedInner = 7;
j++;
}
assert.sameValue(j, 2);
}
assert.sameValue(i, 2);

View File

@ -0,0 +1,28 @@
// Copyright (C) Copyright 2013 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 13.6.4.13
description: >
Control flow during body evaluation should honor `return` statements.
---*/
function* values() {
yield 1;
yield 1;
}
var iterable = values();
var i = 0;
var result = (function() {
for (var x of iterable) {
i++;
return 34;
$ERROR('This code is unreachable.');
}
$ERROR('This code is unreachable.');
})();
assert.sameValue(result, 34);
assert.sameValue(i, 1);