mirror of
https://github.com/anomalyco/opencode.git
synced 2026-09-11 11:26:24 +00:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5518553b5 | ||
|
|
6eb2042acd | ||
|
|
54504ab3a5 | ||
|
|
cc5086d127 | ||
|
|
b20482461c | ||
|
|
5b5368fe98 |
@@ -18,6 +18,7 @@ const WebSocketResponseCreate = Schema.StructWithRest(Schema.Struct({ type: Sche
|
||||
])
|
||||
const decodeMessage = ProviderShared.validateWith(Schema.decodeUnknownEffect(WebSocketResponseCreate))
|
||||
const encodeMessage = Schema.encodeSync(Schema.fromJsonString(WebSocketResponseCreate))
|
||||
const decodeEvent = Schema.decodeUnknownEffect(OpenResponses.protocol.stream.event)
|
||||
|
||||
export interface Options {
|
||||
readonly id: string
|
||||
@@ -26,7 +27,6 @@ export interface Options {
|
||||
readonly enabled?: (url: string) => boolean
|
||||
readonly url?: (url: string) => string
|
||||
readonly headers?: (headers: Headers.Headers) => Headers.Headers
|
||||
readonly continuation?: OpenResponsesContinuation.Shape
|
||||
}
|
||||
|
||||
export interface Prepared {
|
||||
@@ -60,7 +60,7 @@ const driver = (options: Options, body: string): WebSocketChannelDriver => {
|
||||
}),
|
||||
observe: (_create, frame) =>
|
||||
Effect.gen(function* () {
|
||||
const event = yield* OpenResponses.decodeChannelEvent(frame).pipe(
|
||||
const event = yield* decodeEvent(frame).pipe(
|
||||
Effect.mapError((cause) =>
|
||||
ProviderShared.eventError(options.id, `Invalid ${options.name} WebSocket event`, frame, cause),
|
||||
),
|
||||
@@ -163,7 +163,6 @@ export const transport = <Body>(options: Options): Transport<Body, Prepared, str
|
||||
request: create.request,
|
||||
message: create.message,
|
||||
base,
|
||||
continuation: options.continuation,
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
@@ -6,6 +6,7 @@ import { OpenResponses } from "./open-responses.js"
|
||||
|
||||
const PROTOCOL = "open-responses.websocket.v1"
|
||||
const VERSION = 1
|
||||
const decodeEvent = Schema.decodeUnknownEffect(OpenResponses.protocol.stream.event)
|
||||
|
||||
interface CheckpointValue {
|
||||
readonly version: typeof VERSION
|
||||
@@ -14,19 +15,12 @@ interface CheckpointValue {
|
||||
readonly output: ReadonlyArray<unknown>
|
||||
}
|
||||
|
||||
/**
|
||||
* Fields to send next to `previous_response_id` on an incremental step, or undefined to send the step in full.
|
||||
* Whether omitted fields carry over from the continued response is provider behavior the route must know.
|
||||
*/
|
||||
export type Shape = (request: Readonly<Record<string, unknown>>) => Readonly<Record<string, unknown>> | undefined
|
||||
|
||||
export interface DriverInput {
|
||||
readonly id: string
|
||||
readonly name: string
|
||||
readonly request: Readonly<Record<string, unknown>>
|
||||
readonly message: string
|
||||
readonly base: WebSocketChannelDriver
|
||||
readonly continuation?: Shape
|
||||
}
|
||||
|
||||
const checkpointValue = (checkpoint: ChannelCheckpoint | undefined): CheckpointValue | undefined => {
|
||||
@@ -133,26 +127,22 @@ const rejected = (
|
||||
|
||||
export const driver = (input: DriverInput): WebSocketChannelDriver => {
|
||||
const { previous_response_id: _previousResponseID, ...request } = input.request
|
||||
const shape = input.continuation ?? ((fields: Readonly<Record<string, unknown>>) => fields)
|
||||
let output: OpenResponses.StreamItem[] = []
|
||||
return {
|
||||
create: (checkpoint) =>
|
||||
Effect.sync(() => {
|
||||
output = []
|
||||
const previous = checkpointValue(checkpoint)
|
||||
// Ask the route first: diffing the whole history is wasted when it declines the continuation.
|
||||
const fields = previous ? shape(request) : undefined
|
||||
const delta = previous && fields ? incremental(request, previous) : undefined
|
||||
if (!previous || !fields || !delta)
|
||||
return { message: ProviderShared.encodeJson(request), mode: "full" as const }
|
||||
const delta = previous ? incremental(request, previous) : undefined
|
||||
if (!previous || !delta) return { message: ProviderShared.encodeJson(request), mode: "full" as const }
|
||||
return {
|
||||
message: ProviderShared.encodeJson({ ...fields, input: delta, previous_response_id: previous.responseID }),
|
||||
message: ProviderShared.encodeJson({ ...request, input: delta, previous_response_id: previous.responseID }),
|
||||
mode: "incremental" as const,
|
||||
}
|
||||
}),
|
||||
observe: (create, frame) =>
|
||||
Effect.gen(function* () {
|
||||
const event = yield* OpenResponses.decodeChannelEvent(frame).pipe(
|
||||
const event = yield* decodeEvent(frame).pipe(
|
||||
Effect.mapError((cause) =>
|
||||
ProviderShared.eventError(input.id, `Invalid ${input.name} WebSocket event`, frame, cause),
|
||||
),
|
||||
@@ -205,4 +195,4 @@ export const driver = (input: DriverInput): WebSocketChannelDriver => {
|
||||
}
|
||||
}
|
||||
|
||||
export * as OpenResponsesContinuation from "./open-responses-continuation.js"
|
||||
export const OpenResponsesContinuation = { driver } as const
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Effect, Option, Schema, SchemaGetter } from "effect"
|
||||
import { Effect, Option, Schema } from "effect"
|
||||
import type { Content } from "@opencode/schema/tool"
|
||||
import { HttpTransport } from "../route/transport/index.js"
|
||||
import { Protocol } from "../route/protocol.js"
|
||||
@@ -325,8 +325,9 @@ export const StreamItem = Schema.StructWithRest(
|
||||
export type StreamItem = Schema.Schema.Type<typeof StreamItem>
|
||||
export type OutputItem = StreamItem & { readonly id: string }
|
||||
|
||||
// Responses-compatible providers put streaming error details at the top level or
|
||||
// under `error`, and response failures under `response.error`. Accept all three shapes.
|
||||
// The Responses schema puts streaming error details at the top level and
|
||||
// response failures under `response.error`. WebSocket failures use an
|
||||
// event-level `error` envelope, so accept all three shapes here.
|
||||
// https://www.openresponses.org/specification
|
||||
const OpenResponsesErrorPayload = Schema.Struct({
|
||||
type: optionalNull(Schema.String),
|
||||
@@ -400,39 +401,10 @@ export const Event = Schema.StructWithRest(
|
||||
headers: Schema.optional(Schema.Unknown),
|
||||
}),
|
||||
[Schema.Record(Schema.String, Schema.Unknown)],
|
||||
).pipe(
|
||||
Schema.decode({
|
||||
decode: SchemaGetter.transform((event) => {
|
||||
if (event.type !== "error" || event.error != null) return event
|
||||
const { code, message, param, ...rest } = event
|
||||
if (code === undefined && message === undefined && param === undefined) return event
|
||||
// Flat errors (for example, Meta's) can also arrive through generic Responses endpoints.
|
||||
return { ...rest, error: { code, message, param } }
|
||||
}),
|
||||
encode: SchemaGetter.passthrough(),
|
||||
}),
|
||||
)
|
||||
export type Event = Schema.Schema.Type<typeof Event>
|
||||
export type NormalizedEvent = Event & { readonly item?: OutputItem | null }
|
||||
|
||||
const decodeEventValue = Schema.decodeUnknownEffect(Event)
|
||||
const decodeFrame = Schema.decodeUnknownEffect(ProviderShared.Json)
|
||||
|
||||
/**
|
||||
* Decodes one WebSocket frame. xAI answers a rejected `response.create` with `{ "error": { "message", "type" } }` and no
|
||||
* event type; that envelope reads as an error event so the failure classifies instead of failing decoding.
|
||||
*/
|
||||
export const decodeChannelEvent = (frame: string) =>
|
||||
decodeFrame(frame).pipe(
|
||||
Effect.flatMap((value) =>
|
||||
decodeEventValue(
|
||||
ProviderShared.isRecord(value) && value.type === undefined && ProviderShared.isRecord(value.error)
|
||||
? { ...value, type: "error" }
|
||||
: value,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
export interface ProviderAdapter {
|
||||
readonly id: string
|
||||
readonly name: string
|
||||
|
||||
@@ -41,10 +41,6 @@ const responsesRoute = Route.make({
|
||||
id: "openai-responses",
|
||||
name: "xAI Responses",
|
||||
rotateAfterMs: RESPONSES_WEBSOCKET_ROTATE_AFTER_MS,
|
||||
// xAI continues a chain only from stored responses: with `store: false` (the route default) `previous_response_id`
|
||||
// fails with "Response with id=… not found", so those steps are sent in full over the reused connection. It also
|
||||
// rejects `instructions` next to `previous_response_id` and keeps the instructions of the response it continues.
|
||||
continuation: ({ instructions: _instructions, ...request }) => (request.store === false ? undefined : request),
|
||||
}),
|
||||
defaults: { providerOptions: { store: false, include: ["reasoning.encrypted_content"] } },
|
||||
})
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
import { expect } from "bun:test"
|
||||
import { Effect, Schema } from "effect"
|
||||
import { LLM, LLMClient } from "../../src/index.js"
|
||||
import { OpenResponses } from "../../src/protocols/open-responses.js"
|
||||
import { Meta } from "../../src/providers/index.js"
|
||||
import { configure } from "../../src/providers/openai-compatible-responses.js"
|
||||
import { it } from "../lib/effect.js"
|
||||
import { fixedResponse } from "../lib/http.js"
|
||||
import { sseEvents } from "../lib/sse.js"
|
||||
|
||||
const decodeEvent = Schema.decodeUnknownEffect(OpenResponses.protocol.stream.event)
|
||||
|
||||
it.effect("normalizes flat errors in shared SSE and WebSocket decoding", () =>
|
||||
Effect.gen(function* () {
|
||||
const frame = {
|
||||
type: "error",
|
||||
sequence_number: 4,
|
||||
code: "server_shutting_down",
|
||||
message: "Server is shutting down. Please retry your request.",
|
||||
param: null,
|
||||
}
|
||||
for (const decode of [decodeEvent, OpenResponses.decodeChannelEvent]) {
|
||||
const event = yield* decode(JSON.stringify(frame))
|
||||
expect(event).toEqual({
|
||||
type: "error",
|
||||
sequence_number: 4,
|
||||
error: { code: frame.code, message: frame.message, param: null },
|
||||
})
|
||||
|
||||
for (const unchanged of [
|
||||
event,
|
||||
{ type: "error" },
|
||||
{
|
||||
type: "response.failed",
|
||||
response: { id: "resp_failed", error: { code: "server_error", message: "Internal server error" } },
|
||||
},
|
||||
{ type: "response.output_text.delta", item_id: "msg_text", delta: "Hello" },
|
||||
]) {
|
||||
expect(yield* decode(JSON.stringify(unchanged))).toEqual(unchanged)
|
||||
}
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("continues to normalize untyped xAI WebSocket errors", () =>
|
||||
Effect.gen(function* () {
|
||||
const frame = { error: { type: "api_error", message: "gRPC error: Response with id=resp_missing not found" } }
|
||||
expect(yield* OpenResponses.decodeChannelEvent(JSON.stringify(frame))).toEqual({ ...frame, type: "error" })
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("retains classification and original error bodies through Meta and generic Responses routes", () =>
|
||||
Effect.gen(function* () {
|
||||
const raw = `{
|
||||
"type": "error",
|
||||
"sequence_number": 4,
|
||||
"code": "server_shutting_down",
|
||||
"message": "Server is shutting down. Please retry your request.",
|
||||
"param": null,
|
||||
"diagnostic": "retain-original-frame"
|
||||
}`
|
||||
for (const model of [
|
||||
Meta.configure({ apiKey: "fixture" }).responses("muse-spark-1.3"),
|
||||
configure({ apiKey: "fixture", provider: "gateway", baseURL: "https://responses.example.test/v1" }).model(
|
||||
"example-model",
|
||||
),
|
||||
]) {
|
||||
const error = yield* LLMClient.generate(LLM.request({ model, prompt: "Hello" })).pipe(
|
||||
Effect.provide(fixedResponse(sseEvents(raw.replaceAll("\n", "\ndata: ")))),
|
||||
Effect.flip,
|
||||
)
|
||||
expect(error.reason._tag).toBe("ProviderInternal")
|
||||
expect(error.message).toBe("server_shutting_down: Server is shutting down. Please retry your request.")
|
||||
expect(error.reason.body).toBe(raw)
|
||||
expect(error.reason.http?.status).toBe(200)
|
||||
}
|
||||
}),
|
||||
)
|
||||
@@ -90,11 +90,7 @@ const classifyingChannelDriver = (message: string): WebSocketChannelDriver => {
|
||||
}
|
||||
}
|
||||
|
||||
const continuationDriver = (
|
||||
request: Readonly<Record<string, unknown>>,
|
||||
base = baseChannelDriver,
|
||||
continuation?: OpenResponsesContinuation.Shape,
|
||||
) => {
|
||||
const continuationDriver = (request: Readonly<Record<string, unknown>>, base = baseChannelDriver) => {
|
||||
const message = ProviderShared.encodeJson(request)
|
||||
return OpenResponsesContinuation.driver({
|
||||
id: "openai-responses",
|
||||
@@ -102,7 +98,6 @@ const continuationDriver = (
|
||||
request,
|
||||
message,
|
||||
base: base(message),
|
||||
continuation,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -926,58 +921,6 @@ describe("OpenAI Responses route", () => {
|
||||
type: "provider-failure",
|
||||
error: { reason: { _tag: "InvalidRequest", classification: "context-overflow" } },
|
||||
})
|
||||
|
||||
// A retryable failure stays one: the runner retries it, and the transport has already dropped the
|
||||
// checkpoint, so that retry is a full send. xAI reports every rejection this way.
|
||||
const internal = ProviderShared.encodeJson({
|
||||
type: "error",
|
||||
error: { type: "api_error", message: "gRPC error: Response with id=resp_1 not found" },
|
||||
})
|
||||
expect(yield* second.observe(yield* second.create(saved), internal)).toMatchObject({
|
||||
type: "provider-failure",
|
||||
error: { reason: { _tag: "ProviderInternal" } },
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("shapes the incremental send with the route continuation", () =>
|
||||
Effect.gen(function* () {
|
||||
const firstRequest = {
|
||||
type: "response.create",
|
||||
model: "grok-4.6",
|
||||
store: true,
|
||||
instructions: "You are terse.",
|
||||
input: [{ role: "user", content: [{ type: "input_text", text: "First" }] }],
|
||||
}
|
||||
const secondRequest = {
|
||||
...firstRequest,
|
||||
input: [...firstRequest.input, { role: "user", content: [{ type: "input_text", text: "Second" }] }],
|
||||
}
|
||||
const saved = checkpoint(
|
||||
yield* continuationDriver(firstRequest).observe(
|
||||
yield* continuationDriver(firstRequest).create(undefined),
|
||||
ProviderShared.encodeJson({ type: "response.completed", response: { id: "resp_1" } }),
|
||||
),
|
||||
)
|
||||
|
||||
const trimmed = yield* continuationDriver(
|
||||
secondRequest,
|
||||
baseChannelDriver,
|
||||
({ instructions: _, ...rest }) => rest,
|
||||
).create(saved)
|
||||
expect(trimmed.mode).toBe("incremental")
|
||||
expect(JSON.parse(trimmed.message)).toEqual({
|
||||
type: "response.create",
|
||||
model: "grok-4.6",
|
||||
store: true,
|
||||
previous_response_id: "resp_1",
|
||||
input: [{ role: "user", content: [{ type: "input_text", text: "Second" }] }],
|
||||
})
|
||||
|
||||
// Declining the continuation sends the step in full and never sends a previous_response_id.
|
||||
const declined = yield* continuationDriver(secondRequest, baseChannelDriver, () => undefined).create(saved)
|
||||
expect(declined.mode).toBe("full")
|
||||
expect(JSON.parse(declined.message)).toEqual(secondRequest)
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
import { describe, expect } from "bun:test"
|
||||
import { Effect, Layer, Stream } from "effect"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, LLMEvent, Message } from "../../src/index.js"
|
||||
import { XAI } from "../../src/providers.js"
|
||||
import { OpenResponses } from "../../src/protocols/open-responses.js"
|
||||
import { OpenAIResponses } from "../../src/protocols/openai-responses.js"
|
||||
import * as ProviderShared from "../../src/protocols/shared.js"
|
||||
import { XAIResponses } from "../../src/protocols/xai-responses.js"
|
||||
import {
|
||||
LLMClient,
|
||||
RequestExecutor,
|
||||
WebSocketTransport,
|
||||
type ChannelCheckpoint,
|
||||
type WebSocketChannelDriver,
|
||||
} from "../../src/route.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
import { it } from "../lib/effect.js"
|
||||
import { fixedResponse } from "../lib/http.js"
|
||||
@@ -20,35 +13,6 @@ import { sseEvents } from "../lib/sse.js"
|
||||
|
||||
const model = XAI.configure({ apiKey: "test", baseURL: "https://api.x.ai/v1" }).responses("grok-4.6")
|
||||
|
||||
/** Runs a request through the WebSocket transport and hands back its channel driver; the HTTP fallback answers. */
|
||||
const channelDriver = (request: ReturnType<typeof LLM.request>) =>
|
||||
Effect.gen(function* () {
|
||||
let driver: WebSocketChannelDriver | undefined
|
||||
yield* LLMClient.generate(request, {
|
||||
webSocket: {
|
||||
execute: (exchange) =>
|
||||
Effect.sync(() => {
|
||||
driver = exchange.driver
|
||||
return { frames: exchange.fallback(), complete: Effect.void }
|
||||
}),
|
||||
},
|
||||
}).pipe(Effect.provide(fixedResponse(sseEvents({ type: "response.completed", response: { id: "http" } }))))
|
||||
if (!driver) throw new Error("Expected a WebSocket channel driver")
|
||||
return driver
|
||||
})
|
||||
|
||||
const completed = (driver: WebSocketChannelDriver, id: string) =>
|
||||
Effect.gen(function* () {
|
||||
const create = yield* driver.create(undefined)
|
||||
yield* driver.observe(create, ProviderShared.encodeJson({ type: "response.created", response: { id } }))
|
||||
const observation = yield* driver.observe(
|
||||
create,
|
||||
ProviderShared.encodeJson({ type: "response.completed", response: { id } }),
|
||||
)
|
||||
if (observation.type !== "completed" || !observation.checkpoint) throw new Error("Expected a checkpoint")
|
||||
return observation.checkpoint
|
||||
})
|
||||
|
||||
describe("xAI Responses route", () => {
|
||||
it.effect("composes the Open Responses baseline with xAI extensions", () =>
|
||||
Effect.gen(function* () {
|
||||
@@ -198,78 +162,6 @@ describe("xAI Responses route", () => {
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("classifies xAI's untyped WebSocket error envelope", () =>
|
||||
Effect.gen(function* () {
|
||||
// xAI answers a rejected response.create with an error envelope that carries no event type.
|
||||
const envelope = ProviderShared.encodeJson({
|
||||
error: {
|
||||
message:
|
||||
'Request validation error: {"code":"400","error":"Argument not supported: instructions and previous_response_id together"}',
|
||||
type: "api_error",
|
||||
},
|
||||
})
|
||||
const webSocket = WebSocketTransport.makeDirect({
|
||||
open: () =>
|
||||
Effect.succeed({ sendText: () => Effect.void, messages: Stream.make(envelope), close: Effect.void }),
|
||||
})
|
||||
const error = yield* LLMClient.generate(LLM.request({ model, prompt: "Hello" }), { webSocket }).pipe(
|
||||
Effect.provide(
|
||||
LLMClient.layer.pipe(
|
||||
Layer.provide(
|
||||
Layer.succeed(
|
||||
RequestExecutor.Service,
|
||||
RequestExecutor.Service.of({ execute: () => Effect.die("unexpected HTTP request") }),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Effect.flip,
|
||||
)
|
||||
|
||||
expect(error.reason._tag).toBe("ProviderInternal")
|
||||
expect(error.message).toContain("Argument not supported: instructions and previous_response_id together")
|
||||
expect(error.reason.body).toBe(envelope)
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("continues stored responses without instructions and sends unstored steps in full", () =>
|
||||
Effect.gen(function* () {
|
||||
const step = (store: boolean, ...prompts: string[]) =>
|
||||
LLM.request({
|
||||
model,
|
||||
system: "You are terse.",
|
||||
messages: prompts.map((prompt) => Message.user(prompt)),
|
||||
providerOptions: { store },
|
||||
})
|
||||
const send = (store: boolean, checkpoint: ChannelCheckpoint) =>
|
||||
channelDriver(step(store, "First", "Second")).pipe(Effect.flatMap((driver) => driver.create(checkpoint)))
|
||||
|
||||
const stored = yield* send(true, yield* completed(yield* channelDriver(step(true, "First")), "resp_1"))
|
||||
expect(stored.mode).toBe("incremental")
|
||||
expect(JSON.parse(stored.message)).toEqual({
|
||||
type: "response.create",
|
||||
model: "grok-4.6",
|
||||
store: true,
|
||||
include: ["reasoning.encrypted_content"],
|
||||
previous_response_id: "resp_1",
|
||||
input: [{ role: "user", content: [{ type: "input_text", text: "Second" }] }],
|
||||
})
|
||||
|
||||
// The connection cache only serves stored responses, so the default store: false never chains.
|
||||
const unstored = yield* send(false, yield* completed(yield* channelDriver(step(false, "First")), "resp_1"))
|
||||
expect(unstored.mode).toBe("full")
|
||||
expect(JSON.parse(unstored.message)).toMatchObject({
|
||||
instructions: "You are terse.",
|
||||
store: false,
|
||||
input: [
|
||||
{ role: "user", content: [{ type: "input_text", text: "First" }] },
|
||||
{ role: "user", content: [{ type: "input_text", text: "Second" }] },
|
||||
],
|
||||
})
|
||||
expect(JSON.parse(unstored.message).previous_response_id).toBeUndefined()
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("parses xAI hosted tool items", () =>
|
||||
Effect.gen(function* () {
|
||||
const item = { type: "x_search_call", id: "x_search_1", status: "completed", action: { query: "news" } }
|
||||
|
||||
@@ -126,9 +126,15 @@ export function createComposerSubmit(input: ComposerSubmitInput) {
|
||||
|
||||
if (command) {
|
||||
clearSubmission(input, submission)
|
||||
void sendCommand(session, value, command, input.adapter.controls().model.selection.trackSessionCommit).catch(
|
||||
(error) => failSubmission(input, session, "command", error, restore, value.id),
|
||||
)
|
||||
// Commands always steer: the server applies a command's configured
|
||||
// agent and model immediately at admission, so queueing one would
|
||||
// reconfigure the turn it is supposed to wait behind.
|
||||
void sendCommand(
|
||||
session,
|
||||
{ ...value, delivery: "steer" },
|
||||
command,
|
||||
input.adapter.controls().model.selection.trackSessionCommit,
|
||||
).catch((error) => failSubmission(input, session, "command", error, restore, value.id))
|
||||
return
|
||||
}
|
||||
} finally {
|
||||
@@ -320,8 +326,7 @@ async function sendCommand(
|
||||
track?: ModelSelection["trackSessionCommit"],
|
||||
) {
|
||||
const request = await buildSubmissionRequest(session, value)
|
||||
// Like queued prompts, queued commands must not apply the composer's selection to active work.
|
||||
if (value.delivery === "steer") await applySelection(session, value.selection, track)
|
||||
await applySelection(session, value.selection, track)
|
||||
await session.api.command({
|
||||
sessionID: session.id,
|
||||
command: command.command,
|
||||
|
||||
@@ -47,7 +47,7 @@ const handler = Effect.fn("cli.session.list")(function* (
|
||||
null,
|
||||
2,
|
||||
)
|
||||
: formatList(page.data)) + EOL
|
||||
: formatTable(page.data)) + EOL
|
||||
const write = Effect.tryPromise(
|
||||
() =>
|
||||
new Promise<void>((resolve, reject) => {
|
||||
@@ -96,14 +96,18 @@ export default Runtime.handler(Commands.commands.session.commands.list, (input)
|
||||
),
|
||||
)
|
||||
|
||||
function formatList(sessions: ReadonlyArray<SessionInfo>) {
|
||||
return sessions
|
||||
.map((session) =>
|
||||
[
|
||||
session.id,
|
||||
(session.title ?? "Untitled session").replace(/[\r\n\t]/g, " "),
|
||||
new Date(session.time.updated).toLocaleString(),
|
||||
].join("\t"),
|
||||
)
|
||||
.join(EOL)
|
||||
function formatTable(sessions: ReadonlyArray<SessionInfo>) {
|
||||
const rows = sessions.map((session) => ({
|
||||
id: session.id,
|
||||
title: (session.title ?? "Untitled session").replace(/[\r\n\t]/g, " "),
|
||||
updated: new Date(session.time.updated).toLocaleString(),
|
||||
}))
|
||||
const idWidth = Math.max(20, ...rows.map((row) => row.id.length))
|
||||
const titleWidth = Math.max(25, ...rows.map((row) => row.title.length))
|
||||
const header = `${"Session ID".padEnd(idWidth)} ${"Title".padEnd(titleWidth)} Updated`
|
||||
return [
|
||||
header,
|
||||
"─".repeat(header.length),
|
||||
...rows.map((row) => `${row.id.padEnd(idWidth)} ${row.title.padEnd(titleWidth)} ${row.updated}`),
|
||||
].join(EOL)
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ import type { RelativePath } from "@opencode/schema/schema"
|
||||
import type { Brand } from "effect"
|
||||
import type { Model } from "@opencode/schema/model"
|
||||
import type { DateTime } from "effect"
|
||||
import type { Permission } from "@opencode/schema/permission"
|
||||
import type { SessionMessage } from "@opencode/schema/session-message"
|
||||
import type { SessionInbox } from "@opencode/schema/session-inbox"
|
||||
import type { PromptInput } from "@opencode/schema/prompt-input"
|
||||
import type { AgentAttachment } from "@opencode/schema/prompt"
|
||||
import type { Skill } from "@opencode/schema/skill"
|
||||
import type { Event } from "@opencode/schema/event"
|
||||
import type { FileDiff } from "@opencode/schema/file-diff"
|
||||
import type { InstructionEntry } from "@opencode/schema/instruction-entry"
|
||||
import type { Schema } from "effect"
|
||||
import type { EventLog } from "@opencode/schema/event-log"
|
||||
@@ -27,6 +27,7 @@ import type { Integration } from "@opencode/schema/integration"
|
||||
import type { Form } from "@opencode/schema/form"
|
||||
import type { Mcp } from "@opencode/schema/mcp"
|
||||
import type { Credential } from "@opencode/schema/credential"
|
||||
import type { Permission } from "@opencode/schema/permission"
|
||||
import type { PermissionSaved } from "@opencode/schema/permission-saved"
|
||||
import type { FileSystem } from "@opencode/schema/filesystem"
|
||||
import type { Command } from "@opencode/schema/command"
|
||||
@@ -36,7 +37,6 @@ import type { PtyTicket } from "@opencode/schema/pty-ticket"
|
||||
import type { Reference } from "@opencode/schema/reference"
|
||||
import type { Worktree } from "@opencode/schema/worktree"
|
||||
import type { Vcs } from "@opencode/schema/vcs"
|
||||
import type { FileDiff } from "@opencode/schema/file-diff"
|
||||
import type { WebSearch } from "@opencode/schema/websearch"
|
||||
import type { Config } from "@opencode/schema/config"
|
||||
|
||||
@@ -209,7 +209,6 @@ export type SessionCreateInput = {
|
||||
readonly model?: Model.Ref | undefined
|
||||
readonly location?: Location.Ref | undefined
|
||||
readonly metadata?: Session.Metadata | undefined
|
||||
readonly permissions?: Permission.Ruleset | undefined
|
||||
}
|
||||
export type SessionCreateOutput = Session.Info
|
||||
export type SessionCreateOperation<E = never> = (input?: SessionCreateInput) => Effect.Effect<SessionCreateOutput, E>
|
||||
@@ -361,6 +360,15 @@ export type SessionContextInput = { readonly sessionID: Session.ID }
|
||||
export type SessionContextOutput = ReadonlyArray<SessionMessage.Info>
|
||||
export type SessionContextOperation<E = never> = (input: SessionContextInput) => Effect.Effect<SessionContextOutput, E>
|
||||
|
||||
export type SessionDiffInput = {
|
||||
readonly sessionID: Session.ID
|
||||
readonly messageID?: SessionMessage.ID | undefined
|
||||
readonly to?: SessionMessage.ID | undefined
|
||||
readonly context?: number | undefined
|
||||
}
|
||||
export type SessionDiffOutput = ReadonlyArray<FileDiff.Info>
|
||||
export type SessionDiffOperation<E = never> = (input: SessionDiffInput) => Effect.Effect<SessionDiffOutput, E>
|
||||
|
||||
export type SessionInboxListInput = { readonly sessionID: Session.ID }
|
||||
export type SessionInboxListOutput = ReadonlyArray<SessionInbox.Info>
|
||||
export type SessionInboxListOperation<E = never> = (
|
||||
@@ -438,7 +446,6 @@ export type SessionLogOutput =
|
||||
readonly agent?: Agent.ID | undefined
|
||||
readonly model?: Model.Ref | undefined
|
||||
readonly metadata?: Session.Metadata | undefined
|
||||
readonly permissions?: Permission.Ruleset | undefined
|
||||
readonly version: string
|
||||
}
|
||||
}
|
||||
@@ -491,15 +498,6 @@ export type SessionLogOutput =
|
||||
readonly location?: Location.Ref | undefined
|
||||
readonly data: { readonly sessionID: Session.ID; readonly title: string }
|
||||
}
|
||||
| {
|
||||
readonly id: Event.ID
|
||||
readonly created: number
|
||||
readonly metadata?: { readonly [x: string]: unknown } | undefined
|
||||
readonly type: "session.permissions.updated"
|
||||
readonly durable: { readonly aggregateID: string; readonly seq: Event.Seq; readonly version: Event.Version }
|
||||
readonly location?: Location.Ref | undefined
|
||||
readonly data: { readonly sessionID: Session.ID; readonly permissions: Permission.Ruleset }
|
||||
}
|
||||
| {
|
||||
readonly id: Event.ID
|
||||
readonly created: number
|
||||
@@ -1150,6 +1148,7 @@ export interface SessionApi<E = never> {
|
||||
readonly commit: SessionRevertCommitOperation<E>
|
||||
}
|
||||
readonly context: SessionContextOperation<E>
|
||||
readonly diff: SessionDiffOperation<E>
|
||||
readonly inbox: {
|
||||
readonly list: SessionInboxListOperation<E>
|
||||
readonly cancel: SessionInboxCancelOperation<E>
|
||||
@@ -1596,12 +1595,6 @@ export type PermissionReplyOperation<E = never> = (
|
||||
input: PermissionReplyInput,
|
||||
) => Effect.Effect<PermissionReplyOutput, E>
|
||||
|
||||
export type PermissionRulesInput = { readonly sessionID: Session.ID; readonly permissions: Permission.Ruleset }
|
||||
export type PermissionRulesOutput = void
|
||||
export type PermissionRulesOperation<E = never> = (
|
||||
input: PermissionRulesInput,
|
||||
) => Effect.Effect<PermissionRulesOutput, E>
|
||||
|
||||
export interface PermissionApi<E = never> {
|
||||
readonly request: { readonly list: PermissionRequestListOperation<E> }
|
||||
readonly saved: { readonly list: PermissionSavedListOperation<E>; readonly remove: PermissionSavedRemoveOperation<E> }
|
||||
@@ -1609,7 +1602,6 @@ export interface PermissionApi<E = never> {
|
||||
readonly list: PermissionListOperation<E>
|
||||
readonly get: PermissionGetOperation<E>
|
||||
readonly reply: PermissionReplyOperation<E>
|
||||
readonly rules: PermissionRulesOperation<E>
|
||||
}
|
||||
|
||||
export type FileListInput = {
|
||||
|
||||
@@ -68,6 +68,8 @@ import type {
|
||||
SessionRevertCommitOutput,
|
||||
SessionContextInput,
|
||||
SessionContextOutput,
|
||||
SessionDiffInput,
|
||||
SessionDiffOutput,
|
||||
SessionInboxListInput,
|
||||
SessionInboxListOutput,
|
||||
SessionInboxCancelInput,
|
||||
@@ -181,8 +183,6 @@ import type {
|
||||
PermissionGetOutput,
|
||||
PermissionReplyInput,
|
||||
PermissionReplyOutput,
|
||||
PermissionRulesInput,
|
||||
PermissionRulesOutput,
|
||||
FileListInput,
|
||||
FileListOutput,
|
||||
FileFindInput,
|
||||
@@ -397,7 +397,6 @@ const EndpointSessionCreate = (raw: RawClient["server.session"]) => (input?: Ses
|
||||
model: input?.["model"],
|
||||
location: input?.["location"],
|
||||
metadata: input?.["metadata"],
|
||||
permissions: input?.["permissions"],
|
||||
},
|
||||
}).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
@@ -595,6 +594,17 @@ const EndpointSessionContext = (raw: RawClient["server.session"]) => (input: Ses
|
||||
),
|
||||
)
|
||||
|
||||
const EndpointSessionDiff = (raw: RawClient["server.session"]) => (input: SessionDiffInput) =>
|
||||
preserveEffect<SessionDiffOutput>()(
|
||||
raw["session.diff"]({
|
||||
params: { sessionID: input["sessionID"] },
|
||||
query: { messageID: input["messageID"], to: input["to"], context: input["context"] },
|
||||
}).pipe(
|
||||
Effect.mapError(mapClientError),
|
||||
Effect.map((value) => value.data),
|
||||
),
|
||||
)
|
||||
|
||||
const EndpointSessionInboxList = (raw: RawClient["server.session"]) => (input: SessionInboxListInput) =>
|
||||
preserveEffect<SessionInboxListOutput>()(
|
||||
raw["session.inbox.list"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
||||
@@ -734,6 +744,7 @@ const adaptGroupSession = (raw: RawClient["server.session"]) => ({
|
||||
commit: EndpointSessionRevertCommit(raw),
|
||||
},
|
||||
context: EndpointSessionContext(raw),
|
||||
diff: EndpointSessionDiff(raw),
|
||||
inbox: {
|
||||
list: EndpointSessionInboxList(raw),
|
||||
cancel: EndpointSessionInboxCancel(raw),
|
||||
@@ -1148,14 +1159,6 @@ const EndpointPermissionReply = (raw: RawClient["server.permission"]) => (input:
|
||||
}).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const EndpointPermissionRules = (raw: RawClient["server.permission"]) => (input: PermissionRulesInput) =>
|
||||
preserveEffect<PermissionRulesOutput>()(
|
||||
raw["session.permission.rules"]({
|
||||
params: { sessionID: input["sessionID"] },
|
||||
payload: { permissions: input["permissions"] },
|
||||
}).pipe(Effect.mapError(mapClientError)),
|
||||
)
|
||||
|
||||
const adaptGroupPermission = (raw: RawClient["server.permission"]) => ({
|
||||
request: { list: EndpointPermissionRequestList(raw) },
|
||||
saved: { list: EndpointPermissionSavedList(raw), remove: EndpointPermissionSavedRemove(raw) },
|
||||
@@ -1163,7 +1166,6 @@ const adaptGroupPermission = (raw: RawClient["server.permission"]) => ({
|
||||
list: EndpointPermissionList(raw),
|
||||
get: EndpointPermissionGet(raw),
|
||||
reply: EndpointPermissionReply(raw),
|
||||
rules: EndpointPermissionRules(raw),
|
||||
})
|
||||
|
||||
const EndpointFileList = (raw: RawClient["server.fs"]) => (input?: FileListInput) =>
|
||||
|
||||
@@ -62,6 +62,8 @@ import type {
|
||||
SessionRevertCommitOutput,
|
||||
SessionContextInput,
|
||||
SessionContextOutput,
|
||||
SessionDiffInput,
|
||||
SessionDiffOutput,
|
||||
SessionInboxListInput,
|
||||
SessionInboxListOutput,
|
||||
SessionInboxCancelInput,
|
||||
@@ -175,8 +177,6 @@ import type {
|
||||
PermissionGetOutput,
|
||||
PermissionReplyInput,
|
||||
PermissionReplyOutput,
|
||||
PermissionRulesInput,
|
||||
PermissionRulesOutput,
|
||||
FileReadInput,
|
||||
FileReadOutput,
|
||||
FileListInput,
|
||||
@@ -567,7 +567,6 @@ export function make(options: ClientOptions) {
|
||||
model: input?.["model"],
|
||||
location: input?.["location"],
|
||||
metadata: input?.["metadata"],
|
||||
permissions: input?.["permissions"],
|
||||
},
|
||||
successStatus: 200,
|
||||
declaredStatuses: [400, 401],
|
||||
@@ -845,6 +844,18 @@ export function make(options: ClientOptions) {
|
||||
},
|
||||
requestOptions,
|
||||
).then((value) => value.data),
|
||||
diff: (input: SessionDiffInput, requestOptions?: RequestOptions) =>
|
||||
request<{ readonly data: SessionDiffOutput }>(
|
||||
{
|
||||
method: "GET",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/diff`,
|
||||
query: { messageID: input["messageID"], to: input["to"], context: input["context"] },
|
||||
successStatus: 200,
|
||||
declaredStatuses: [400, 401, 404, 500],
|
||||
empty: false,
|
||||
},
|
||||
requestOptions,
|
||||
).then((value) => value.data),
|
||||
inbox: {
|
||||
list: (input: SessionInboxListInput, requestOptions?: RequestOptions) =>
|
||||
request<{ readonly data: SessionInboxListOutput }>(
|
||||
@@ -1569,18 +1580,6 @@ export function make(options: ClientOptions) {
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
rules: (input: PermissionRulesInput, requestOptions?: RequestOptions) =>
|
||||
request<PermissionRulesOutput>(
|
||||
{
|
||||
method: "PUT",
|
||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/permission/rules`,
|
||||
body: { permissions: input["permissions"] },
|
||||
successStatus: 204,
|
||||
declaredStatuses: [400, 401, 404],
|
||||
empty: true,
|
||||
},
|
||||
requestOptions,
|
||||
),
|
||||
},
|
||||
file: {
|
||||
read: (input: FileReadInput, requestOptions?: RequestOptions) =>
|
||||
|
||||
@@ -147,6 +147,14 @@ export type SessionProviderContextProvenance = {
|
||||
endpoint: string
|
||||
}
|
||||
|
||||
export type SessionMessageIdle = {
|
||||
id: string
|
||||
metadata?: { [x: string]: JsonValue }
|
||||
time: { created: number }
|
||||
type: "idle"
|
||||
outcome: "succeeded" | "failed" | "interrupted"
|
||||
}
|
||||
|
||||
export type SessionActive = { type: "running" }
|
||||
|
||||
export type SessionInboxDelivery = "steer" | "queue"
|
||||
@@ -551,6 +559,28 @@ export type InstructionEntryInfo = { key: InstructionEntryKey; value: JsonValue
|
||||
|
||||
export type InstructionEntrySnapshot = Array<{ key: InstructionEntryKey; value: JsonValue; removed: boolean }>
|
||||
|
||||
export type SessionCreated = {
|
||||
id: string
|
||||
created: number
|
||||
metadata?: { [x: string]: any }
|
||||
type: "session.created"
|
||||
durable: { aggregateID: string; seq: number; version: 1 }
|
||||
location?: LocationRef
|
||||
data: {
|
||||
sessionID: string
|
||||
projectID: string
|
||||
location: LocationRef
|
||||
subpath?: string
|
||||
parentID?: string
|
||||
slug: string
|
||||
title?: string
|
||||
agent?: string
|
||||
model?: ModelRef
|
||||
metadata?: SessionMetadata
|
||||
version: string
|
||||
}
|
||||
}
|
||||
|
||||
export type SessionAgentSelected = {
|
||||
id: string
|
||||
created: number
|
||||
@@ -1629,6 +1659,24 @@ export type SessionInboxMove = {
|
||||
delivery: SessionInboxDelivery
|
||||
}
|
||||
|
||||
export type SessionInfo = {
|
||||
id: string
|
||||
parentID?: string
|
||||
fork?: { sessionID: string; boundary: SessionForkBoundary }
|
||||
projectID: string
|
||||
agent?: string
|
||||
model?: ModelRef
|
||||
cost: MoneyUSD
|
||||
tokens: TokenUsageInfo
|
||||
outcome?: "succeeded" | "failed" | "interrupted"
|
||||
time: { created: number; updated: number; idle?: number; viewed?: number; archived?: number }
|
||||
title?: string
|
||||
location: LocationRef
|
||||
subpath?: string
|
||||
metadata?: SessionMetadata
|
||||
revert?: SessionRevert
|
||||
}
|
||||
|
||||
export type SessionRevertStaged = {
|
||||
id: string
|
||||
created: number
|
||||
@@ -1872,58 +1920,6 @@ export type AgentInfo = {
|
||||
permissions: PermissionRuleset
|
||||
}
|
||||
|
||||
export type SessionPermissionsUpdated = {
|
||||
id: string
|
||||
created: number
|
||||
metadata?: { [x: string]: any }
|
||||
type: "session.permissions.updated"
|
||||
durable: { aggregateID: string; seq: number; version: 1 }
|
||||
location?: LocationRef
|
||||
data: { sessionID: string; permissions: PermissionRuleset }
|
||||
}
|
||||
|
||||
export type SessionInfo = {
|
||||
id: string
|
||||
parentID?: string
|
||||
fork?: { sessionID: string; boundary: SessionForkBoundary }
|
||||
projectID: string
|
||||
agent?: string
|
||||
model?: ModelRef
|
||||
cost: MoneyUSD
|
||||
tokens: TokenUsageInfo
|
||||
outcome?: "succeeded" | "failed" | "interrupted"
|
||||
time: { created: number; updated: number; idle?: number; viewed?: number; archived?: number }
|
||||
title?: string
|
||||
location: LocationRef
|
||||
subpath?: string
|
||||
metadata?: SessionMetadata
|
||||
permissions?: PermissionRuleset
|
||||
revert?: SessionRevert
|
||||
}
|
||||
|
||||
export type SessionCreated = {
|
||||
id: string
|
||||
created: number
|
||||
metadata?: { [x: string]: any }
|
||||
type: "session.created"
|
||||
durable: { aggregateID: string; seq: number; version: 1 }
|
||||
location?: LocationRef
|
||||
data: {
|
||||
sessionID: string
|
||||
projectID: string
|
||||
location: LocationRef
|
||||
subpath?: string
|
||||
parentID?: string
|
||||
slug: string
|
||||
title?: string
|
||||
agent?: string
|
||||
model?: ModelRef
|
||||
metadata?: SessionMetadata
|
||||
permissions?: PermissionRuleset
|
||||
version: string
|
||||
}
|
||||
}
|
||||
|
||||
export type ConfigEntry =
|
||||
| {
|
||||
type: "document"
|
||||
@@ -2096,6 +2092,8 @@ export type ConfigEntry =
|
||||
| { type: "agents"; path: string }
|
||||
| { type: "claude"; path: string }
|
||||
|
||||
export type SessionsResponse = { data: Array<SessionInfo>; cursor: { previous?: string | null; next?: string | null } }
|
||||
|
||||
export type SessionInboxUser = {
|
||||
id: string
|
||||
sessionID: string
|
||||
@@ -2150,8 +2148,6 @@ export type FormFields = [FormField, ...Array<FormField>]
|
||||
|
||||
export type FormFields2 = [FormField1, ...Array<FormField1>]
|
||||
|
||||
export type SessionsResponse = { data: Array<SessionInfo>; cursor: { previous?: string | null; next?: string | null } }
|
||||
|
||||
export type SessionInboxInfo = SessionInboxUser | SessionInboxSynthetic | SessionInboxCompaction | SessionInboxMove
|
||||
|
||||
export type SessionInboxEnqueued = {
|
||||
@@ -2206,6 +2202,7 @@ export type SessionMessageInfo =
|
||||
| SessionMessageShell
|
||||
| SessionMessageAssistant
|
||||
| SessionMessageCompaction
|
||||
| SessionMessageIdle
|
||||
|
||||
export type SessionMessageContentUpdated = {
|
||||
id: string
|
||||
@@ -2245,7 +2242,6 @@ export type SessionEventDurable =
|
||||
| SessionModelSelected
|
||||
| SessionMoved
|
||||
| SessionRenamed
|
||||
| SessionPermissionsUpdated
|
||||
| SessionViewed
|
||||
| SessionDeleted
|
||||
| SessionForked
|
||||
@@ -2305,7 +2301,6 @@ export type V2Event =
|
||||
| SessionModelSelected
|
||||
| SessionMoved
|
||||
| SessionRenamed
|
||||
| SessionPermissionsUpdated
|
||||
| SessionViewed
|
||||
| SessionUsageUpdated
|
||||
| SessionDeleted
|
||||
@@ -2818,11 +2813,6 @@ export type SessionCreateInput = {
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly permissions?: ReadonlyArray<{
|
||||
readonly action: string
|
||||
readonly resource: string
|
||||
readonly effect: "allow" | "deny" | "ask"
|
||||
}> | null
|
||||
}["id"]
|
||||
readonly title?: {
|
||||
readonly id?: string | null
|
||||
@@ -2831,11 +2821,6 @@ export type SessionCreateInput = {
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly permissions?: ReadonlyArray<{
|
||||
readonly action: string
|
||||
readonly resource: string
|
||||
readonly effect: "allow" | "deny" | "ask"
|
||||
}> | null
|
||||
}["title"]
|
||||
readonly agent?: {
|
||||
readonly id?: string | null
|
||||
@@ -2844,11 +2829,6 @@ export type SessionCreateInput = {
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly permissions?: ReadonlyArray<{
|
||||
readonly action: string
|
||||
readonly resource: string
|
||||
readonly effect: "allow" | "deny" | "ask"
|
||||
}> | null
|
||||
}["agent"]
|
||||
readonly model?: {
|
||||
readonly id?: string | null
|
||||
@@ -2857,11 +2837,6 @@ export type SessionCreateInput = {
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly permissions?: ReadonlyArray<{
|
||||
readonly action: string
|
||||
readonly resource: string
|
||||
readonly effect: "allow" | "deny" | "ask"
|
||||
}> | null
|
||||
}["model"]
|
||||
readonly location?: {
|
||||
readonly id?: string | null
|
||||
@@ -2870,11 +2845,6 @@ export type SessionCreateInput = {
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly permissions?: ReadonlyArray<{
|
||||
readonly action: string
|
||||
readonly resource: string
|
||||
readonly effect: "allow" | "deny" | "ask"
|
||||
}> | null
|
||||
}["location"]
|
||||
readonly metadata?: {
|
||||
readonly id?: string | null
|
||||
@@ -2883,25 +2853,7 @@ export type SessionCreateInput = {
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly permissions?: ReadonlyArray<{
|
||||
readonly action: string
|
||||
readonly resource: string
|
||||
readonly effect: "allow" | "deny" | "ask"
|
||||
}> | null
|
||||
}["metadata"]
|
||||
readonly permissions?: {
|
||||
readonly id?: string | null
|
||||
readonly title?: string | null
|
||||
readonly agent?: string | null
|
||||
readonly model?: { readonly id: string; readonly providerID: string; readonly variant?: string } | null
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
readonly metadata?: { readonly [x: string]: JsonValue } | null
|
||||
readonly permissions?: ReadonlyArray<{
|
||||
readonly action: string
|
||||
readonly resource: string
|
||||
readonly effect: "allow" | "deny" | "ask"
|
||||
}> | null
|
||||
}["permissions"]
|
||||
}
|
||||
|
||||
export type SessionCreateOutput = { data: SessionInfo }["data"]
|
||||
@@ -2939,11 +2891,6 @@ export type SessionImportInput = {
|
||||
readonly location: { readonly directory: string; readonly workspaceID?: string }
|
||||
readonly subpath?: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly permissions?: ReadonlyArray<{
|
||||
readonly action: string
|
||||
readonly resource: string
|
||||
readonly effect: "allow" | "deny" | "ask"
|
||||
}>
|
||||
readonly revert?: {
|
||||
readonly messageID: string
|
||||
readonly partID?: string
|
||||
@@ -3214,6 +3161,13 @@ export type SessionImportInput = {
|
||||
}
|
||||
}
|
||||
)
|
||||
| {
|
||||
readonly id: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly time: { readonly created: number }
|
||||
readonly type: "idle"
|
||||
readonly outcome: "succeeded" | "failed" | "interrupted"
|
||||
}
|
||||
>
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
}["info"]
|
||||
@@ -3249,11 +3203,6 @@ export type SessionImportInput = {
|
||||
readonly location: { readonly directory: string; readonly workspaceID?: string }
|
||||
readonly subpath?: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly permissions?: ReadonlyArray<{
|
||||
readonly action: string
|
||||
readonly resource: string
|
||||
readonly effect: "allow" | "deny" | "ask"
|
||||
}>
|
||||
readonly revert?: {
|
||||
readonly messageID: string
|
||||
readonly partID?: string
|
||||
@@ -3524,6 +3473,13 @@ export type SessionImportInput = {
|
||||
}
|
||||
}
|
||||
)
|
||||
| {
|
||||
readonly id: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly time: { readonly created: number }
|
||||
readonly type: "idle"
|
||||
readonly outcome: "succeeded" | "failed" | "interrupted"
|
||||
}
|
||||
>
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
}["messages"]
|
||||
@@ -3559,11 +3515,6 @@ export type SessionImportInput = {
|
||||
readonly location: { readonly directory: string; readonly workspaceID?: string }
|
||||
readonly subpath?: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly permissions?: ReadonlyArray<{
|
||||
readonly action: string
|
||||
readonly resource: string
|
||||
readonly effect: "allow" | "deny" | "ask"
|
||||
}>
|
||||
readonly revert?: {
|
||||
readonly messageID: string
|
||||
readonly partID?: string
|
||||
@@ -3834,6 +3785,13 @@ export type SessionImportInput = {
|
||||
}
|
||||
}
|
||||
)
|
||||
| {
|
||||
readonly id: string
|
||||
readonly metadata?: { readonly [x: string]: JsonValue }
|
||||
readonly time: { readonly created: number }
|
||||
readonly type: "idle"
|
||||
readonly outcome: "succeeded" | "failed" | "interrupted"
|
||||
}
|
||||
>
|
||||
readonly location?: { readonly directory: string; readonly workspaceID?: string } | null
|
||||
}["location"]
|
||||
@@ -4323,6 +4281,27 @@ export type SessionContextInput = { readonly sessionID: { readonly sessionID: st
|
||||
|
||||
export type SessionContextOutput = { data: Array<SessionMessageInfo> }["data"]
|
||||
|
||||
export type SessionDiffInput = {
|
||||
readonly sessionID: { readonly sessionID: string }["sessionID"]
|
||||
readonly messageID?: {
|
||||
readonly messageID?: string | undefined
|
||||
readonly to?: string | undefined
|
||||
readonly context?: number | undefined
|
||||
}["messageID"]
|
||||
readonly to?: {
|
||||
readonly messageID?: string | undefined
|
||||
readonly to?: string | undefined
|
||||
readonly context?: number | undefined
|
||||
}["to"]
|
||||
readonly context?: {
|
||||
readonly messageID?: string | undefined
|
||||
readonly to?: string | undefined
|
||||
readonly context?: number | undefined
|
||||
}["context"]
|
||||
}
|
||||
|
||||
export type SessionDiffOutput = { data: Array<FileDiffInfo> }["data"]
|
||||
|
||||
export type SessionInboxListInput = { readonly sessionID: { readonly sessionID: string }["sessionID"] }
|
||||
|
||||
export type SessionInboxListOutput = { data: Array<SessionInboxInfo> }["data"]
|
||||
@@ -5825,19 +5804,6 @@ export type PermissionReplyInput = {
|
||||
|
||||
export type PermissionReplyOutput = void
|
||||
|
||||
export type PermissionRulesInput = {
|
||||
readonly sessionID: { readonly sessionID: string }["sessionID"]
|
||||
readonly permissions: {
|
||||
readonly permissions: ReadonlyArray<{
|
||||
readonly action: string
|
||||
readonly resource: string
|
||||
readonly effect: "allow" | "deny" | "ask"
|
||||
}>
|
||||
}["permissions"]
|
||||
}
|
||||
|
||||
export type PermissionRulesOutput = void
|
||||
|
||||
export type FileReadInput = {
|
||||
readonly location?: {
|
||||
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
||||
|
||||
@@ -695,10 +695,6 @@ export function createData(config: CreateDataInput) {
|
||||
})
|
||||
return
|
||||
}
|
||||
case "session.permissions.updated":
|
||||
if (store.session.info[event.data.sessionID])
|
||||
setStore("session", "info", event.data.sessionID, "permissions", event.data.permissions)
|
||||
return
|
||||
case "session.moved": {
|
||||
const current = store.session.info[event.data.sessionID]
|
||||
if (current) {
|
||||
@@ -1028,6 +1024,18 @@ export function createData(config: CreateDataInput) {
|
||||
if (currentAssistant) currentAssistant.retry = undefined
|
||||
})
|
||||
if (event.type === "session.execution.interrupted" && event.data.reason === "shutdown") return
|
||||
// Mirror the projected idle marker so turn boundaries match before the next message read.
|
||||
message.insert(event.data.sessionID, {
|
||||
id: messageIDFromEvent(event.id),
|
||||
type: "idle",
|
||||
outcome:
|
||||
event.type === "session.execution.succeeded"
|
||||
? "succeeded"
|
||||
: event.type === "session.execution.failed"
|
||||
? "failed"
|
||||
: "interrupted",
|
||||
time: { created: event.created },
|
||||
})
|
||||
// An event can overtake the first read; queue a revalidation when that read is still active.
|
||||
if (!store.session.info[event.data.sessionID] && !sync.has(`session:${event.data.sessionID}`)) return
|
||||
result.session.invalidate(event.data.sessionID)
|
||||
|
||||
@@ -9,8 +9,7 @@ standard-library surface that programs can use today, plus concrete gaps that ma
|
||||
- Intentional boundaries are not listed as compatibility work.
|
||||
|
||||
When behavior changes, update this file and the tests in the same change. The implementation and tests remain the
|
||||
ultimate source of truth. Upstream test262 files run verbatim from `test/test262`; a failing file is listed in
|
||||
`test/test262/skipped.txt` and its gap is an unchecked item here (see `test/test262/README.md`).
|
||||
ultimate source of truth.
|
||||
|
||||
## Source and execution model
|
||||
|
||||
@@ -26,10 +25,6 @@ ultimate source of truth. Upstream test262 files run verbatim from `test/test262
|
||||
- [x] The global `search(...)` built-in: synchronous tool discovery that counts as an admitted tool call and is
|
||||
shadowable by program declarations like other globals.
|
||||
- [x] Cooperative timeout, an optional total tool-call limit, output bounding, and unrestricted tool-call concurrency.
|
||||
- [ ] Strict-mode early errors: duplicate parameter names, `yield` as an identifier, and a trailing comma after a
|
||||
rest parameter are accepted unless the program itself begins with `"use strict"`.
|
||||
- [ ] Valid JavaScript rejected by TypeScript transpilation before interpretation, such as `in` inside a destructuring
|
||||
default in a `for...of` head and Unicode-escaped keywords.
|
||||
|
||||
## Values and literals
|
||||
|
||||
@@ -69,11 +64,6 @@ ultimate source of truth. Upstream test262 files run verbatim from `test/test262
|
||||
- [x] Array binding and assignment destructuring from strings, Maps, Sets, URLSearchParams, custom synchronous
|
||||
iterators, and synchronous generators, including stepwise elisions/rest and `IteratorClose` on early completion
|
||||
or binding/default failure.
|
||||
- [ ] Object destructuring from primitives follows ToObject (`const { length } = "abc"`, `const {} = 1`); non-object
|
||||
sources are rejected.
|
||||
- [ ] Destructuring a key that member access resolves through the owning built-in, such as
|
||||
`const { constructor } = error`, reads `undefined`.
|
||||
- [ ] Member expressions as `for...in` targets (`for (x.y in obj)`).
|
||||
|
||||
## Statements and control flow
|
||||
|
||||
@@ -121,12 +111,6 @@ ultimate source of truth. Upstream test262 files run verbatim from `test/test262
|
||||
- [ ] User-defined constructor calls.
|
||||
- [ ] `Function.prototype.call`, `apply`, and `bind` for CodeMode functions.
|
||||
- [ ] Classes and private fields.
|
||||
- [ ] `name` and `length` properties of functions, including names inferred from bindings and destructuring defaults.
|
||||
- [ ] A named function expression's name is not bound inside its own body.
|
||||
- [ ] Redeclaring a function in the same scope is rejected; in JavaScript the last declaration wins.
|
||||
- [ ] A line terminator between `async function` and the function name.
|
||||
- [ ] Async generator functions evaluate parameter defaults and destructuring at the first `next()` rather than at the
|
||||
call, so their errors are not thrown synchronously.
|
||||
- [x] Synchronous and async generator declarations/expressions, `yield`, and `yield*`, including lazy bodies,
|
||||
`next(value)`, `return(value)`, `throw(value)`, exhaustion, promise adoption, async request ordering,
|
||||
`try`/`catch`/`finally`, and sync/async iterator symbols. Async `yield*` awaits values while adapting a sync
|
||||
@@ -170,8 +154,6 @@ ultimate source of truth. Upstream test262 files run verbatim from `test/test262
|
||||
- [x] Plain, arithmetic, bitwise, and logical assignment operators.
|
||||
- [x] Property deletion on plain data objects and arrays, including computed and optional forms; deleting an array index
|
||||
creates a hole without changing its length.
|
||||
- [ ] Operators, `switch` discriminants, and coercion helpers such as `String` and `isNaN` applied to functions and
|
||||
namespaces; JavaScript coerces them, the interpreter rejects non-data operands.
|
||||
|
||||
## Promises and tools
|
||||
|
||||
@@ -244,7 +226,6 @@ ultimate source of truth. Upstream test262 files run verbatim from `test/test262
|
||||
- [x] `Object.is` for supported data values.
|
||||
- [x] `Object.groupBy` over finite collections and custom synchronous iterators/generators, with string-key coercion
|
||||
and null-prototype results.
|
||||
- [ ] `Object.prototype` methods on values: `toString`, `toLocaleString`, `valueOf`, and `hasOwnProperty`.
|
||||
|
||||
## Arrays
|
||||
|
||||
@@ -268,13 +249,6 @@ ultimate source of truth. Upstream test262 files run verbatim from `test/test262
|
||||
`1`; arbitrary array-property assignment remains unsupported.
|
||||
- [x] `Array.prototype.sort` preserves trailing holes, while `toSorted` densifies holes into `undefined` elements,
|
||||
like JavaScript.
|
||||
- [ ] Assigning `length` to truncate or extend an array.
|
||||
- [ ] Non-index own properties on arrays (`arr.foo = 1`, `arr.constructor = null`).
|
||||
- [ ] Argument coercion for `indexOf`, `lastIndexOf`, `includes`, `fill`, `flat`, `copyWithin`, and the `join`
|
||||
separator: JavaScript applies ToIntegerOrInfinity/ToString (including `valueOf`, strings, and `undefined`), the
|
||||
interpreter requires numbers and strings; `includes()`/`indexOf()` with no argument should search for
|
||||
`undefined`.
|
||||
- [ ] Iterator objects from `keys`, `values`, and `entries` with a live `next()`.
|
||||
|
||||
## Strings
|
||||
|
||||
@@ -417,5 +391,3 @@ ultimate source of truth. Upstream test262 files run verbatim from `test/test262
|
||||
- [x] Caught errors do not distinguish user throws, interpreter failures, and tool failures; a program sees one
|
||||
Error-shaped value with `name` and `message` in `catch`, rejection handlers, and `Promise.allSettled` reasons.
|
||||
This is deliberate: the program should handle a failure the same way regardless of where it originated.
|
||||
- [ ] Failures raised by the interpreter itself carry the generic `Error` name where JavaScript throws a `TypeError`,
|
||||
`RangeError`, or `ReferenceError`, so `e instanceof TypeError` and `e.constructor === TypeError` are false.
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
// Copies the manifest's test262 directories from a local checkout into test/test262, verbatim.
|
||||
// Files needing unsupported flags, features, or harness includes, or whose code crosses one of the
|
||||
// interpreter's intentional boundaries, are not copied, so the vendored tree is exactly what
|
||||
// test/test262.test.ts runs.
|
||||
//
|
||||
// Usage: bun run script/sync-test262.ts /path/to/test262
|
||||
import path from "node:path"
|
||||
import { rm } from "node:fs/promises"
|
||||
|
||||
type Frontmatter = { flags?: Array<string>; features?: Array<string>; includes?: Array<string> }
|
||||
|
||||
const root = path.resolve(import.meta.dir, "../test/test262")
|
||||
const manifest = (await Bun.file(path.join(root, "manifest.json")).json()) as {
|
||||
revision: string
|
||||
directories: Array<string>
|
||||
harness: Array<string>
|
||||
flags: Array<string>
|
||||
features: Array<string>
|
||||
boundaries: Record<string, string>
|
||||
}
|
||||
const boundaries = Object.entries(manifest.boundaries).map(([name, pattern]) => [name, new RegExp(pattern)] as const)
|
||||
const checkout = process.argv[2]
|
||||
if (checkout === undefined) {
|
||||
console.error("usage: bun run script/sync-test262.ts /path/to/test262")
|
||||
process.exit(1)
|
||||
}
|
||||
const head = (await Bun.$`git -C ${checkout} rev-parse HEAD`.text()).trim()
|
||||
if (head !== manifest.revision) {
|
||||
console.error(`checkout is at ${head}; manifest pins ${manifest.revision}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const excluded = new Map<string, number>()
|
||||
let copied = 0
|
||||
for (const dir of manifest.directories) {
|
||||
await rm(path.join(root, dir), { recursive: true, force: true })
|
||||
const from = path.join(checkout, "test", dir)
|
||||
for await (const file of new Bun.Glob("**/*.js").scan({ cwd: from })) {
|
||||
if (file.endsWith("_FIXTURE.js")) continue
|
||||
const source = await Bun.file(path.join(from, file)).text()
|
||||
const start = source.indexOf("/*---")
|
||||
const end = source.indexOf("---*/", start)
|
||||
const meta = start === -1 ? {} : (Bun.YAML.parse(source.slice(start + 5, end)) as Frontmatter)
|
||||
const code = start === -1 ? source : source.slice(end + 5)
|
||||
const reason =
|
||||
meta.flags?.find((flag) => manifest.flags.includes(flag)) ??
|
||||
meta.features?.find((feature) => manifest.features.includes(feature)) ??
|
||||
meta.includes?.find((include) => !manifest.harness.includes(include)) ??
|
||||
boundaries.find(([, pattern]) => pattern.test(code))?.[0]
|
||||
if (reason !== undefined) {
|
||||
excluded.set(reason, (excluded.get(reason) ?? 0) + 1)
|
||||
continue
|
||||
}
|
||||
await Bun.write(path.join(root, dir, file), Bun.file(path.join(from, file)))
|
||||
copied++
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`copied ${copied} files`)
|
||||
for (const [reason, count] of [...excluded].sort((a, b) => b[1] - a[1])) {
|
||||
console.log(` excluded ${String(count).padStart(5)} ${reason}`)
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
// Runs every vendored test262 file, including skipped ones, and groups failures by cause. Pass
|
||||
// --write to regenerate test/test262/skipped.txt from the current failures.
|
||||
//
|
||||
// Usage: bun run script/test262-report.ts [--write] [path-prefix]
|
||||
import path from "node:path"
|
||||
import { root, run, skipped } from "../test/test262/run.js"
|
||||
|
||||
const write = process.argv.includes("--write")
|
||||
const prefix = process.argv.slice(2).find((arg) => !arg.startsWith("--")) ?? ""
|
||||
const files = [...new Bun.Glob("**/*.js").scanSync({ cwd: root })].filter((file) => file.startsWith(prefix)).sort()
|
||||
|
||||
const failures: Array<{ file: string; reason: string }> = []
|
||||
const recovered: Array<string> = []
|
||||
for (const file of files) {
|
||||
const outcome = await run(file)
|
||||
if (outcome.status === "fail") failures.push({ file, reason: outcome.reason })
|
||||
if (outcome.status === "pass" && skipped.has(file)) recovered.push(file)
|
||||
}
|
||||
|
||||
// Collapse a reason to the part that identifies the cause rather than the test.
|
||||
const bucket = (reason: string) => {
|
||||
const syntax = reason.match(/Syntax '([A-Za-z]+)' is not supported/)
|
||||
if (syntax) return `unsupported syntax ${syntax[1]}`
|
||||
if (reason.startsWith("expected ")) return reason.replace(/ but got .*/, " but the program ran")
|
||||
return reason
|
||||
.replace(/^(\$DONE: |ExecutionFailure: |InvalidDataValue: |ParseError: |Uncaught: |Test262Error: |Error: )+/, "")
|
||||
.replace(/ \(line \d+, col \d+\)/, "")
|
||||
.replace(/^[\w$]+\.(\w+) is not a function/, ".$1 is not a function")
|
||||
.replace(/^[\w$]+ cannot be constructed/, "… cannot be constructed")
|
||||
.replace(/'[^']*'/g, "'…'")
|
||||
.slice(0, 100)
|
||||
}
|
||||
|
||||
const buckets = new Map<string, Array<string>>()
|
||||
for (const failure of failures) {
|
||||
const key = bucket(failure.reason)
|
||||
buckets.set(key, [...(buckets.get(key) ?? []), failure.file])
|
||||
}
|
||||
|
||||
console.log(`${files.length - failures.length} pass, ${failures.length} fail of ${files.length}\n`)
|
||||
for (const [key, list] of [...buckets].sort((a, b) => b[1].length - a[1].length)) {
|
||||
console.log(`${String(list.length).padStart(5)} ${key}`)
|
||||
for (const file of list.slice(0, 3)) console.log(` ${file}`)
|
||||
if (list.length > 3) console.log(` … ${list.length - 3} more`)
|
||||
}
|
||||
if (recovered.length > 0) {
|
||||
console.log(`\n${recovered.length} skipped files pass now; remove them from skipped.txt:`)
|
||||
for (const file of recovered) console.log(` ${file}`)
|
||||
}
|
||||
|
||||
if (write) {
|
||||
const lines = failures.map((failure) => `${failure.file} # ${bucket(failure.reason)}`)
|
||||
await Bun.write(path.join(root, "skipped.txt"), `${lines.join("\n")}\n`)
|
||||
console.log(`\nwrote ${lines.length} entries to skipped.txt`)
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import type { DataValue, Diagnostic, ResolvedExecutionLimits, Result } from "../
|
||||
import { toData } from "../data.js"
|
||||
import { ToolRuntime } from "../tool-runtime.js"
|
||||
import { normalizeError } from "./errors.js"
|
||||
import type { Host } from "./globals.js"
|
||||
import { InterpreterRuntimeError } from "./model.js"
|
||||
import { PromiseRuntime } from "./promises.js"
|
||||
import { Runtime } from "./runtime.js"
|
||||
@@ -17,7 +16,6 @@ export const executeProgram = <R>(
|
||||
prepared: ToolRuntime.Prepared<R>,
|
||||
limits: ResolvedExecutionLimits,
|
||||
hooks: ToolRuntime.ToolCallHooks<R>,
|
||||
extraGlobals?: (host: Host<R>) => ReadonlyArray<readonly [string, unknown]>,
|
||||
): Effect.Effect<Result, never, R> => {
|
||||
if (code.trim().length === 0) {
|
||||
return Effect.succeed({
|
||||
@@ -41,14 +39,7 @@ export const executeProgram = <R>(
|
||||
Effect.gen(function* () {
|
||||
const program = parseProgram(code)
|
||||
const promises = new PromiseRuntime<R>(scope)
|
||||
const value = yield* new Runtime<R>(
|
||||
tools.execute,
|
||||
tools.search,
|
||||
tools.keys,
|
||||
promises,
|
||||
logs,
|
||||
extraGlobals,
|
||||
).run(program)
|
||||
const value = yield* new Runtime<R>(tools.execute, tools.search, tools.keys, promises, logs).run(program)
|
||||
const result = toData(value, "Execution result", "result") as DataValue
|
||||
returned = { value: result, promises }
|
||||
const warnings = yield* promises.interrupt()
|
||||
|
||||
@@ -66,7 +66,7 @@ import {
|
||||
unsupportedSyntax,
|
||||
} from "./model.js"
|
||||
import { caughtErrorValue } from "./errors.js"
|
||||
import { globals, type Host } from "./globals.js"
|
||||
import { globals } from "./globals.js"
|
||||
import { HostFunction, HostNamespace } from "./host.js"
|
||||
import { invokeIntrinsic } from "./methods.js"
|
||||
import { preserveConsumerError, type Runner } from "./runner.js"
|
||||
@@ -285,7 +285,6 @@ export class Runtime<R> {
|
||||
readonly toolKeys: (path: ReadonlyArray<string>) => ReadonlyArray<string>,
|
||||
readonly promises: PromiseRuntime<R>,
|
||||
readonly logs: Array<string> = [],
|
||||
extraGlobals: (host: Host<R>) => ReadonlyArray<readonly [string, unknown]> = () => [],
|
||||
) {
|
||||
const globalScope = new Map<string, Binding>()
|
||||
// Calling back into the program never reads frame state, so any frame serves; the root is always alive.
|
||||
@@ -296,7 +295,7 @@ export class Runtime<R> {
|
||||
settlePromise: (promise) => this.root.settlePromise(promise),
|
||||
syncIterator: (value, node) => this.root.syncIterator(value, node),
|
||||
}
|
||||
this.builtins = new Map([...globals(this), ...extraGlobals(this)])
|
||||
this.builtins = new Map(globals(this))
|
||||
for (const [name, value] of this.builtins) globalScope.set(name, { mutable: false, value })
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@ import { coerceToString } from "./value.js"
|
||||
// WebIDL DOMString conversion: a missing argument is a TypeError, anything else stringifies.
|
||||
const base64 = (name: "atob" | "btoa") =>
|
||||
sync(name, (args, node) => {
|
||||
if (args.length === 0)
|
||||
throw new InterpreterRuntimeError(`${name} requires 1 argument (a string)`, node).as("TypeError")
|
||||
if (args.length === 0) {
|
||||
throw new InterpreterRuntimeError(`${name} requires 1 argument, but only 0 were provided.`, node).as("TypeError")
|
||||
}
|
||||
const input = coerceToString(args[0])
|
||||
try {
|
||||
return name === "atob" ? atob(input) : btoa(input)
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Runs the test262 files vendored under test/test262 (see test/test262/README.md) verbatim.
|
||||
* Files listed in test/test262/skipped.txt fail on a known interpreter gap and are skipped;
|
||||
* `bun run script/test262-report.ts` shows current gaps and which skipped files pass again.
|
||||
* Licensed under test/LICENSE.test262.
|
||||
*/
|
||||
import { test } from "bun:test"
|
||||
import { root, run, skipped } from "./test262/run.js"
|
||||
|
||||
for (const file of [...new Bun.Glob("**/*.js").scanSync({ cwd: root })].sort()) {
|
||||
const define = skipped.has(file) ? test.skip : test
|
||||
define(
|
||||
file,
|
||||
async () => {
|
||||
const outcome = await run(file)
|
||||
if (outcome.status === "fail") throw new Error(outcome.reason)
|
||||
},
|
||||
10_000,
|
||||
)
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
# test262
|
||||
|
||||
Upstream [test262](https://github.com/tc39/test262) files, vendored byte-for-byte and run verbatim by
|
||||
`test/test262.test.ts`. Licensed under `test/LICENSE.test262`.
|
||||
|
||||
## Layout
|
||||
|
||||
- `manifest.json` — the pinned upstream revision, which upstream directories are vendored, and what is left out.
|
||||
- `built-ins/`, `language/` — the vendored files, mirroring upstream `test/`.
|
||||
- `skipped.txt` — vendored files that fail on a known interpreter gap, one `path # reason` per line. They are
|
||||
skipped, and each gap is listed as unchecked in `interpreter-support.md`.
|
||||
- `run.ts` — runs one file: prepends `"use strict"`, provides the harness (`assert`, `Test262Error`,
|
||||
`compareArray`, `$DONE`, `$DONOTEVALUATE`) as host globals, and interprets the file's frontmatter (`negative`,
|
||||
`flags: [async]`).
|
||||
|
||||
## What is not vendored
|
||||
|
||||
`script/sync-test262.ts` skips a file when its frontmatter declares a `flags`, `features`, or `includes` value the
|
||||
manifest marks unsupported, or when its code matches one of the manifest's `boundaries` patterns. Boundaries are
|
||||
intentional limits of the interpreter, not compatibility work: classes, `this`, `arguments`, prototype objects,
|
||||
property descriptors, accessors, boxed primitives, sloppy mode, `eval`, `Symbol()`, and the `$262` host API. If one
|
||||
of those decisions changes, delete its entry and re-sync; the tests are upstream, not lost.
|
||||
|
||||
## Commands
|
||||
|
||||
```sh
|
||||
bun run script/sync-test262.ts /path/to/test262 # re-copy at the pinned revision; edit manifest.json to change scope
|
||||
bun run script/test262-report.ts [--write] [dir] # run everything, group failures by cause; --write regenerates skipped.txt
|
||||
bun test test/test262.test.ts # what CI runs
|
||||
```
|
||||
|
||||
When a fix makes skipped files pass, the report lists them so they can be removed from `skipped.txt`, and the
|
||||
matching gap in `interpreter-support.md` is checked in the same change.
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.concat
|
||||
description: >
|
||||
Behavior when `constructor` property is neither an Object nor undefined
|
||||
info: |
|
||||
1. Let O be ? ToObject(this value).
|
||||
2. Let A be ? ArraySpeciesCreate(O, 0).
|
||||
|
||||
9.4.2.3 ArraySpeciesCreate
|
||||
|
||||
[...]
|
||||
5. Let C be ? Get(originalArray, "constructor").
|
||||
[...]
|
||||
9. If IsConstructor(C) is false, throw a TypeError exception.
|
||||
---*/
|
||||
|
||||
var a = [];
|
||||
|
||||
a.constructor = null;
|
||||
assert.throws(TypeError, function() {
|
||||
a.concat();
|
||||
}, 'a.concat() throws a TypeError exception');
|
||||
|
||||
a = [];
|
||||
a.constructor = 1;
|
||||
assert.throws(TypeError, function() {
|
||||
a.concat();
|
||||
}, 'a.concat() throws a TypeError exception');
|
||||
|
||||
a = [];
|
||||
a.constructor = 'string';
|
||||
assert.throws(TypeError, function() {
|
||||
a.concat();
|
||||
}, 'a.concat() throws a TypeError exception');
|
||||
|
||||
a = [];
|
||||
a.constructor = true;
|
||||
assert.throws(TypeError, function() {
|
||||
a.concat();
|
||||
}, 'a.concat() throws a TypeError exception');
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
end argument is coerced to an integer values.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
11. If end is undefined, let relativeEnd be len; else let relativeEnd be
|
||||
ToInteger(end).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(1, 0, null), [0, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(1, 0, null) must return [0, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(1, 0, NaN), [0, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(1, 0, NaN) must return [0, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(1, 0, false), [0, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(1, 0, false) must return [0, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(1, 0, true), [0, 0, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(1, 0, true) must return [0, 0, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(1, 0, '-2'), [0, 0, 1, 3],
|
||||
'[0, 1, 2, 3].copyWithin(1, 0, "-2") must return [0, 0, 1, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(1, 0, -2.5), [0, 0, 1, 3],
|
||||
'[0, 1, 2, 3].copyWithin(1, 0, -2.5) must return [0, 0, 1, 3]'
|
||||
);
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
// Copyright (C) 2019 Google. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
SECURITY: start argument is coerced to an integer value
|
||||
and side effects change the length of the array so that
|
||||
the target is out of bounds
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
8. Let relativeStart be ToInteger(start).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
|
||||
// make a long integer Array
|
||||
function longDenseArray(){
|
||||
var a = [0];
|
||||
for(var i = 0; i < 1024; i++){
|
||||
a[i] = i;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
function shorten(){
|
||||
currArray.length = 20;
|
||||
return 1;
|
||||
}
|
||||
|
||||
var array = longDenseArray();
|
||||
array.length = 20;
|
||||
for(var i = 0; i < 19; i++){
|
||||
array[i+1000] = array[i+1];
|
||||
}
|
||||
|
||||
var currArray = longDenseArray();
|
||||
|
||||
assert.compareArray(
|
||||
currArray.copyWithin(1000, {valueOf: shorten}), array,
|
||||
'currArray.copyWithin(1000, {valueOf: shorten}) returns array'
|
||||
);
|
||||
Vendored
-56
@@ -1,56 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
start argument is coerced to an integer value.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
8. Let relativeStart be ToInteger(start).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(1, undefined), [0, 0, 1, 2],
|
||||
'[0, 1, 2, 3].copyWithin(1, undefined) must return [0, 0, 1, 2]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(1, false), [0, 0, 1, 2],
|
||||
'[0, 1, 2, 3].copyWithin(1, false) must return [0, 0, 1, 2]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(1, NaN), [0, 0, 1, 2],
|
||||
'[0, 1, 2, 3].copyWithin(1, NaN) must return [0, 0, 1, 2]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(1, null), [0, 0, 1, 2],
|
||||
'[0, 1, 2, 3].copyWithin(1, null) must return [0, 0, 1, 2]'
|
||||
);
|
||||
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, true), [1, 2, 3, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, true) must return [1, 2, 3, 3]'
|
||||
);
|
||||
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, '1'), [1, 2, 3, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, "1") must return [1, 2, 3, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(1, 0.5), [0, 0, 1, 2],
|
||||
'[0, 1, 2, 3].copyWithin(1, 0.5) must return [0, 0, 1, 2]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, 1.5), [1, 2, 3, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, 1.5) must return [1, 2, 3, 3]'
|
||||
);
|
||||
Vendored
-61
@@ -1,61 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
target argument is coerced to an integer value.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
5. Let relativeTarget be ToInteger(target).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(undefined, 1), [1, 2, 3, 3],
|
||||
'[0, 1, 2, 3].copyWithin(undefined, 1) must return [1, 2, 3, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(false, 1), [1, 2, 3, 3],
|
||||
'[0, 1, 2, 3].copyWithin(false, 1) must return [1, 2, 3, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(NaN, 1), [1, 2, 3, 3],
|
||||
'[0, 1, 2, 3].copyWithin(NaN, 1) must return [1, 2, 3, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(null, 1), [1, 2, 3, 3],
|
||||
'[0, 1, 2, 3].copyWithin(null, 1) must return [1, 2, 3, 3]'
|
||||
);
|
||||
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(true, 0), [0, 0, 1, 2],
|
||||
'[0, 1, 2, 3].copyWithin(true, 0) must return [0, 0, 1, 2]'
|
||||
);
|
||||
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin('1', 0), [0, 0, 1, 2],
|
||||
'[0, 1, 2, 3].copyWithin("1", 0) must return [0, 0, 1, 2]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0.5, 1), [1, 2, 3, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0.5, 1) must return [1, 2, 3, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(1.5, 0), [0, 0, 1, 2],
|
||||
'[0, 1, 2, 3].copyWithin(1.5, 0) must return [0, 0, 1, 2]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin({}, 1), [1, 2, 3, 3],
|
||||
'[0, 1, 2, 3].copyWithin({}, 1) must return [1, 2, 3, 3]'
|
||||
);
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Loop from each property, even empty holes.
|
||||
---*/
|
||||
|
||||
var arr = [0, 1, , , 1];
|
||||
|
||||
arr.copyWithin(0, 1, 4);
|
||||
|
||||
assert.sameValue(arr.length, 5);
|
||||
assert.sameValue(arr[0], 1);
|
||||
assert.sameValue(arr[4], 1);
|
||||
assert.sameValue(arr.hasOwnProperty(1), false);
|
||||
assert.sameValue(arr.hasOwnProperty(2), false);
|
||||
assert.sameValue(arr.hasOwnProperty(3), false);
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Set values with negative end argument.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
11. If end is undefined, let relativeEnd be len; else let relativeEnd be
|
||||
ToInteger(end).
|
||||
12. ReturnIfAbrupt(relativeEnd).
|
||||
13. If relativeEnd < 0, let final be max((len + relativeEnd),0); else let
|
||||
final be min(relativeEnd, len).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, 1, -1), [1, 2, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, 1, -1) must return [1, 2, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4].copyWithin(2, 0, -1), [0, 1, 0, 1, 2],
|
||||
'[0, 1, 2, 3, 4].copyWithin(2, 0, -1) must return [0, 1, 0, 1, 2]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4].copyWithin(1, 2, -2), [0, 2, 2, 3, 4],
|
||||
'[0, 1, 2, 3, 4].copyWithin(1, 2, -2) must return [0, 2, 2, 3, 4]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, -2, -1), [2, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, -2, -1) must return [2, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4].copyWithin(2, -2, -1), [0, 1, 3, 3, 4],
|
||||
'[0, 1, 2, 3, 4].copyWithin(2, -2, -1) must return [0, 1, 3, 3, 4]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(-3, -2, -1), [0, 2, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(-3, -2, -1) must return [0, 2, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4].copyWithin(-2, -3, -1), [0, 1, 2, 2, 3],
|
||||
'[0, 1, 2, 3, 4].copyWithin(-2, -3, -1) must return [0, 1, 2, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4].copyWithin(-5, -2, -1), [3, 1, 2, 3, 4],
|
||||
'[0, 1, 2, 3, 4].copyWithin(-5, -2, -1) must return [3, 1, 2, 3, 4]'
|
||||
);
|
||||
Vendored
-68
@@ -1,68 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Set values with negative out of bounds end argument.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
11. If end is undefined, let relativeEnd be len; else let relativeEnd be
|
||||
ToInteger(end).
|
||||
12. ReturnIfAbrupt(relativeEnd).
|
||||
13. If relativeEnd < 0, let final be max((len + relativeEnd),0); else let
|
||||
final be min(relativeEnd, len).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, 1, -10), [0, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, 1, -10) must return [0, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[1, 2, 3, 4, 5].copyWithin(0, 1, -Infinity), [1, 2, 3, 4, 5],
|
||||
'[1, 2, 3, 4, 5].copyWithin(0, 1, -Infinity) must return [1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, -2, -10), [0, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, -2, -10) must return [0, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[1, 2, 3, 4, 5].copyWithin(0, -2, -Infinity), [1, 2, 3, 4, 5],
|
||||
'[1, 2, 3, 4, 5].copyWithin(0, -2, -Infinity) must return [1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, -9, -10), [0, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, -9, -10) must return [0, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[1, 2, 3, 4, 5].copyWithin(0, -9, -Infinity), [1, 2, 3, 4, 5],
|
||||
'[1, 2, 3, 4, 5].copyWithin(0, -9, -Infinity) must return [1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(-3, -2, -10), [0, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(-3, -2, -10) must return [0, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[1, 2, 3, 4, 5].copyWithin(-3, -2, -Infinity), [1, 2, 3, 4, 5],
|
||||
'[1, 2, 3, 4, 5].copyWithin(-3, -2, -Infinity) must return [1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(-7, -8, -9), [0, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(-7, -8, -9) must return [0, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[1, 2, 3, 4, 5].copyWithin(-7, -8, -Infinity), [1, 2, 3, 4, 5],
|
||||
'[1, 2, 3, 4, 5].copyWithin(-7, -8, -Infinity) must return [1, 2, 3, 4, 5]'
|
||||
);
|
||||
Vendored
-57
@@ -1,57 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Set values with out of bounds negative start argument.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
10. If relativeStart < 0, let from be max((len + relativeStart),0); else let
|
||||
from be min(relativeStart, len).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, -10), [0, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, -10) must return [0, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[1, 2, 3, 4, 5].copyWithin(0, -Infinity), [1, 2, 3, 4, 5],
|
||||
'[1, 2, 3, 4, 5].copyWithin(0, -Infinity) must return [1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4].copyWithin(2, -10), [0, 1, 0, 1, 2],
|
||||
'[0, 1, 2, 3, 4].copyWithin(2, -10) must return [0, 1, 0, 1, 2]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[1, 2, 3, 4, 5].copyWithin(2, -Infinity), [1, 2, 1, 2, 3],
|
||||
'[1, 2, 3, 4, 5].copyWithin(2, -Infinity) must return [1, 2, 1, 2, 3]'
|
||||
);
|
||||
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4].copyWithin(10, -10), [0, 1, 2, 3, 4],
|
||||
'[0, 1, 2, 3, 4].copyWithin(10, -10) must return [0, 1, 2, 3, 4]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[1, 2, 3, 4, 5].copyWithin(10, -Infinity), [1, 2, 3, 4, 5],
|
||||
'[1, 2, 3, 4, 5].copyWithin(10, -Infinity) must return [1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(-9, -10), [0, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(-9, -10) must return [0, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[1, 2, 3, 4, 5].copyWithin(-9, -Infinity), [1, 2, 3, 4, 5],
|
||||
'[1, 2, 3, 4, 5].copyWithin(-9, -Infinity) must return [1, 2, 3, 4, 5]'
|
||||
);
|
||||
packages/codemode/test/test262/built-ins/Array/prototype/copyWithin/negative-out-of-bounds-target.js
Vendored
-35
@@ -1,35 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Set values with out of bounds negative target argument.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
7. If relativeTarget < 0, let to be max((len + relativeTarget),0); else let to
|
||||
be min(relativeTarget, len).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(-10, 0), [0, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(-10, 0) must return [0, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[1, 2, 3, 4, 5].copyWithin(-Infinity, 0), [1, 2, 3, 4, 5],
|
||||
'[1, 2, 3, 4, 5].copyWithin(-Infinity, 0) must return [1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4].copyWithin(-10, 2), [2, 3, 4, 3, 4],
|
||||
'[0, 1, 2, 3, 4].copyWithin(-10, 2) must return [2, 3, 4, 3, 4]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[1, 2, 3, 4, 5].copyWithin(-Infinity, 2), [3, 4, 5, 4, 5],
|
||||
'[1, 2, 3, 4, 5].copyWithin(-Infinity, 2) must return [3, 4, 5, 4, 5]'
|
||||
);
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Set values with negative start argument.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
10. If relativeStart < 0, let from be max((len + relativeStart),0); else let
|
||||
from be min(relativeStart, len).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, -1), [3, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, -1) must return [3, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4].copyWithin(2, -2), [0, 1, 3, 4, 4],
|
||||
'[0, 1, 2, 3, 4].copyWithin(2, -2) must return [0, 1, 3, 4, 4]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4].copyWithin(1, -2), [0, 3, 4, 3, 4],
|
||||
'[0, 1, 2, 3, 4].copyWithin(1, -2) must return [0, 3, 4, 3, 4]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(-1, -2), [0, 1, 2, 2],
|
||||
'[0, 1, 2, 3].copyWithin(-1, -2) must return [0, 1, 2, 2]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4].copyWithin(-2, -3), [0, 1, 2, 2, 3],
|
||||
'[0, 1, 2, 3, 4].copyWithin(-2, -3) must return [0, 1, 2, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4].copyWithin(-5, -2), [3, 4, 2, 3, 4],
|
||||
'[0, 1, 2, 3, 4].copyWithin(-5, -2) must return [3, 4, 2, 3, 4]'
|
||||
);
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Set values with negative target argument.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
7. If relativeTarget < 0, let to be max((len + relativeTarget),0); else let to
|
||||
be min(relativeTarget, len).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(-1, 0), [0, 1, 2, 0],
|
||||
'[0, 1, 2, 3].copyWithin(-1, 0) must return [0, 1, 2, 0]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4].copyWithin(-2, 2), [0, 1, 2, 2, 3],
|
||||
'[0, 1, 2, 3, 4].copyWithin(-2, 2) must return [0, 1, 2, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(-1, 2), [0, 1, 2, 2],
|
||||
'[0, 1, 2, 3].copyWithin(-1, 2) must return [0, 1, 2, 2]'
|
||||
);
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Max value of end position is the this.length.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
7. If relativeTarget < 0, let to be max((len + relativeTarget),0); else let to
|
||||
be min(relativeTarget, len).
|
||||
...
|
||||
10. If relativeStart < 0, let from be max((len + relativeStart),0); else let
|
||||
from be min(relativeStart, len).
|
||||
11. If end is undefined, let relativeEnd be len; else let relativeEnd be
|
||||
ToInteger(end).
|
||||
...
|
||||
14. Let count be min(final-from, len-to).
|
||||
15. If from<to and to<from+count
|
||||
a. Let direction be -1.
|
||||
b. Let from be from + count -1.
|
||||
c. Let to be to + count -1.
|
||||
16. Else,
|
||||
a. Let direction = 1.
|
||||
17. Repeat, while count > 0
|
||||
...
|
||||
a. If fromPresent is true, then
|
||||
i. Let fromVal be Get(O, fromKey).
|
||||
...
|
||||
iii. Let setStatus be Set(O, toKey, fromVal, true).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, 1, 6), [1, 2, 3, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, 1, 6) must return [1, 2, 3, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, 1, Infinity), [1, 2, 3, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, 1, Infinity) must return [1, 2, 3, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(1, 3, 6), [0, 3, 4, 5, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(1, 3, 6) must return [0, 3, 4, 5, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(1, 3, Infinity), [0, 3, 4, 5, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(1, 3, Infinity) must return [0, 3, 4, 5, 4, 5]'
|
||||
);
|
||||
-105
@@ -1,105 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Max values of target and start positions are this.length.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
7. If relativeTarget < 0, let to be max((len + relativeTarget),0); else let to
|
||||
be min(relativeTarget, len).
|
||||
...
|
||||
10. If relativeStart < 0, let from be max((len + relativeStart),0); else let
|
||||
from be min(relativeStart, len).
|
||||
11. If end is undefined, let relativeEnd be len; else let relativeEnd be
|
||||
ToInteger(end).
|
||||
...
|
||||
14. Let count be min(final-from, len-to).
|
||||
15. If from<to and to<from+count
|
||||
...
|
||||
16. Else,
|
||||
a. Let direction = 1.
|
||||
17. Repeat, while count > 0
|
||||
...
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(6, 0), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(6, 0) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(7, 0), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(7, 0) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(Infinity, 0), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(Infinity, 0) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(6, 2), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(6, 2) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(7, 2), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(7, 2) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(Infinity, 2), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(Infinity, 2) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(0, 6), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(0, 6) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(0, 7), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(0, 7) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(0, Infinity), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(0, Infinity) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(2, 6), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(2, 6) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(1, 7), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(1, 7) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(3, Infinity), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(3, Infinity) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(6, 6), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(6, 6) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(10, 10), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(10, 10) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(Infinity, Infinity), [0, 1, 2, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(Infinity, Infinity) must return [0, 1, 2, 3, 4, 5]'
|
||||
);
|
||||
packages/codemode/test/test262/built-ins/Array/prototype/copyWithin/non-negative-target-and-start.js
Vendored
-52
@@ -1,52 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Copy values with non-negative target and start positions.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
7. If relativeTarget < 0, let to be max((len + relativeTarget),0); else let to
|
||||
be min(relativeTarget, len).
|
||||
...
|
||||
10. If relativeStart < 0, let from be max((len + relativeStart),0); else let
|
||||
from be min(relativeStart, len).
|
||||
11. If end is undefined, let relativeEnd be len; else let relativeEnd be
|
||||
ToInteger(end).
|
||||
...
|
||||
14. Let count be min(final-from, len-to).
|
||||
15. If from<to and to<from+count
|
||||
...
|
||||
16. Else,
|
||||
a. Let direction = 1.
|
||||
17. Repeat, while count > 0
|
||||
...
|
||||
a. If fromPresent is true, then
|
||||
i. Let fromVal be Get(O, fromKey).
|
||||
...
|
||||
iii. Let setStatus be Set(O, toKey, fromVal, true).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
['a', 'b', 'c', 'd', 'e', 'f'].copyWithin(0, 0),
|
||||
['a', 'b', 'c', 'd', 'e', 'f']
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
['a', 'b', 'c', 'd', 'e', 'f'].copyWithin(0, 2),
|
||||
['c', 'd', 'e', 'f', 'e', 'f']
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
['a', 'b', 'c', 'd', 'e', 'f'].copyWithin(3, 0),
|
||||
['a', 'b', 'c', 'a', 'b', 'c']
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(1, 4),
|
||||
[0, 4, 5, 3, 4, 5]
|
||||
);
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Copy values with non-negative target, start and end positions.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
7. If relativeTarget < 0, let to be max((len + relativeTarget),0); else let to
|
||||
be min(relativeTarget, len).
|
||||
...
|
||||
10. If relativeStart < 0, let from be max((len + relativeStart),0); else let
|
||||
from be min(relativeStart, len).
|
||||
11. If end is undefined, let relativeEnd be len; else let relativeEnd be
|
||||
ToInteger(end).
|
||||
...
|
||||
14. Let count be min(final-from, len-to).
|
||||
15. If from<to and to<from+count
|
||||
a. Let direction be -1.
|
||||
b. Let from be from + count -1.
|
||||
c. Let to be to + count -1.
|
||||
16. Else,
|
||||
a. Let direction = 1.
|
||||
17. Repeat, while count > 0
|
||||
...
|
||||
a. If fromPresent is true, then
|
||||
i. Let fromVal be Get(O, fromKey).
|
||||
...
|
||||
iii. Let setStatus be Set(O, toKey, fromVal, true).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, 0, 0), [0, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, 0, 0) must return [0, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, 0, 2), [0, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, 0, 2) must return [0, 1, 2, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, 1, 2), [1, 1, 2, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, 1, 2) must return [1, 1, 2, 3]'
|
||||
);
|
||||
|
||||
/*
|
||||
* 15. If from<to and to<from+count
|
||||
* a. Let direction be -1.
|
||||
* b. Let from be from + count -1.
|
||||
* c. Let to be to + count -1.
|
||||
*
|
||||
* 0 < 1, 1 < 0 + 2
|
||||
* direction = -1
|
||||
* from = 0 + 2 - 1
|
||||
* to = 1 + 2 - 1
|
||||
*/
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(1, 0, 2), [0, 0, 1, 3],
|
||||
'[0, 1, 2, 3].copyWithin(1, 0, 2) must return [0, 0, 1, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3, 4, 5].copyWithin(1, 3, 5), [0, 3, 4, 3, 4, 5],
|
||||
'[0, 1, 2, 3, 4, 5].copyWithin(1, 3, 5) must return [0, 3, 4, 3, 4, 5]'
|
||||
);
|
||||
Vendored
-24
@@ -1,24 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Return abrupt from ToInteger(end).
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
11. If end is undefined, let relativeEnd be len; else let relativeEnd be
|
||||
ToInteger(end).
|
||||
12. ReturnIfAbrupt(relativeEnd).
|
||||
...
|
||||
---*/
|
||||
|
||||
var o1 = {
|
||||
valueOf: function() {
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
assert.throws(Test262Error, function() {
|
||||
[].copyWithin(0, 0, o1);
|
||||
});
|
||||
Vendored
-23
@@ -1,23 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Return abrupt from ToInteger(start).
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
8. Let relativeStart be ToInteger(start).
|
||||
9. ReturnIfAbrupt(relativeStart).
|
||||
...
|
||||
---*/
|
||||
|
||||
var o1 = {
|
||||
valueOf: function() {
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
assert.throws(Test262Error, function() {
|
||||
[].copyWithin(0, o1);
|
||||
});
|
||||
Vendored
-23
@@ -1,23 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
Return abrupt from ToInteger(target).
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
5. Let relativeTarget be ToInteger(target).
|
||||
6. ReturnIfAbrupt(relativeTarget).
|
||||
...
|
||||
---*/
|
||||
|
||||
var o1 = {
|
||||
valueOf: function() {
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
assert.throws(Test262Error, function() {
|
||||
[].copyWithin(o1);
|
||||
});
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.copywithin
|
||||
description: >
|
||||
If `end` is undefined, set final position to `this.length`.
|
||||
info: |
|
||||
22.1.3.3 Array.prototype.copyWithin (target, start [ , end ] )
|
||||
|
||||
...
|
||||
11. If end is undefined, let relativeEnd be len; else let relativeEnd be
|
||||
ToInteger(end).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, 1, undefined), [1, 2, 3, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, 1, undefined) must return [1, 2, 3, 3]'
|
||||
);
|
||||
|
||||
assert.compareArray(
|
||||
[0, 1, 2, 3].copyWithin(0, 1), [1, 2, 3, 3],
|
||||
'[0, 1, 2, 3].copyWithin(0, 1) must return [1, 2, 3, 3]'
|
||||
);
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.entries
|
||||
description: >
|
||||
New items in the array are accessible via iteration until iterator is "done".
|
||||
info: |
|
||||
The method should return a valid iterator with the context as the
|
||||
IteratedObject. When an item is added to the array after the iterator is
|
||||
created but before the iterator is "done" (as defined by 22.1.5.2.1) the
|
||||
new item should be accessible via iteration.
|
||||
---*/
|
||||
|
||||
var array = [];
|
||||
var iterator = array.entries();
|
||||
var result;
|
||||
|
||||
array.push('a');
|
||||
|
||||
result = iterator.next();
|
||||
assert.sameValue(result.done, false, 'First result `done` flag');
|
||||
assert.sameValue(result.value[0], 0, 'First result `value` (array key)');
|
||||
assert.sameValue(result.value[1], 'a', 'First result `value (array value)');
|
||||
assert.sameValue(result.value.length, 2, 'First result `value` (length)');
|
||||
|
||||
result = iterator.next();
|
||||
assert.sameValue(result.done, true, 'Exhausted result `done` flag');
|
||||
assert.sameValue(result.value, undefined, 'Exhausted result `value`');
|
||||
|
||||
array.push('b');
|
||||
|
||||
result = iterator.next();
|
||||
assert.sameValue(result.done, true, 'Exhausted result `done` flag (after push)');
|
||||
assert.sameValue(result.value, undefined, 'Exhausted result `value` (after push)');
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.entries
|
||||
description: >
|
||||
The return is a valid iterator with the array's numeric properties.
|
||||
info: |
|
||||
22.1.3.4 Array.prototype.entries ( )
|
||||
|
||||
1. Let O be ToObject(this value).
|
||||
2. ReturnIfAbrupt(O).
|
||||
3. Return CreateArrayIterator(O, "key+value").
|
||||
---*/
|
||||
|
||||
var array = ['a', 'b', 'c'];
|
||||
var iterator = array.entries();
|
||||
var result;
|
||||
|
||||
result = iterator.next();
|
||||
assert.sameValue(result.done, false, 'First result `done` flag');
|
||||
assert.sameValue(result.value[0], 0, 'First result `value` (array key)');
|
||||
assert.sameValue(result.value[1], 'a', 'First result `value` (array value)');
|
||||
assert.sameValue(result.value.length, 2, 'First result `value` (length)');
|
||||
|
||||
result = iterator.next();
|
||||
assert.sameValue(result.done, false, 'Second result `done` flag');
|
||||
assert.sameValue(result.value[0], 1, 'Second result `value` (array key)');
|
||||
assert.sameValue(result.value[1], 'b', 'Second result `value` (array value)');
|
||||
assert.sameValue(result.value.length, 2, 'Second result `value` (length)');
|
||||
|
||||
result = iterator.next();
|
||||
assert.sameValue(result.done, false, 'Third result `done` flag');
|
||||
assert.sameValue(result.value[0], 2, 'Third result `value` (array key)');
|
||||
assert.sameValue(result.value[1], 'c', 'Third result `value` (array value)');
|
||||
assert.sameValue(result.value.length, 2, 'Third result `value` (length)');
|
||||
|
||||
result = iterator.next();
|
||||
assert.sameValue(result.done, true, 'Exhausted result `done` flag');
|
||||
assert.sameValue(result.value, undefined, 'Exhausted result `value`');
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
es5id: 15.4.4.16-4-1
|
||||
description: Array.prototype.every throws TypeError if callbackfn is undefined
|
||||
---*/
|
||||
|
||||
var arr = new Array(10);
|
||||
assert.throws(TypeError, function() {
|
||||
arr.every();
|
||||
});
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
es5id: 15.4.4.16-4-12
|
||||
description: Array.prototype.every - 'callbackfn' is a function
|
||||
---*/
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
return val > 10;
|
||||
}
|
||||
|
||||
assert.sameValue([11, 9].every(callbackfn), false, '[11, 9].every(callbackfn)');
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
es5id: 15.4.4.16-4-3
|
||||
description: Array.prototype.every throws TypeError if callbackfn is null
|
||||
---*/
|
||||
|
||||
var arr = new Array(10);
|
||||
assert.throws(TypeError, function() {
|
||||
arr.every(null);
|
||||
});
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
es5id: 15.4.4.16-4-4
|
||||
description: Array.prototype.every throws TypeError if callbackfn is boolean
|
||||
---*/
|
||||
|
||||
var arr = new Array(10);
|
||||
assert.throws(TypeError, function() {
|
||||
arr.every(true);
|
||||
});
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
es5id: 15.4.4.16-4-5
|
||||
description: Array.prototype.every throws TypeError if callbackfn is number
|
||||
---*/
|
||||
|
||||
var arr = new Array(10);
|
||||
assert.throws(TypeError, function() {
|
||||
arr.every(5);
|
||||
});
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
es5id: 15.4.4.16-4-6
|
||||
description: Array.prototype.every throws TypeError if callbackfn is string
|
||||
---*/
|
||||
|
||||
var arr = new Array(10);
|
||||
assert.throws(TypeError, function() {
|
||||
arr.every("abc");
|
||||
});
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
es5id: 15.4.4.16-4-7
|
||||
description: >
|
||||
Array.prototype.every throws TypeError if callbackfn is Object
|
||||
without a Call internal method
|
||||
---*/
|
||||
|
||||
var arr = new Array(10);
|
||||
assert.throws(TypeError, function() {
|
||||
arr.every({});
|
||||
});
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every considers new elements added to array after
|
||||
the call
|
||||
---*/
|
||||
|
||||
var calledForThree = false;
|
||||
|
||||
function callbackfn(val, Idx, obj)
|
||||
{
|
||||
arr[2] = 3;
|
||||
if (val == 3)
|
||||
calledForThree = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
var arr = [1, 2, , 4, 5];
|
||||
|
||||
var res = arr.every(callbackfn);
|
||||
|
||||
assert(calledForThree, 'calledForThree !== true');
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every considers new value of elements in array
|
||||
after the call
|
||||
---*/
|
||||
|
||||
function callbackfn(val, Idx, obj)
|
||||
{
|
||||
arr[4] = 6;
|
||||
if (val < 6)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
var arr = [1, 2, 3, 4, 5];
|
||||
|
||||
|
||||
assert.sameValue(arr.every(callbackfn), false, 'arr.every(callbackfn)');
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every doesn't visit deleted elements in array
|
||||
after the call
|
||||
---*/
|
||||
|
||||
function callbackfn(val, Idx, obj)
|
||||
{
|
||||
delete arr[2];
|
||||
if (val == 3)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
var arr = [1, 2, 3, 4, 5];
|
||||
|
||||
|
||||
assert.sameValue(arr.every(callbackfn), true, 'arr.every(callbackfn)');
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every doesn't visit deleted elements when
|
||||
Array.length is decreased
|
||||
---*/
|
||||
|
||||
function callbackfn(val, Idx, obj)
|
||||
{
|
||||
arr.length = 3;
|
||||
if (val < 4)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
var arr = [1, 2, 3, 4, 6];
|
||||
|
||||
|
||||
assert.sameValue(arr.every(callbackfn), true, 'arr.every(callbackfn)');
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every doesn't consider newly added elements in
|
||||
sparse array
|
||||
---*/
|
||||
|
||||
function callbackfn(val, Idx, obj)
|
||||
{
|
||||
arr[1000] = 3;
|
||||
if (val < 3)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
var arr = new Array(10);
|
||||
arr[1] = 1;
|
||||
arr[2] = 2;
|
||||
|
||||
|
||||
assert.sameValue(arr.every(callbackfn), true, 'arr.every(callbackfn)');
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - Deleting the array itself within the
|
||||
callbackfn of Array.prototype.every is successful once
|
||||
Array.prototype.every is called for all elements
|
||||
---*/
|
||||
|
||||
var o = new Object();
|
||||
o.arr = [1, 2, 3, 4, 5];
|
||||
|
||||
function callbackfn(val, Idx, obj) {
|
||||
delete o.arr;
|
||||
if (val === Idx + 1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(o.arr.every(callbackfn), 'o.arr.every(callbackfn) !== true');
|
||||
assert.sameValue(o.hasOwnProperty("arr"), false, 'o.hasOwnProperty("arr")');
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - callbackfn not called for indexes never
|
||||
been assigned values
|
||||
---*/
|
||||
|
||||
var callCnt = 0.;
|
||||
|
||||
function callbackfn(val, Idx, obj)
|
||||
{
|
||||
callCnt++;
|
||||
return true;
|
||||
}
|
||||
|
||||
var arr = new Array(10);
|
||||
arr[1] = undefined;
|
||||
arr.every(callbackfn);
|
||||
|
||||
assert.sameValue(callCnt, 1, 'callCnt');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - element to be retrieved is own data
|
||||
property on an Array
|
||||
---*/
|
||||
|
||||
var called = 0;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
called++;
|
||||
return val === 11;
|
||||
}
|
||||
|
||||
assert([11].every(callbackfn), '[11].every(callbackfn) !== true');
|
||||
assert.sameValue(called, 1, 'called');
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: Array.prototype.every - callbackfn called with correct parameters
|
||||
---*/
|
||||
|
||||
function callbackfn(val, Idx, obj)
|
||||
{
|
||||
if (obj[Idx] === val)
|
||||
return true;
|
||||
}
|
||||
|
||||
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
|
||||
|
||||
assert.sameValue(arr.every(callbackfn), true, 'arr.every(callbackfn)');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - callbackfn is called with 1 formal
|
||||
parameter
|
||||
---*/
|
||||
|
||||
var called = 0;
|
||||
|
||||
function callbackfn(val) {
|
||||
called++;
|
||||
return val > 10;
|
||||
}
|
||||
|
||||
assert([11, 12].every(callbackfn), '[11, 12].every(callbackfn) !== true');
|
||||
assert.sameValue(called, 2, 'called');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - callbackfn is called with 3 formal
|
||||
parameter
|
||||
---*/
|
||||
|
||||
var called = 0;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
called++;
|
||||
return val > 10 && obj[idx] === val;
|
||||
}
|
||||
|
||||
assert([11, 12, 13].every(callbackfn), '[11, 12, 13].every(callbackfn) !== true');
|
||||
assert.sameValue(called, 3, 'called');
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every immediately returns false if callbackfn
|
||||
returns false
|
||||
---*/
|
||||
|
||||
var callCnt = 0;
|
||||
|
||||
function callbackfn(val, idx, obj)
|
||||
{
|
||||
callCnt++;
|
||||
if (idx > 5)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
|
||||
|
||||
assert.sameValue(arr.every(callbackfn), false, 'arr.every(callbackfn)');
|
||||
assert.sameValue(callCnt, 7, 'callCnt');
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - k values are passed in ascending numeric
|
||||
order
|
||||
---*/
|
||||
|
||||
var arr = [0, 1, 2, 3, 4, 5];
|
||||
var lastIdx = 0;
|
||||
var called = 0;
|
||||
|
||||
function callbackfn(val, idx, o) {
|
||||
called++;
|
||||
if (lastIdx !== idx) {
|
||||
return false;
|
||||
} else {
|
||||
lastIdx++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
assert(arr.every(callbackfn), 'arr.every(callbackfn) !== true');
|
||||
assert.sameValue(arr.length, called, 'arr.length');
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - k values are accessed during each
|
||||
iteration and not prior to starting the loop on an Array
|
||||
---*/
|
||||
|
||||
var called = 0;
|
||||
var kIndex = [];
|
||||
|
||||
//By below way, we could verify that k would be setted as 0, 1, ..., length - 1 in order, and each value will be setted one time.
|
||||
function callbackfn(val, idx, obj) {
|
||||
called++;
|
||||
//Each position should be visited one time, which means k is accessed one time during iterations.
|
||||
if (typeof kIndex[idx] === "undefined") {
|
||||
//when current position is visited, its previous index should has been visited.
|
||||
if (idx !== 0 && typeof kIndex[idx - 1] === "undefined") {
|
||||
return false;
|
||||
}
|
||||
kIndex[idx] = 1;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
assert([11, 12, 13, 14].every(callbackfn, undefined), '[11, 12, 13, 14].every(callbackfn, undefined) !== true');
|
||||
assert.sameValue(called, 4, 'called');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - callbackfn is called with 0 formal
|
||||
parameter
|
||||
---*/
|
||||
|
||||
var called = 0;
|
||||
|
||||
function callbackfn() {
|
||||
called++;
|
||||
return true;
|
||||
}
|
||||
|
||||
assert([11, 12].every(callbackfn), '[11, 12].every(callbackfn) !== true');
|
||||
assert.sameValue(called, 2, 'called');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is a number
|
||||
(value is Infinity)
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
assert([11].every(callbackfn), '[11].every(callbackfn) !== true');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is a number
|
||||
(value is -Infinity)
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return -Infinity;
|
||||
}
|
||||
|
||||
assert([11].every(callbackfn), '[11].every(callbackfn) !== true');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is a number
|
||||
(value is NaN)
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return NaN;
|
||||
}
|
||||
|
||||
assert.sameValue([11].every(callbackfn), false, '[11].every(callbackfn)');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is an empty
|
||||
string
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return "";
|
||||
}
|
||||
|
||||
assert.sameValue([11].every(callbackfn), false, '[11].every(callbackfn)');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is a non-empty
|
||||
string
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return "non-empty string";
|
||||
}
|
||||
|
||||
assert([11].every(callbackfn), '[11].every(callbackfn) !== true');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is a Function
|
||||
object
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return function() {};
|
||||
}
|
||||
|
||||
assert([11].every(callbackfn), '[11].every(callbackfn) !== true');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is an Array
|
||||
object
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return [];
|
||||
}
|
||||
|
||||
assert([11].every(callbackfn), '[11].every(callbackfn) !== true');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is the Math
|
||||
object
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return Math;
|
||||
}
|
||||
|
||||
assert([11].every(callbackfn), '[11].every(callbackfn) !== true');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: Array.prototype.every - return value of callbackfn is a Date object
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return new Date(0);
|
||||
}
|
||||
|
||||
assert([11].every(callbackfn), '[11].every(callbackfn) !== true');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is a RegExp
|
||||
object
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return new RegExp();
|
||||
}
|
||||
|
||||
assert([11].every(callbackfn), '[11].every(callbackfn) !== true');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is the JSON
|
||||
object
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return JSON;
|
||||
}
|
||||
|
||||
assert([11].every(callbackfn), '[11].every(callbackfn) !== true');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is an Error
|
||||
object
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return new EvalError();
|
||||
}
|
||||
|
||||
assert([11].every(callbackfn), '[11].every(callbackfn) !== true');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is a number
|
||||
(value is 0)
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert.sameValue([11].every(callbackfn), false, '[11].every(callbackfn)');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is a number
|
||||
(value is +0)
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return +0;
|
||||
}
|
||||
|
||||
assert.sameValue([11].every(callbackfn), false, '[11].every(callbackfn)');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is a nunmber
|
||||
(value is -0)
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return -0;
|
||||
}
|
||||
|
||||
assert.sameValue([11].every(callbackfn), false, '[11].every(callbackfn)');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is a number
|
||||
(value is positive number)
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return 5;
|
||||
}
|
||||
|
||||
assert([11].every(callbackfn), '[11].every(callbackfn) !== true');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every - return value of callbackfn is a number
|
||||
(value is negative number)
|
||||
---*/
|
||||
|
||||
var accessed = false;
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
accessed = true;
|
||||
return -5;
|
||||
}
|
||||
|
||||
assert([11].every(callbackfn), '[11].every(callbackfn) !== true');
|
||||
assert(accessed, 'accessed !== true');
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: Array.prototype.every returns true if 'length' is 0 (empty array)
|
||||
---*/
|
||||
|
||||
function cb() {}
|
||||
var i = [].every(cb);
|
||||
|
||||
assert.sameValue(i, true, 'i');
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every returns true when all calls to callbackfn
|
||||
return true
|
||||
---*/
|
||||
|
||||
var callCnt = 0;
|
||||
|
||||
function callbackfn(val, idx, obj)
|
||||
{
|
||||
callCnt++;
|
||||
return true;
|
||||
}
|
||||
|
||||
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
|
||||
|
||||
assert.sameValue(arr.every(callbackfn), true, 'arr.every(callbackfn)');
|
||||
assert.sameValue(callCnt, 10, 'callCnt');
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: >
|
||||
Array.prototype.every doesn't mutate the array on which it is
|
||||
called on
|
||||
---*/
|
||||
|
||||
function callbackfn(val, idx, obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var arr = [1, 2, 3, 4, 5];
|
||||
arr.every(callbackfn);
|
||||
|
||||
assert.sameValue(arr[0], 1, 'arr[0]');
|
||||
assert.sameValue(arr[1], 2, 'arr[1]');
|
||||
assert.sameValue(arr[2], 3, 'arr[2]');
|
||||
assert.sameValue(arr[3], 4, 'arr[3]');
|
||||
assert.sameValue(arr[4], 5, 'arr[4]');
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.every
|
||||
description: Array.prototype.every doesn't visit expandos
|
||||
---*/
|
||||
|
||||
var callCnt = 0;
|
||||
|
||||
function callbackfn(val, idx, obj)
|
||||
{
|
||||
callCnt++;
|
||||
return true;
|
||||
}
|
||||
|
||||
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
arr["i"] = 10;
|
||||
arr[true] = 11;
|
||||
|
||||
|
||||
assert.sameValue(arr.every(callbackfn), true, 'arr.every(callbackfn)');
|
||||
assert.sameValue(callCnt, 10, 'callCnt');
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.fill
|
||||
description: >
|
||||
Fills elements from coerced to Integer `start` and `end` values
|
||||
info: |
|
||||
Array.prototype.fill ( _value_ [ , _start_ [ , _end_ ] ] )
|
||||
|
||||
3. Let _relativeStart_ be ? ToIntegerOrInfinity(_start_).
|
||||
4. If _relativeStart_ = -∞, let _k_ be 0.
|
||||
5. Else if _relativeStart_ < 0, let _k_ be max(_len_ + _relativeStart_, 0).
|
||||
|
||||
7. If _end_ is *undefined*, let _relativeEnd_ be _len_; else let _relativeEnd_ be ? ToIntegerOrInfinity(_end_).
|
||||
8. If _relativeEnd_ = -∞, let _final_ be 0.
|
||||
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray([0, 0].fill(1, undefined), [1, 1],
|
||||
'[0, 0].fill(1, undefined) must return [1, 1]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, 0, undefined), [1, 1],
|
||||
'[0, 0].fill(1, 0, undefined) must return [1, 1]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, null), [1, 1],
|
||||
'[0, 0].fill(1, null) must return [1, 1]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, 0, null), [0, 0],
|
||||
'[0, 0].fill(1, 0, null) must return [0, 0]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, true), [0, 1],
|
||||
'[0, 0].fill(1, true) must return [0, 1]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, 0, true), [1, 0],
|
||||
'[0, 0].fill(1, 0, true) must return [1, 0]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, false), [1, 1],
|
||||
'[0, 0].fill(1, false) must return [1, 1]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, 0, false), [0, 0],
|
||||
'[0, 0].fill(1, 0, false) must return [0, 0]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, NaN), [1, 1],
|
||||
'[0, 0].fill(1, NaN) must return [1, 1]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, 0, NaN), [0, 0],
|
||||
'[0, 0].fill(1, 0, NaN) must return [0, 0]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, '1'), [0, 1],
|
||||
'[0, 0].fill(1, "1") must return [0, 1]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, 0, '1'), [1, 0],
|
||||
'[0, 0].fill(1, 0, "1") must return [1, 0]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, 1.5), [0, 1],
|
||||
'[0, 0].fill(1, 1.5) must return [0, 1]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, 0, 1.5), [1, 0],
|
||||
'[0, 0].fill(1, 0, 1.5) must return [1, 0]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, Number.NEGATIVE_INFINITY, 1), [1, 0],
|
||||
'[0, 0].fill(1, Number.NEGATIVE_INFINITY, 1) must return [1, 0]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0].fill(1, 0, Number.NEGATIVE_INFINITY), [0, 0],
|
||||
'[0, 0].fill(1, 0, Number.NEGATIVE_INFINITY) must return [0, 0]'
|
||||
);
|
||||
Vendored
-38
@@ -1,38 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.fill
|
||||
description: >
|
||||
Fills all the elements from a with a custom start and end indexes.
|
||||
info: |
|
||||
22.1.3.6 Array.prototype.fill (value [ , start [ , end ] ] )
|
||||
|
||||
...
|
||||
7. If relativeStart < 0, let k be max((len + relativeStart),0); else let k be
|
||||
min(relativeStart, len).
|
||||
8. If end is undefined, let relativeEnd be len; else let relativeEnd be
|
||||
ToInteger(end).
|
||||
9. ReturnIfAbrupt(relativeEnd).
|
||||
10. If relativeEnd < 0, let final be max((len + relativeEnd),0); else let
|
||||
final be min(relativeEnd, len).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray([0, 0, 0].fill(8, 1, 2), [0, 8, 0], '[0, 0, 0].fill(8, 1, 2) must return [0, 8, 0]');
|
||||
assert.compareArray(
|
||||
[0, 0, 0, 0, 0].fill(8, -3, 4),
|
||||
[0, 0, 8, 8, 0],
|
||||
'[0, 0, 0, 0, 0].fill(8, -3, 4) must return [0, 0, 8, 8, 0]'
|
||||
);
|
||||
assert.compareArray(
|
||||
[0, 0, 0, 0, 0].fill(8, -2, -1),
|
||||
[0, 0, 0, 8, 0],
|
||||
'[0, 0, 0, 0, 0].fill(8, -2, -1) must return [0, 0, 0, 8, 0]'
|
||||
);
|
||||
assert.compareArray(
|
||||
[0, 0, 0, 0, 0].fill(8, -1, -3),
|
||||
[0, 0, 0, 0, 0],
|
||||
'[0, 0, 0, 0, 0].fill(8, -1, -3) must return [0, 0, 0, 0, 0]'
|
||||
);
|
||||
assert.compareArray([, , , , 0].fill(8, 1, 3), [, 8, 8, , 0], '[, , , , 0].fill(8, 1, 3) must return [, 8, 8, , 0]');
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.fill
|
||||
description: >
|
||||
Fills all the elements from a with a custom start index.
|
||||
info: |
|
||||
22.1.3.6 Array.prototype.fill (value [ , start [ , end ] ] )
|
||||
|
||||
...
|
||||
8. If end is undefined, let relativeEnd be len; else let relativeEnd be
|
||||
ToInteger(end).
|
||||
9. ReturnIfAbrupt(relativeEnd).
|
||||
10. If relativeEnd < 0, let final be max((len + relativeEnd),0); else let
|
||||
final be min(relativeEnd, len).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray([0, 0, 0].fill(8, 0, 1), [8, 0, 0],
|
||||
'[0, 0, 0].fill(8, 0, 1) must return [8, 0, 0]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0, 0].fill(8, 0, -1), [8, 8, 0],
|
||||
'[0, 0, 0].fill(8, 0, -1) must return [8, 8, 0]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0, 0].fill(8, 0, 5), [8, 8, 8],
|
||||
'[0, 0, 0].fill(8, 0, 5) must return [8, 8, 8]'
|
||||
);
|
||||
Vendored
-27
@@ -1,27 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.fill
|
||||
description: >
|
||||
Fills all the elements from a with a custom start index.
|
||||
info: |
|
||||
22.1.3.6 Array.prototype.fill (value [ , start [ , end ] ] )
|
||||
|
||||
...
|
||||
7. If relativeStart < 0, let k be max((len + relativeStart),0); else let k be
|
||||
min(relativeStart, len).
|
||||
...
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray([0, 0, 0].fill(8, 1), [0, 8, 8],
|
||||
'[0, 0, 0].fill(8, 1) must return [0, 8, 8]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0, 0].fill(8, 4), [0, 0, 0],
|
||||
'[0, 0, 0].fill(8, 4) must return [0, 0, 0]'
|
||||
);
|
||||
|
||||
assert.compareArray([0, 0, 0].fill(8, -1), [0, 0, 8],
|
||||
'[0, 0, 0].fill(8, -1) must return [0, 0, 8]'
|
||||
);
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.fill
|
||||
description: >
|
||||
Fills all the elements with `value` from a defaul start and index.
|
||||
info: |
|
||||
22.1.3.6 Array.prototype.fill (value [ , start [ , end ] ] )
|
||||
|
||||
...
|
||||
7. If relativeStart < 0, let k be max((len + relativeStart),0); else let k be
|
||||
min(relativeStart, len).
|
||||
8. If end is undefined, let relativeEnd be len; else let relativeEnd be
|
||||
ToInteger(end).
|
||||
9. ReturnIfAbrupt(relativeEnd).
|
||||
10. If relativeEnd < 0, let final be max((len + relativeEnd),0); else let
|
||||
final be min(relativeEnd, len).
|
||||
11. Repeat, while k < final
|
||||
a. Let Pk be ToString(k).
|
||||
b. Let setStatus be Set(O, Pk, value, true).
|
||||
c. ReturnIfAbrupt(setStatus).
|
||||
d. Increase k by 1.
|
||||
12. Return O.
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
assert.compareArray([].fill(8), [], '[].fill(8) must return []');
|
||||
|
||||
assert.compareArray([0, 0].fill(), [undefined, undefined], '[0, 0].fill() must return [undefined, undefined]');
|
||||
|
||||
assert.compareArray([0, 0, 0].fill(8), [8, 8, 8],
|
||||
'[0, 0, 0].fill(8) must return [8, 8, 8]'
|
||||
);
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.fill
|
||||
description: >
|
||||
Return abrupt from ToInteger(end).
|
||||
info: |
|
||||
22.1.3.6 Array.prototype.fill (value [ , start [ , end ] ] )
|
||||
|
||||
...
|
||||
8. If end is undefined, let relativeEnd be len; else let relativeEnd be
|
||||
ToInteger(end).
|
||||
9. ReturnIfAbrupt(relativeEnd).
|
||||
...
|
||||
---*/
|
||||
|
||||
var end = {
|
||||
valueOf: function() {
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[].fill(1, 0, end);
|
||||
});
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
// Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-array.prototype.fill
|
||||
description: >
|
||||
Return abrupt from ToInteger(start).
|
||||
info: |
|
||||
22.1.3.6 Array.prototype.fill (value [ , start [ , end ] ] )
|
||||
|
||||
...
|
||||
5. Let relativeStart be ToInteger(start).
|
||||
6. ReturnIfAbrupt(relativeStart).
|
||||
...
|
||||
---*/
|
||||
|
||||
var start = {
|
||||
valueOf: function() {
|
||||
throw new Test262Error();
|
||||
}
|
||||
};
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
[].fill(1, start);
|
||||
});
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.filter
|
||||
description: >
|
||||
Array.prototype.filter doesn't mutate the Array on which it is
|
||||
called on
|
||||
---*/
|
||||
|
||||
function callbackfn(val, idx, obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var srcArr = [1, 2, 3, 4, 5];
|
||||
srcArr.filter(callbackfn);
|
||||
|
||||
assert.sameValue(srcArr[0], 1, 'srcArr[0]');
|
||||
assert.sameValue(srcArr[1], 2, 'srcArr[1]');
|
||||
assert.sameValue(srcArr[2], 3, 'srcArr[2]');
|
||||
assert.sameValue(srcArr[3], 4, 'srcArr[3]');
|
||||
assert.sameValue(srcArr[4], 5, 'srcArr[4]');
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.filter
|
||||
description: >
|
||||
Array.prototype.filter returns new Array with length equal to
|
||||
number of true returned by callbackfn
|
||||
---*/
|
||||
|
||||
function callbackfn(val, idx, obj)
|
||||
{
|
||||
if (val % 2)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
var srcArr = [1, 2, 3, 4, 5];
|
||||
var resArr = srcArr.filter(callbackfn);
|
||||
|
||||
assert.sameValue(resArr.length, 3, 'resArr.length');
|
||||
assert.sameValue(resArr[0], 1, 'resArr[0]');
|
||||
assert.sameValue(resArr[1], 3, 'resArr[1]');
|
||||
assert.sameValue(resArr[2], 5, 'resArr[2]');
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.filter
|
||||
description: Array.prototype.filter doesn't visit expandos
|
||||
---*/
|
||||
|
||||
var callCnt = 0;
|
||||
|
||||
function callbackfn(val, idx, obj)
|
||||
{
|
||||
callCnt++;
|
||||
}
|
||||
var srcArr = [1, 2, 3, 4, 5];
|
||||
srcArr["i"] = 10;
|
||||
srcArr[true] = 11;
|
||||
|
||||
var resArr = srcArr.filter(callbackfn);
|
||||
|
||||
assert.sameValue(callCnt, 5, 'callCnt');
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.filter
|
||||
description: Array.prototype.filter - 'length' is own data property on an Array
|
||||
---*/
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
return obj.length === 2;
|
||||
}
|
||||
|
||||
var newArr = [12, 11].filter(callbackfn);
|
||||
|
||||
assert.sameValue(newArr.length, 2, 'newArr.length');
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.filter
|
||||
description: Array.prototype.filter throws TypeError if callbackfn is undefined
|
||||
---*/
|
||||
|
||||
var arr = new Array(10);
|
||||
assert.throws(TypeError, function() {
|
||||
arr.filter();
|
||||
});
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-array.prototype.filter
|
||||
description: Array.prototype.filter - 'callbackfn' is a function
|
||||
---*/
|
||||
|
||||
function callbackfn(val, idx, obj) {
|
||||
if (idx === 1) {
|
||||
return val === 9;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var newArr = [11, 9].filter(callbackfn);
|
||||
|
||||
assert.sameValue(newArr.length, 1, 'newArr.length');
|
||||
assert.sameValue(newArr[0], 9, 'newArr[0]');
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user