[INFO] cloning repository https://github.com/schmijos/cucumber-rust-reprod [INFO] running `Command { std: "git" "-c" "credential.helper=" "-c" "credential.helper=/workspace/cargo-home/bin/git-credential-null" "clone" "--bare" "https://github.com/schmijos/cucumber-rust-reprod" "/workspace/cache/git-repos/https%3A%2F%2Fgithub.com%2Fschmijos%2Fcucumber-rust-reprod", kill_on_drop: false }` [INFO] [stderr] Cloning into bare repository '/workspace/cache/git-repos/https%3A%2F%2Fgithub.com%2Fschmijos%2Fcucumber-rust-reprod'... [INFO] running `Command { std: "git" "rev-parse" "HEAD", kill_on_drop: false }` [INFO] [stdout] cfa2d75e05fb5af2122a507b79fa18a5b344e376 [INFO] testing schmijos/cucumber-rust-reprod against 1.60.0 for beta-1.61-1 [INFO] running `Command { std: "git" "clone" "/workspace/cache/git-repos/https%3A%2F%2Fgithub.com%2Fschmijos%2Fcucumber-rust-reprod" "/workspace/builds/worker-0/source", kill_on_drop: false }` [INFO] [stderr] Cloning into '/workspace/builds/worker-0/source'... [INFO] [stderr] done. [INFO] validating manifest of git repo https://github.com/schmijos/cucumber-rust-reprod on toolchain 1.60.0 [INFO] running `Command { std: "/workspace/cargo-home/bin/cargo" "+1.60.0" "metadata" "--manifest-path" "Cargo.toml" "--no-deps", kill_on_drop: false }` [INFO] started tweaking git repo https://github.com/schmijos/cucumber-rust-reprod [INFO] removed 0 missing tests [INFO] finished tweaking git repo https://github.com/schmijos/cucumber-rust-reprod [INFO] tweaked toml for git repo https://github.com/schmijos/cucumber-rust-reprod written to /workspace/builds/worker-0/source/Cargo.toml [INFO] crate git repo https://github.com/schmijos/cucumber-rust-reprod already has a lockfile, it will not be regenerated [INFO] running `Command { std: "/workspace/cargo-home/bin/cargo" "+1.60.0" "fetch" "--manifest-path" "Cargo.toml", kill_on_drop: false }` [INFO] [stderr] Downloading crates ... [INFO] [stderr] Downloaded pest_generator v2.1.1 [INFO] [stderr] Downloaded pathdiff v0.1.0 [INFO] [stderr] Downloaded crossbeam-channel v0.4.0 [INFO] [stderr] Downloaded globwalk v0.7.1 [INFO] [stderr] Downloaded ignore v0.4.11 [INFO] [stderr] Downloaded pest v2.1.2 [INFO] [stderr] Downloaded pest_meta v2.1.2 [INFO] [stderr] Downloaded bstr v0.2.9 [INFO] [stderr] Downloaded gherkin_rust v0.6.0 [INFO] [stderr] Downloaded darling_macro v0.9.0 [INFO] [stderr] Downloaded shh v1.0.0 [INFO] [stderr] Downloaded darling v0.9.0 [INFO] [stderr] Downloaded derive_builder v0.7.2 [INFO] [stderr] Downloaded darling_core v0.9.0 [INFO] [stderr] Downloaded derive_builder_core v0.5.0 [INFO] [stderr] Downloaded cucumber_rust v0.6.4 [INFO] running `Command { std: "docker" "create" "-v" "/var/lib/crater-agent-workspace/builds/worker-0/target:/opt/rustwide/target:rw,Z" "-v" "/var/lib/crater-agent-workspace/builds/worker-0/source:/opt/rustwide/workdir:ro,Z" "-v" "/var/lib/crater-agent-workspace/cargo-home:/opt/rustwide/cargo-home:ro,Z" "-v" "/var/lib/crater-agent-workspace/rustup-home:/opt/rustwide/rustup-home:ro,Z" "-e" "SOURCE_DIR=/opt/rustwide/workdir" "-e" "CARGO_TARGET_DIR=/opt/rustwide/target" "-e" "CARGO_HOME=/opt/rustwide/cargo-home" "-e" "RUSTUP_HOME=/opt/rustwide/rustup-home" "-w" "/opt/rustwide/workdir" "-m" "1610612736" "--user" "0:0" "--network" "none" "ghcr.io/rust-lang/crates-build-env/linux@sha256:eaef2f80f755933c374d2ae5edccceec0c1312ceb8a4e0b6404e8ab76561e1e5" "/opt/rustwide/cargo-home/bin/cargo" "+1.60.0" "metadata" "--no-deps" "--format-version=1", kill_on_drop: false }` [INFO] [stdout] 3c0ee7f40ac454dd02baf0dd909b5213f991496b85d477970f8343ce469b6d06 [INFO] [stderr] WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap. [INFO] running `Command { std: "docker" "start" "-a" "3c0ee7f40ac454dd02baf0dd909b5213f991496b85d477970f8343ce469b6d06", kill_on_drop: false }` [INFO] running `Command { std: "docker" "inspect" "3c0ee7f40ac454dd02baf0dd909b5213f991496b85d477970f8343ce469b6d06", kill_on_drop: false }` [INFO] running `Command { std: "docker" "rm" "-f" "3c0ee7f40ac454dd02baf0dd909b5213f991496b85d477970f8343ce469b6d06", kill_on_drop: false }` [INFO] [stdout] 3c0ee7f40ac454dd02baf0dd909b5213f991496b85d477970f8343ce469b6d06 [INFO] running `Command { std: "docker" "create" "-v" "/var/lib/crater-agent-workspace/builds/worker-0/target:/opt/rustwide/target:rw,Z" "-v" "/var/lib/crater-agent-workspace/builds/worker-0/source:/opt/rustwide/workdir:ro,Z" "-v" "/var/lib/crater-agent-workspace/cargo-home:/opt/rustwide/cargo-home:ro,Z" "-v" "/var/lib/crater-agent-workspace/rustup-home:/opt/rustwide/rustup-home:ro,Z" "-e" "SOURCE_DIR=/opt/rustwide/workdir" "-e" "CARGO_TARGET_DIR=/opt/rustwide/target" "-e" "CARGO_INCREMENTAL=0" "-e" "RUST_BACKTRACE=full" "-e" "RUSTFLAGS=--cap-lints=warn" "-e" "CARGO_HOME=/opt/rustwide/cargo-home" "-e" "RUSTUP_HOME=/opt/rustwide/rustup-home" "-w" "/opt/rustwide/workdir" "-m" "1610612736" "--user" "0:0" "--network" "none" "ghcr.io/rust-lang/crates-build-env/linux@sha256:eaef2f80f755933c374d2ae5edccceec0c1312ceb8a4e0b6404e8ab76561e1e5" "/opt/rustwide/cargo-home/bin/cargo" "+1.60.0" "build" "--frozen" "--message-format=json", kill_on_drop: false }` [INFO] [stderr] WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap. [INFO] [stdout] 33f20f01360e489bca89d6e7583c78900ee10ec2204df530ec6ba13e9419196d [INFO] running `Command { std: "docker" "start" "-a" "33f20f01360e489bca89d6e7583c78900ee10ec2204df530ec6ba13e9419196d", kill_on_drop: false }` [INFO] [stderr] Compiling cucumber-test v0.1.0 (/opt/rustwide/workdir) [INFO] [stderr] Finished dev [unoptimized + debuginfo] target(s) in 1.78s [INFO] running `Command { std: "docker" "inspect" "33f20f01360e489bca89d6e7583c78900ee10ec2204df530ec6ba13e9419196d", kill_on_drop: false }` [INFO] running `Command { std: "docker" "rm" "-f" "33f20f01360e489bca89d6e7583c78900ee10ec2204df530ec6ba13e9419196d", kill_on_drop: false }` [INFO] [stdout] 33f20f01360e489bca89d6e7583c78900ee10ec2204df530ec6ba13e9419196d [INFO] running `Command { std: "docker" "create" "-v" "/var/lib/crater-agent-workspace/builds/worker-0/target:/opt/rustwide/target:rw,Z" "-v" "/var/lib/crater-agent-workspace/builds/worker-0/source:/opt/rustwide/workdir:ro,Z" "-v" "/var/lib/crater-agent-workspace/cargo-home:/opt/rustwide/cargo-home:ro,Z" "-v" "/var/lib/crater-agent-workspace/rustup-home:/opt/rustwide/rustup-home:ro,Z" "-e" "SOURCE_DIR=/opt/rustwide/workdir" "-e" "CARGO_TARGET_DIR=/opt/rustwide/target" "-e" "CARGO_INCREMENTAL=0" "-e" "RUST_BACKTRACE=full" "-e" "RUSTFLAGS=--cap-lints=warn" "-e" "CARGO_HOME=/opt/rustwide/cargo-home" "-e" "RUSTUP_HOME=/opt/rustwide/rustup-home" "-w" "/opt/rustwide/workdir" "-m" "1610612736" "--user" "0:0" "--network" "none" "ghcr.io/rust-lang/crates-build-env/linux@sha256:eaef2f80f755933c374d2ae5edccceec0c1312ceb8a4e0b6404e8ab76561e1e5" "/opt/rustwide/cargo-home/bin/cargo" "+1.60.0" "test" "--frozen" "--no-run" "--message-format=json", kill_on_drop: false }` [INFO] [stderr] WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap. [INFO] [stdout] cb1275c932f2b77e905ce6b30237d434dd3b01a72ad3a0c7818095e0c32a4018 [INFO] running `Command { std: "docker" "start" "-a" "cb1275c932f2b77e905ce6b30237d434dd3b01a72ad3a0c7818095e0c32a4018", kill_on_drop: false }` [INFO] [stderr] Compiling memchr v2.3.0 [INFO] [stderr] Compiling syn v0.15.44 [INFO] [stderr] Compiling syn v1.0.13 [INFO] [stderr] Compiling regex-syntax v0.6.13 [INFO] [stderr] Compiling derive_builder v0.7.2 [INFO] [stderr] Compiling pathdiff v0.1.0 [INFO] [stderr] Compiling pest v2.1.2 [INFO] [stderr] Compiling term_size v0.3.1 [INFO] [stderr] Compiling atty v0.2.14 [INFO] [stderr] Compiling shh v1.0.0 [INFO] [stderr] Compiling crossbeam-channel v0.4.0 [INFO] [stderr] Compiling textwrap v0.11.0 [INFO] [stderr] Compiling clap v2.33.0 [INFO] [stderr] Compiling aho-corasick v0.7.6 [INFO] [stderr] Compiling bstr v0.2.9 [INFO] [stderr] Compiling pest_meta v2.1.2 [INFO] [stderr] Compiling regex v1.3.3 [INFO] [stderr] Compiling pest_generator v2.1.1 [INFO] [stderr] Compiling globset v0.4.4 [INFO] [stderr] Compiling pest_derive v2.1.0 [INFO] [stderr] Compiling ignore v0.4.11 [INFO] [stderr] Compiling darling_core v0.9.0 [INFO] [stderr] Compiling globwalk v0.7.1 [INFO] [stderr] Compiling darling_macro v0.9.0 [INFO] [stderr] Compiling darling v0.9.0 [INFO] [stderr] Compiling derive_builder_core v0.5.0 [INFO] [stderr] Compiling gherkin_rust v0.6.0 [INFO] [stderr] Compiling cucumber_rust v0.6.4 [INFO] [stderr] Compiling cucumber-test v0.1.0 (/opt/rustwide/workdir) [INFO] [stdout] warning: unused import: `steps` [INFO] [stdout] --> tests/cucumber.rs:1:26 [INFO] [stdout] | [INFO] [stdout] 1 | use cucumber::{cucumber, steps, before, after}; [INFO] [stdout] | ^^^^^ [INFO] [stdout] | [INFO] [stdout] = note: `#[warn(unused_imports)]` on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused variable: `scenario` [INFO] [stdout] --> tests/cucumber.rs:65:25 [INFO] [stdout] | [INFO] [stdout] 65 | before!(a_before_fn => |scenario| { [INFO] [stdout] | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_scenario` [INFO] [stdout] | [INFO] [stdout] = note: `#[warn(unused_variables)]` on by default [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused variable: `scenario` [INFO] [stdout] --> tests/cucumber.rs:70:24 [INFO] [stdout] | [INFO] [stdout] 70 | after!(an_after_fn => |scenario| { [INFO] [stdout] | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_scenario` [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused variable: `step` [INFO] [stdout] --> tests/cucumber.rs:23:50 [INFO] [stdout] | [INFO] [stdout] 23 | given "I am trying out Cucumber" |world, step| { [INFO] [stdout] | ^^^^ help: if this is intentional, prefix it with an underscore: `_step` [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused variable: `step` [INFO] [stdout] --> tests/cucumber.rs:28:51 [INFO] [stdout] | [INFO] [stdout] 28 | when "I consider what I am doing" |world, step| { [INFO] [stdout] | ^^^^ help: if this is intentional, prefix it with an underscore: `_step` [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused variable: `step` [INFO] [stdout] --> tests/cucumber.rs:34:48 [INFO] [stdout] | [INFO] [stdout] 34 | then "I am interested in ATDD" |world, step| { [INFO] [stdout] | ^^^^ help: if this is intentional, prefix it with an underscore: `_step` [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused variable: `world` [INFO] [stdout] --> tests/cucumber.rs:39:55 [INFO] [stdout] | [INFO] [stdout] 39 | then regex r"^we can (.*) rules with regex$" |world, matches, step| { [INFO] [stdout] | ^^^^^ help: if this is intentional, prefix it with an underscore: `_world` [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused variable: `step` [INFO] [stdout] --> tests/cucumber.rs:39:71 [INFO] [stdout] | [INFO] [stdout] 39 | then regex r"^we can (.*) rules with regex$" |world, matches, step| { [INFO] [stdout] | ^^^^ help: if this is intentional, prefix it with an underscore: `_step` [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused variable: `world` [INFO] [stdout] --> tests/cucumber.rs:44:77 [INFO] [stdout] | [INFO] [stdout] 44 | then regex r"^we can also match (\d+) (.+) types$" (usize, String) |world, num, word, step| { [INFO] [stdout] | ^^^^^ help: if this is intentional, prefix it with an underscore: `_world` [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused variable: `step` [INFO] [stdout] --> tests/cucumber.rs:44:95 [INFO] [stdout] | [INFO] [stdout] 44 | then regex r"^we can also match (\d+) (.+) types$" (usize, String) |world, num, word, step| { [INFO] [stdout] | ^^^^ help: if this is intentional, prefix it with an underscore: `_step` [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: unused variable: `world` [INFO] [stdout] --> tests/cucumber.rs:50:67 [INFO] [stdout] | [INFO] [stdout] 50 | then "we can use data tables to provide more parameters" |world, step| { [INFO] [stdout] | ^^^^^ help: if this is intentional, prefix it with an underscore: `_world` [INFO] [stdout] [INFO] [stdout] [INFO] [stdout] warning: 11 warnings emitted [INFO] [stdout] [INFO] [stdout] [INFO] [stderr] Finished test [unoptimized + debuginfo] target(s) in 1m 37s [INFO] running `Command { std: "docker" "inspect" "cb1275c932f2b77e905ce6b30237d434dd3b01a72ad3a0c7818095e0c32a4018", kill_on_drop: false }` [INFO] running `Command { std: "docker" "rm" "-f" "cb1275c932f2b77e905ce6b30237d434dd3b01a72ad3a0c7818095e0c32a4018", kill_on_drop: false }` [INFO] [stdout] cb1275c932f2b77e905ce6b30237d434dd3b01a72ad3a0c7818095e0c32a4018 [INFO] running `Command { std: "docker" "create" "-v" "/var/lib/crater-agent-workspace/builds/worker-0/target:/opt/rustwide/target:rw,Z" "-v" "/var/lib/crater-agent-workspace/builds/worker-0/source:/opt/rustwide/workdir:ro,Z" "-v" "/var/lib/crater-agent-workspace/cargo-home:/opt/rustwide/cargo-home:ro,Z" "-v" "/var/lib/crater-agent-workspace/rustup-home:/opt/rustwide/rustup-home:ro,Z" "-e" "SOURCE_DIR=/opt/rustwide/workdir" "-e" "CARGO_TARGET_DIR=/opt/rustwide/target" "-e" "CARGO_INCREMENTAL=0" "-e" "RUST_BACKTRACE=full" "-e" "RUSTFLAGS=--cap-lints=warn" "-e" "CARGO_HOME=/opt/rustwide/cargo-home" "-e" "RUSTUP_HOME=/opt/rustwide/rustup-home" "-w" "/opt/rustwide/workdir" "-m" "1610612736" "--user" "0:0" "--network" "none" "ghcr.io/rust-lang/crates-build-env/linux@sha256:eaef2f80f755933c374d2ae5edccceec0c1312ceb8a4e0b6404e8ab76561e1e5" "/opt/rustwide/cargo-home/bin/cargo" "+1.60.0" "test" "--frozen", kill_on_drop: false }` [INFO] [stderr] WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap. [INFO] [stdout] 5c897d955e20fee26b3d60f8040c961ede71c78202b93ff1e9a2bcd1ba2cb609 [INFO] running `Command { std: "docker" "start" "-a" "5c897d955e20fee26b3d60f8040c961ede71c78202b93ff1e9a2bcd1ba2cb609", kill_on_drop: false }` [INFO] [stderr] warning: unused import: `steps` [INFO] [stderr] --> tests/cucumber.rs:1:26 [INFO] [stderr] | [INFO] [stderr] 1 | use cucumber::{cucumber, steps, before, after}; [INFO] [stderr] | ^^^^^ [INFO] [stderr] | [INFO] [stderr] = note: `#[warn(unused_imports)]` on by default [INFO] [stderr] [INFO] [stderr] warning: unused variable: `scenario` [INFO] [stderr] --> tests/cucumber.rs:65:25 [INFO] [stderr] | [INFO] [stderr] 65 | before!(a_before_fn => |scenario| { [INFO] [stderr] | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_scenario` [INFO] [stderr] | [INFO] [stderr] = note: `#[warn(unused_variables)]` on by default [INFO] [stderr] [INFO] [stderr] warning: unused variable: `scenario` [INFO] [stderr] --> tests/cucumber.rs:70:24 [INFO] [stderr] | [INFO] [stderr] 70 | after!(an_after_fn => |scenario| { [INFO] [stderr] | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_scenario` [INFO] [stderr] [INFO] [stderr] warning: unused variable: `step` [INFO] [stderr] --> tests/cucumber.rs:23:50 [INFO] [stderr] | [INFO] [stderr] 23 | given "I am trying out Cucumber" |world, step| { [INFO] [stderr] | ^^^^ help: if this is intentional, prefix it with an underscore: `_step` [INFO] [stderr] [INFO] [stderr] warning: unused variable: `step` [INFO] [stderr] --> tests/cucumber.rs:28:51 [INFO] [stderr] | [INFO] [stderr] 28 | when "I consider what I am doing" |world, step| { [INFO] [stderr] | ^^^^ help: if this is intentional, prefix it with an underscore: `_step` [INFO] [stderr] [INFO] [stderr] warning: unused variable: `step` [INFO] [stderr] --> tests/cucumber.rs:34:48 [INFO] [stderr] | [INFO] [stderr] 34 | then "I am interested in ATDD" |world, step| { [INFO] [stderr] | ^^^^ help: if this is intentional, prefix it with an underscore: `_step` [INFO] [stderr] [INFO] [stderr] warning: unused variable: `world` [INFO] [stderr] --> tests/cucumber.rs:39:55 [INFO] [stderr] | [INFO] [stderr] 39 | then regex r"^we can (.*) rules with regex$" |world, matches, step| { [INFO] [stderr] | ^^^^^ help: if this is intentional, prefix it with an underscore: `_world` [INFO] [stderr] [INFO] [stderr] warning: unused variable: `step` [INFO] [stderr] --> tests/cucumber.rs:39:71 [INFO] [stderr] | [INFO] [stderr] 39 | then regex r"^we can (.*) rules with regex$" |world, matches, step| { [INFO] [stderr] | ^^^^ help: if this is intentional, prefix it with an underscore: `_step` [INFO] [stderr] [INFO] [stderr] warning: unused variable: `world` [INFO] [stderr] --> tests/cucumber.rs:44:77 [INFO] [stderr] | [INFO] [stderr] 44 | then regex r"^we can also match (\d+) (.+) types$" (usize, String) |world, num, word, step| { [INFO] [stderr] | ^^^^^ help: if this is intentional, prefix it with an underscore: `_world` [INFO] [stderr] [INFO] [stderr] warning: unused variable: `step` [INFO] [stderr] --> tests/cucumber.rs:44:95 [INFO] [stderr] | [INFO] [stderr] 44 | then regex r"^we can also match (\d+) (.+) types$" (usize, String) |world, num, word, step| { [INFO] [stderr] | ^^^^ help: if this is intentional, prefix it with an underscore: `_step` [INFO] [stderr] [INFO] [stderr] warning: unused variable: `world` [INFO] [stderr] --> tests/cucumber.rs:50:67 [INFO] [stderr] | [INFO] [stderr] 50 | then "we can use data tables to provide more parameters" |world, step| { [INFO] [stderr] | ^^^^^ help: if this is intentional, prefix it with an underscore: `_world` [INFO] [stderr] [INFO] [stderr] warning: `cucumber-test` (test "cucumber") generated 11 warnings [INFO] [stderr] Finished test [unoptimized + debuginfo] target(s) in 0.19s [INFO] [stderr] Running unittests (/opt/rustwide/target/debug/deps/cucumber_test-32f23fcf8f8da6db) [INFO] [stdout] [INFO] [stdout] running 0 tests [INFO] [stdout] [INFO] [stdout] test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s [INFO] [stdout] [INFO] [stderr] Running tests/cucumber.rs (/opt/rustwide/target/debug/deps/cucumber-cb33c0dfd5e5e26e) [INFO] [stdout] [Cucumber v0.6.4] [INFO] [stdout] [INFO] [stdout] Feature: Camera features/camera.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: Constructing a camera features/camera.feature:3:11 [INFO] [stdout] - Given hsize ← 160 features/camera.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And vsize ← 120 features/camera.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And field_of_view ← π/2 features/camera.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When c ← camera(hsize, vsize, field_of_view) features/camera.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c.hsize = 160 features/camera.feature:8:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c.vsize = 120 features/camera.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c.field_of_view = π/2 features/camera.feature:10:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c.transform = identity_matrix features/camera.feature:11:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The pixel size for a horizontal canvas features/camera.feature:13:11 [INFO] [stdout] - Given c ← camera(200, 125, π/2) features/camera.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c.pixel_size = 0.01 features/camera.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The pixel size for a vertical canvas features/camera.feature:17:11 [INFO] [stdout] - Given c ← camera(125, 200, π/2) features/camera.feature:18:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c.pixel_size = 0.01 features/camera.feature:19:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Constructing a ray through the center of the canvas [INFO] [stdout] features/camera.feature:21:11 [INFO] [stdout] - Given c ← camera(201, 101, π/2) features/camera.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When r ← ray_for_pixel(c, 100, 50) features/camera.feature:23:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then r.origin = point(0, 0, 0) features/camera.feature:24:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r.direction = vector(0, 0, -1) features/camera.feature:25:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Constructing a ray through a corner of the canvas [INFO] [stdout] features/camera.feature:27:11 [INFO] [stdout] - Given c ← camera(201, 101, π/2) features/camera.feature:28:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When r ← ray_for_pixel(c, 0, 0) features/camera.feature:29:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then r.origin = point(0, 0, 0) features/camera.feature:30:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r.direction = vector(0.66519, 0.33259, -0.66851) [INFO] [stdout] features/camera.feature:31:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Constructing a ray when the camera is transformed [INFO] [stdout] features/camera.feature:33:11 [INFO] [stdout] - Given c ← camera(201, 101, π/2) features/camera.feature:34:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When c.transform ← rotation_y(π/4) * translation(0, -2, 5) [INFO] [stdout] features/camera.feature:35:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray_for_pixel(c, 100, 50) features/camera.feature:36:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then r.origin = point(0, 2, -5) features/camera.feature:37:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r.direction = vector(√2/2, 0, -√2/2) features/camera.feature:38:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Rendering a world with a camera features/camera.feature:40:11 [INFO] [stdout] - Given w ← default_world() features/camera.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c ← camera(11, 11, π/2) features/camera.feature:42:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And from ← point(0, 0, -5) features/camera.feature:43:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And to ← point(0, 0, 0) features/camera.feature:44:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And up ← vector(0, 1, 0) features/camera.feature:45:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c.transform ← view_transform(from, to, up) features/camera.feature:46:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When image ← render(c, w) features/camera.feature:47:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then pixel_at(image, 5, 5) = color(0.38066, 0.47583, 0.2855) [INFO] [stdout] features/camera.feature:48:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Canvas features/canvas.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: Creating a canvas features/canvas.feature:3:11 [INFO] [stdout] - Given c ← canvas(10, 20) features/canvas.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c.width = 10 features/canvas.feature:5:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c.height = 20 features/canvas.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And every pixel of c is color(0, 0, 0) features/canvas.feature:7:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Writing pixels to a canvas features/canvas.feature:9:11 [INFO] [stdout] - Given c ← canvas(10, 20) features/canvas.feature:10:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And red ← color(1, 0, 0) features/canvas.feature:11:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When write_pixel(c, 2, 3, red) features/canvas.feature:12:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then pixel_at(c, 2, 3) = red features/canvas.feature:13:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Constructing the PPM header features/canvas.feature:15:11 [INFO] [stdout] - Given c ← canvas(5, 3) features/canvas.feature:16:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When ppm ← canvas_to_ppm(c) features/canvas.feature:17:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then lines 1-3 of ppm are features/canvas.feature:18:3 [INFO] [stdout] """ [INFO] [stdout] P3 [INFO] [stdout] 5 3 [INFO] [stdout] 255 [INFO] [stdout] """ [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Constructing the PPM pixel data features/canvas.feature:25:11 [INFO] [stdout] - Given c ← canvas(5, 3) features/canvas.feature:26:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c1 ← color(1.5, 0, 0) features/canvas.feature:27:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c2 ← color(0, 0.5, 0) features/canvas.feature:28:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c3 ← color(-0.5, 0, 1) features/canvas.feature:29:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When write_pixel(c, 0, 0, c1) features/canvas.feature:30:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And write_pixel(c, 2, 1, c2) features/canvas.feature:31:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And write_pixel(c, 4, 2, c3) features/canvas.feature:32:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And ppm ← canvas_to_ppm(c) features/canvas.feature:33:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then lines 4-6 of ppm are features/canvas.feature:34:3 [INFO] [stdout] """ [INFO] [stdout] 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 [INFO] [stdout] 0 0 0 0 0 0 0 128 0 0 0 0 0 0 0 [INFO] [stdout] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 [INFO] [stdout] """ [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Splitting long lines in PPM files features/canvas.feature:41:11 [INFO] [stdout] - Given c ← canvas(10, 2) features/canvas.feature:42:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When every pixel of c is set to color(1, 0.8, 0.6) [INFO] [stdout] features/canvas.feature:43:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And ppm ← canvas_to_ppm(c) features/canvas.feature:44:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then lines 4-7 of ppm are features/canvas.feature:45:3 [INFO] [stdout] """ [INFO] [stdout] 255 204 153 255 204 153 255 204 153 255 204 153 255 204 153 255 204 [INFO] [stdout] 153 255 204 153 255 204 153 255 204 153 255 204 153 [INFO] [stdout] 255 204 153 255 204 153 255 204 153 255 204 153 255 204 153 255 204 [INFO] [stdout] 153 255 204 153 255 204 153 255 204 153 255 204 153 [INFO] [stdout] """ [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: PPM files are terminated by a newline character [INFO] [stdout] features/canvas.feature:53:11 [INFO] [stdout] - Given c ← canvas(5, 3) features/canvas.feature:54:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When ppm ← canvas_to_ppm(c) features/canvas.feature:55:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then ppm ends with a newline character features/canvas.feature:56:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Cones features/cones.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a cone with a ray 0 features/cones.feature:12:12 [INFO] [stdout] - Given shape ← cone() features/cones.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(vector(0, 0, 1)) features/cones.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -5), direction) features/cones.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(shape, r) features/cones.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cones.feature:8:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 5 features/cones.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 5 features/cones.feature:10:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a cone with a ray 1 features/cones.feature:12:12 [INFO] [stdout] - Given shape ← cone() features/cones.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(vector(1, 1, 1)) features/cones.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -5), direction) features/cones.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(shape, r) features/cones.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cones.feature:8:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 8.66025 features/cones.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 8.66025 features/cones.feature:10:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a cone with a ray 2 features/cones.feature:12:12 [INFO] [stdout] - Given shape ← cone() features/cones.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(vector(-0.5, -1, 1)) features/cones.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(1, 1, -5), direction) features/cones.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(shape, r) features/cones.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cones.feature:8:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 4.55006 features/cones.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 49.44994 features/cones.feature:10:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a cone with a ray parallel to one of its halves [INFO] [stdout] features/cones.feature:18:11 [INFO] [stdout] - Given shape ← cone() features/cones.feature:19:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(vector(0, 1, 1)) features/cones.feature:20:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -1), direction) features/cones.feature:21:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(shape, r) features/cones.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 1 features/cones.feature:23:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 0.35355 features/cones.feature:24:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a cone's end caps 0 features/cones.feature:36:12 [INFO] [stdout] - Given shape ← cone() features/cones.feature:27:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape.minimum ← -0.5 features/cones.feature:28:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape.maximum ← 0.5 features/cones.feature:29:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape.closed ← true features/cones.feature:30:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(vector(0, 1, 0)) features/cones.feature:31:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -5), direction) features/cones.feature:32:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(shape, r) features/cones.feature:33:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 0 features/cones.feature:34:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a cone's end caps 1 features/cones.feature:36:12 [INFO] [stdout] - Given shape ← cone() features/cones.feature:27:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape.minimum ← -0.5 features/cones.feature:28:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape.maximum ← 0.5 features/cones.feature:29:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape.closed ← true features/cones.feature:30:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(vector(0, 1, 1)) features/cones.feature:31:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -0.25), direction) features/cones.feature:32:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(shape, r) features/cones.feature:33:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cones.feature:34:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a cone's end caps 2 features/cones.feature:36:12 [INFO] [stdout] - Given shape ← cone() features/cones.feature:27:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape.minimum ← -0.5 features/cones.feature:28:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape.maximum ← 0.5 features/cones.feature:29:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape.closed ← true features/cones.feature:30:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(vector(0, 1, 0)) features/cones.feature:31:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -0.25), direction) features/cones.feature:32:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(shape, r) features/cones.feature:33:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 4 features/cones.feature:34:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Computing the normal vector on a cone 0 features/cones.feature:47:12 [INFO] [stdout] - Given shape ← cone() features/cones.feature:43:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← local_normal_at(shape, point(0, 0, 0)) features/cones.feature:44:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, 0, 0) features/cones.feature:45:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Computing the normal vector on a cone 1 features/cones.feature:47:12 [INFO] [stdout] - Given shape ← cone() features/cones.feature:43:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← local_normal_at(shape, point(1, 1, 1)) features/cones.feature:44:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(1, -√2, 1) features/cones.feature:45:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Computing the normal vector on a cone 2 features/cones.feature:47:12 [INFO] [stdout] - Given shape ← cone() features/cones.feature:43:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← local_normal_at(shape, point(-1, -1, 0)) [INFO] [stdout] features/cones.feature:44:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(-1, 1, 0) features/cones.feature:45:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Constructive Solid Geometry (CSG) features/csg.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: CSG is created with an operation and two shapes [INFO] [stdout] features/csg.feature:3:11 [INFO] [stdout] - Given s1 ← sphere() features/csg.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s2 ← cube() features/csg.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When c ← csg("union", s1, s2) features/csg.feature:6:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c.operation = "union" features/csg.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c.left = s1 features/csg.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c.right = s2 features/csg.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s1.parent = c features/csg.feature:10:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s2.parent = c features/csg.feature:11:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 0 features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("union", true, true, true) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = false features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 1 features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("union", true, true, false) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = true features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 2 features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("union", true, false, true) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = false features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 3 features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("union", true, false, false) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = true features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 4 features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("union", false, true, true) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = false features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 5 features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("union", false, true, false) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = false features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 6 features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("union", false, false, true) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = true features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 7 features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("union", false, false, false) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = true features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 8 features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("intersection", true, true, true) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = true features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 9 features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("intersection", true, true, false) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = false features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 10 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("intersection", true, false, true) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = true features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 11 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("intersection", true, false, false) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = false features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 12 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("intersection", false, true, true) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = true features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 13 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("intersection", false, true, false) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = true features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 14 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("intersection", false, false, true) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = false features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 15 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("intersection", false, false, false) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = false features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 16 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("difference", true, true, true) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = false features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 17 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("difference", true, true, false) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = true features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 18 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("difference", true, false, true) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = false features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 19 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("difference", true, false, false) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = true features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 20 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("difference", false, true, true) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = true features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 21 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("difference", false, true, false) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = true features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 22 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("difference", false, false, true) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = false features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Evaluating the rule for a CSG operation 23 [INFO] [stdout] features/csg.feature:17:12 [INFO] [stdout] - When result ← intersection_allowed("difference", false, false, false) [INFO] [stdout] features/csg.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = false features/csg.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Filtering a list of intersections 0 features/csg.feature:56:12 [INFO] [stdout] - Given s1 ← sphere() features/csg.feature:47:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s2 ← cube() features/csg.feature:48:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c ← csg("union", s1, s2) features/csg.feature:49:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(1:s1, 2:s2, 3:s1, 4:s2) features/csg.feature:50:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When result ← filter_intersections(c, xs) features/csg.feature:51:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result.count = 2 features/csg.feature:52:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And result[0] = xs[0] features/csg.feature:53:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And result[1] = xs[3] features/csg.feature:54:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Filtering a list of intersections 1 features/csg.feature:56:12 [INFO] [stdout] - Given s1 ← sphere() features/csg.feature:47:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s2 ← cube() features/csg.feature:48:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c ← csg("intersection", s1, s2) features/csg.feature:49:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(1:s1, 2:s2, 3:s1, 4:s2) features/csg.feature:50:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When result ← filter_intersections(c, xs) features/csg.feature:51:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result.count = 2 features/csg.feature:52:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And result[0] = xs[1] features/csg.feature:53:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And result[1] = xs[2] features/csg.feature:54:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Filtering a list of intersections 2 features/csg.feature:56:12 [INFO] [stdout] - Given s1 ← sphere() features/csg.feature:47:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s2 ← cube() features/csg.feature:48:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c ← csg("difference", s1, s2) features/csg.feature:49:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(1:s1, 2:s2, 3:s1, 4:s2) features/csg.feature:50:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When result ← filter_intersections(c, xs) features/csg.feature:51:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result.count = 2 features/csg.feature:52:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And result[0] = xs[0] features/csg.feature:53:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And result[1] = xs[1] features/csg.feature:54:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses a CSG object features/csg.feature:62:11 [INFO] [stdout] - Given c ← csg("union", sphere(), cube()) features/csg.feature:63:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 2, -5), vector(0, 0, 1)) features/csg.feature:64:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/csg.feature:65:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs is empty features/csg.feature:66:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray hits a CSG object features/csg.feature:68:11 [INFO] [stdout] - Given s1 ← sphere() features/csg.feature:69:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s2 ← sphere() features/csg.feature:70:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(s2, translation(0, 0, 0.5)) features/csg.feature:71:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c ← csg("union", s1, s2) features/csg.feature:72:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -5), vector(0, 0, 1)) features/csg.feature:73:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/csg.feature:74:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/csg.feature:75:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 4 features/csg.feature:76:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].object = s1 features/csg.feature:77:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 6.5 features/csg.feature:78:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].object = s2 features/csg.feature:79:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Cubes features/cubes.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: A ray intersects a cube 0 features/cubes.feature:11:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(+x, point(5, 0.5, 0)) features/cubes.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/cubes.feature:6:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cubes.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = vector(-1, 0, 0) features/cubes.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 4 features/cubes.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray intersects a cube 1 features/cubes.feature:11:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(-x, point(-5, 0.5, 0)) features/cubes.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/cubes.feature:6:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cubes.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = vector(1, 0, 0) features/cubes.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 4 features/cubes.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray intersects a cube 2 features/cubes.feature:11:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(+y, point(0.5, 5, 0)) features/cubes.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/cubes.feature:6:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cubes.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = vector(0, -1, 0) features/cubes.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 4 features/cubes.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray intersects a cube 3 features/cubes.feature:11:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(-y, point(0.5, -5, 0)) features/cubes.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/cubes.feature:6:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cubes.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = vector(0, 1, 0) features/cubes.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 4 features/cubes.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray intersects a cube 4 features/cubes.feature:11:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(+z, point(0.5, 0, 5)) features/cubes.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/cubes.feature:6:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cubes.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = vector(0, 0, -1) features/cubes.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 4 features/cubes.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray intersects a cube 5 features/cubes.feature:11:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(-z, point(0.5, 0, -5)) features/cubes.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/cubes.feature:6:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cubes.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = vector(0, 0, 1) features/cubes.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 4 features/cubes.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray intersects a cube 6 features/cubes.feature:11:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(inside, point(0, 0.5, 0)) features/cubes.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/cubes.feature:6:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cubes.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = vector(0, 0, 1) features/cubes.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = -1 features/cubes.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses a cube 0 features/cubes.feature:27:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(-2, 0, 0), vector(0.2673, 0.5345, 0.8018)) [INFO] [stdout] features/cubes.feature:23:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/cubes.feature:24:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 0 features/cubes.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses a cube 1 features/cubes.feature:27:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, -2, 0), vector(0.8018, 0.2673, 0.5345)) [INFO] [stdout] features/cubes.feature:23:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/cubes.feature:24:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 0 features/cubes.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses a cube 2 features/cubes.feature:27:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -2), vector(0.5345, 0.8018, 0.2673)) [INFO] [stdout] features/cubes.feature:23:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/cubes.feature:24:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 0 features/cubes.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses a cube 3 features/cubes.feature:27:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(2, 0, 2), vector(0, 0, -1)) features/cubes.feature:23:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/cubes.feature:24:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 0 features/cubes.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses a cube 4 features/cubes.feature:27:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 2, 2), vector(0, -1, 0)) features/cubes.feature:23:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/cubes.feature:24:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 0 features/cubes.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses a cube 5 features/cubes.feature:27:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(2, 2, 0), vector(-1, 0, 0)) features/cubes.feature:23:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(c, r) features/cubes.feature:24:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 0 features/cubes.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal on the surface of a cube 0 features/cubes.feature:43:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:38:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(1, 0.5, -0.8) features/cubes.feature:39:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When normal ← local_normal_at(c, p) features/cubes.feature:40:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then normal = vector(1, 0, 0) features/cubes.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal on the surface of a cube 1 features/cubes.feature:43:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:38:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(-1, -0.2, 0.9) features/cubes.feature:39:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When normal ← local_normal_at(c, p) features/cubes.feature:40:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then normal = vector(-1, 0, 0) features/cubes.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal on the surface of a cube 2 features/cubes.feature:43:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:38:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(-0.4, 1, -0.1) features/cubes.feature:39:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When normal ← local_normal_at(c, p) features/cubes.feature:40:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then normal = vector(0, 1, 0) features/cubes.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal on the surface of a cube 3 features/cubes.feature:43:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:38:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(0.3, -1, -0.7) features/cubes.feature:39:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When normal ← local_normal_at(c, p) features/cubes.feature:40:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then normal = vector(0, -1, 0) features/cubes.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal on the surface of a cube 4 features/cubes.feature:43:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:38:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(-0.6, 0.3, 1) features/cubes.feature:39:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When normal ← local_normal_at(c, p) features/cubes.feature:40:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then normal = vector(0, 0, 1) features/cubes.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal on the surface of a cube 5 features/cubes.feature:43:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:38:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(0.4, 0.4, -1) features/cubes.feature:39:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When normal ← local_normal_at(c, p) features/cubes.feature:40:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then normal = vector(0, 0, -1) features/cubes.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal on the surface of a cube 6 features/cubes.feature:43:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:38:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(1, 1, 1) features/cubes.feature:39:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When normal ← local_normal_at(c, p) features/cubes.feature:40:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then normal = vector(1, 0, 0) features/cubes.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal on the surface of a cube 7 features/cubes.feature:43:12 [INFO] [stdout] - Given c ← cube() features/cubes.feature:38:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(-1, -1, -1) features/cubes.feature:39:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When normal ← local_normal_at(c, p) features/cubes.feature:40:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then normal = vector(-1, 0, 0) features/cubes.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Cylinders features/cylinders.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses a cylinder 0 features/cylinders.feature:10:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(vector(0, 1, 0)) features/cylinders.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(1, 0, 0), direction) features/cylinders.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 0 features/cylinders.feature:8:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses a cylinder 1 features/cylinders.feature:10:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(vector(0, 1, 0)) features/cylinders.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, 0), direction) features/cylinders.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 0 features/cylinders.feature:8:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses a cylinder 2 features/cylinders.feature:10:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(vector(1, 1, 1)) features/cylinders.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -5), direction) features/cylinders.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 0 features/cylinders.feature:8:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray strikes a cylinder 0 features/cylinders.feature:25:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:17:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(vector(0, 0, 1)) features/cylinders.feature:18:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(1, 0, -5), direction) features/cylinders.feature:19:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:20:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cylinders.feature:21:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 5 features/cylinders.feature:22:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 5 features/cylinders.feature:23:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray strikes a cylinder 1 features/cylinders.feature:25:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:17:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(vector(0, 0, 1)) features/cylinders.feature:18:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -5), direction) features/cylinders.feature:19:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:20:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cylinders.feature:21:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 4 features/cylinders.feature:22:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 6 features/cylinders.feature:23:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray strikes a cylinder 2 features/cylinders.feature:25:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:17:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(vector(0.1, 1, 1)) [INFO] [stdout] features/cylinders.feature:18:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0.5, 0, -5), direction) features/cylinders.feature:19:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:20:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/cylinders.feature:21:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 6.80798 features/cylinders.feature:22:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 7.08872 features/cylinders.feature:23:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Normal vector on a cylinder 0 features/cylinders.feature:36:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:32:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← local_normal_at(cyl, point(1, 0, 0)) [INFO] [stdout] features/cylinders.feature:33:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(1, 0, 0) features/cylinders.feature:34:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Normal vector on a cylinder 1 features/cylinders.feature:36:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:32:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← local_normal_at(cyl, point(0, 5, -1)) [INFO] [stdout] features/cylinders.feature:33:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, 0, -1) features/cylinders.feature:34:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Normal vector on a cylinder 2 features/cylinders.feature:36:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:32:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← local_normal_at(cyl, point(0, -2, 1)) [INFO] [stdout] features/cylinders.feature:33:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, 0, 1) features/cylinders.feature:34:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Normal vector on a cylinder 3 features/cylinders.feature:36:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:32:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← local_normal_at(cyl, point(-1, 1, 0)) [INFO] [stdout] features/cylinders.feature:33:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(-1, 0, 0) features/cylinders.feature:34:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The default minimum and maximum for a cylinder [INFO] [stdout] features/cylinders.feature:43:11 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:44:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then cyl.minimum = -infinity features/cylinders.feature:45:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum = infinity features/cylinders.feature:46:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a constrained cylinder 0 [INFO] [stdout] features/cylinders.feature:57:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:49:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:50:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:51:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(point(0, 1.5, 0)) features/cylinders.feature:52:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(1, direction) features/cylinders.feature:53:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:54:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = vector(0.1, 1, 0) features/cylinders.feature:55:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a constrained cylinder 1 [INFO] [stdout] features/cylinders.feature:57:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:49:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:50:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:51:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(point(0, 3, -5)) features/cylinders.feature:52:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(2, direction) features/cylinders.feature:53:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:54:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = vector(0, 0, 1) features/cylinders.feature:55:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a constrained cylinder 2 [INFO] [stdout] features/cylinders.feature:57:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:49:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:50:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:51:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(point(0, 0, -5)) features/cylinders.feature:52:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(3, direction) features/cylinders.feature:53:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:54:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = vector(0, 0, 1) features/cylinders.feature:55:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a constrained cylinder 3 [INFO] [stdout] features/cylinders.feature:57:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:49:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:50:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:51:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(point(0, 2, -5)) features/cylinders.feature:52:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(4, direction) features/cylinders.feature:53:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:54:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = vector(0, 0, 1) features/cylinders.feature:55:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a constrained cylinder 4 [INFO] [stdout] features/cylinders.feature:57:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:49:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:50:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:51:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(point(0, 1, -5)) features/cylinders.feature:52:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(5, direction) features/cylinders.feature:53:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:54:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = vector(0, 0, 1) features/cylinders.feature:55:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a constrained cylinder 5 [INFO] [stdout] features/cylinders.feature:57:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:49:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:50:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:51:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(point(0, 1.5, -2)) [INFO] [stdout] features/cylinders.feature:52:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(6, direction) features/cylinders.feature:53:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:54:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = vector(0, 0, 1) features/cylinders.feature:55:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The default closed value for a cylinder [INFO] [stdout] features/cylinders.feature:66:11 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:67:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then cyl.closed = false features/cylinders.feature:68:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting the caps of a closed cylinder 0 [INFO] [stdout] features/cylinders.feature:80:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:71:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:72:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:73:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.closed ← true features/cylinders.feature:74:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(point(0, 3, 0)) features/cylinders.feature:75:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(1, direction) features/cylinders.feature:76:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:77:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = vector(0, -1, 0) features/cylinders.feature:78:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting the caps of a closed cylinder 1 [INFO] [stdout] features/cylinders.feature:80:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:71:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:72:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:73:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.closed ← true features/cylinders.feature:74:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(point(0, 3, -2)) features/cylinders.feature:75:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(2, direction) features/cylinders.feature:76:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:77:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = vector(0, -1, 2) features/cylinders.feature:78:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting the caps of a closed cylinder 2 [INFO] [stdout] features/cylinders.feature:80:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:71:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:72:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:73:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.closed ← true features/cylinders.feature:74:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(point(0, 4, -2)) features/cylinders.feature:75:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(3, direction) features/cylinders.feature:76:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:77:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = vector(0, -1, 1) features/cylinders.feature:78:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting the caps of a closed cylinder 3 [INFO] [stdout] features/cylinders.feature:80:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:71:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:72:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:73:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.closed ← true features/cylinders.feature:74:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← normalize(point(0, -1, -2)) features/cylinders.feature:75:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(5, direction) features/cylinders.feature:76:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(cyl, r) features/cylinders.feature:77:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = vector(0, 1, 1) features/cylinders.feature:78:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal vector on a cylinder's end caps 0 [INFO] [stdout] features/cylinders.feature:96:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:89:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:90:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:91:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.closed ← true features/cylinders.feature:92:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← local_normal_at(cyl, point(0, 1, 0)) [INFO] [stdout] features/cylinders.feature:93:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, -1, 0) features/cylinders.feature:94:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal vector on a cylinder's end caps 1 [INFO] [stdout] features/cylinders.feature:96:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:89:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:90:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:91:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.closed ← true features/cylinders.feature:92:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← local_normal_at(cyl, point(0.5, 1, 0)) [INFO] [stdout] features/cylinders.feature:93:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, -1, 0) features/cylinders.feature:94:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal vector on a cylinder's end caps 2 [INFO] [stdout] features/cylinders.feature:96:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:89:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:90:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:91:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.closed ← true features/cylinders.feature:92:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← local_normal_at(cyl, point(0, 1, 0.5)) [INFO] [stdout] features/cylinders.feature:93:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, -1, 0) features/cylinders.feature:94:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal vector on a cylinder's end caps 3 [INFO] [stdout] features/cylinders.feature:96:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:89:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:90:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:91:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.closed ← true features/cylinders.feature:92:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← local_normal_at(cyl, point(0, 2, 0)) [INFO] [stdout] features/cylinders.feature:93:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, 1, 0) features/cylinders.feature:94:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal vector on a cylinder's end caps 4 [INFO] [stdout] features/cylinders.feature:96:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:89:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:90:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:91:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.closed ← true features/cylinders.feature:92:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← local_normal_at(cyl, point(0.5, 2, 0)) [INFO] [stdout] features/cylinders.feature:93:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, 1, 0) features/cylinders.feature:94:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal vector on a cylinder's end caps 5 [INFO] [stdout] features/cylinders.feature:96:12 [INFO] [stdout] - Given cyl ← cylinder() features/cylinders.feature:89:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.minimum ← 1 features/cylinders.feature:90:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.maximum ← 2 features/cylinders.feature:91:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cyl.closed ← true features/cylinders.feature:92:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← local_normal_at(cyl, point(0, 2, 0.5)) [INFO] [stdout] features/cylinders.feature:93:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, 1, 0) features/cylinders.feature:94:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Groups features/groups.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: Creating a new group features/groups.feature:3:11 [INFO] [stdout] - Given g ← group() features/groups.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then g.transform = identity_matrix features/groups.feature:5:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And g is empty features/groups.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Adding a child to a group features/groups.feature:8:11 [INFO] [stdout] - Given g ← group() features/groups.feature:9:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← test_shape() features/groups.feature:10:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When add_child(g, s) features/groups.feature:11:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then g is not empty features/groups.feature:12:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And g includes s features/groups.feature:13:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s.parent = g features/groups.feature:14:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a ray with an empty group features/groups.feature:16:11 [INFO] [stdout] - Given g ← group() features/groups.feature:17:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, 0), vector(0, 0, 1)) features/groups.feature:18:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(g, r) features/groups.feature:19:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs is empty features/groups.feature:20:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a ray with a nonempty group [INFO] [stdout] features/groups.feature:22:11 [INFO] [stdout] - Given g ← group() features/groups.feature:23:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s1 ← sphere() features/groups.feature:24:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s2 ← sphere() features/groups.feature:25:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(s2, translation(0, 0, -3)) features/groups.feature:26:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s3 ← sphere() features/groups.feature:27:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(s3, translation(5, 0, 0)) features/groups.feature:28:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And add_child(g, s1) features/groups.feature:29:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And add_child(g, s2) features/groups.feature:30:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And add_child(g, s3) features/groups.feature:31:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When r ← ray(point(0, 0, -5), vector(0, 0, 1)) features/groups.feature:32:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← local_intersect(g, r) features/groups.feature:33:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 4 features/groups.feature:34:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].object = s2 features/groups.feature:35:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].object = s2 features/groups.feature:36:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[2].object = s1 features/groups.feature:37:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[3].object = s1 features/groups.feature:38:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a transformed group features/groups.feature:40:11 [INFO] [stdout] - Given g ← group() features/groups.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(g, scaling(2, 2, 2)) features/groups.feature:42:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← sphere() features/groups.feature:43:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(s, translation(5, 0, 0)) features/groups.feature:44:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And add_child(g, s) features/groups.feature:45:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When r ← ray(point(10, 0, -10), vector(0, 0, 1)) [INFO] [stdout] features/groups.feature:46:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersect(g, r) features/groups.feature:47:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/groups.feature:48:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Intersections features/intersections.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: An intersection encapsulates t and object [INFO] [stdout] features/intersections.feature:3:11 [INFO] [stdout] - Given s ← sphere() features/intersections.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When i ← intersection(3.5, s) features/intersections.feature:5:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then i.t = 3.5 features/intersections.feature:6:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i.object = s features/intersections.feature:7:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Precomputing the state of an intersection [INFO] [stdout] features/intersections.feature:9:11 [INFO] [stdout] - Given r ← ray(point(0, 0, -5), vector(0, 0, 1)) [INFO] [stdout] features/intersections.feature:10:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← sphere() features/intersections.feature:11:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i ← intersection(4, shape) features/intersections.feature:12:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(i, r) features/intersections.feature:13:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then comps.t = i.t features/intersections.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.object = i.object features/intersections.feature:15:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.point = point(0, 0, -1) features/intersections.feature:16:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.eyev = vector(0, 0, -1) features/intersections.feature:17:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.normalv = vector(0, 0, -1) features/intersections.feature:18:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Precomputing the reflection vector [INFO] [stdout] features/intersections.feature:20:11 [INFO] [stdout] - Given shape ← plane() features/intersections.feature:21:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 1, -1), vector(0, -√2/2, √2/2)) [INFO] [stdout] features/intersections.feature:22:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i ← intersection(√2, shape) features/intersections.feature:23:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(i, r) features/intersections.feature:24:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then comps.reflectv = vector(0, √2/2, √2/2) [INFO] [stdout] features/intersections.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The hit, when an intersection occurs on the outside [INFO] [stdout] features/intersections.feature:27:11 [INFO] [stdout] - Given r ← ray(point(0, 0, -5), vector(0, 0, 1)) [INFO] [stdout] features/intersections.feature:28:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← sphere() features/intersections.feature:29:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i ← intersection(4, shape) features/intersections.feature:30:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(i, r) features/intersections.feature:31:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then comps.inside = false features/intersections.feature:32:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The hit, when an intersection occurs on the inside [INFO] [stdout] features/intersections.feature:34:11 [INFO] [stdout] - Given r ← ray(point(0, 0, 0), vector(0, 0, 1)) [INFO] [stdout] features/intersections.feature:35:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← sphere() features/intersections.feature:36:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i ← intersection(1, shape) features/intersections.feature:37:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(i, r) features/intersections.feature:38:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then comps.point = point(0, 0, 1) features/intersections.feature:39:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.eyev = vector(0, 0, -1) features/intersections.feature:40:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.inside = true features/intersections.feature:41:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.normalv = vector(0, 0, -1) features/intersections.feature:43:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The hit should offset the point features/intersections.feature:45:11 [INFO] [stdout] - Given r ← ray(point(0, 0, -5), vector(0, 0, 1)) [INFO] [stdout] features/intersections.feature:46:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← sphere() with: features/intersections.feature:47:5 [INFO] [stdout] | | | [INFO] [stdout] | transform | translation(0, 0, 1) | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i ← intersection(5, shape) features/intersections.feature:49:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(i, r) features/intersections.feature:50:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then comps.over_point.z < -EPSILON/2 features/intersections.feature:51:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.point.z > comps.over_point.z features/intersections.feature:52:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The under point is offset below the surface [INFO] [stdout] features/intersections.feature:54:11 [INFO] [stdout] - Given r ← ray(point(0, 0, -5), vector(0, 0, 1)) [INFO] [stdout] features/intersections.feature:55:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← glass_sphere() with: features/intersections.feature:56:5 [INFO] [stdout] | | | [INFO] [stdout] | transform | translation(0, 0, 1) | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i ← intersection(5, shape) features/intersections.feature:58:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(i) features/intersections.feature:59:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(i, r, xs) [INFO] [stdout] features/intersections.feature:60:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then comps.under_point.z > EPSILON/2 features/intersections.feature:61:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.point.z < comps.under_point.z features/intersections.feature:62:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Aggregating intersections features/intersections.feature:64:11 [INFO] [stdout] - Given s ← sphere() features/intersections.feature:65:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i1 ← intersection(1, s) features/intersections.feature:66:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i2 ← intersection(2, s) features/intersections.feature:67:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← intersections(i1, i2) features/intersections.feature:68:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/intersections.feature:69:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 1 features/intersections.feature:70:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 2 features/intersections.feature:71:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The hit, when all intersections have positive t [INFO] [stdout] features/intersections.feature:73:11 [INFO] [stdout] - Given s ← sphere() features/intersections.feature:74:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i1 ← intersection(1, s) features/intersections.feature:75:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i2 ← intersection(2, s) features/intersections.feature:76:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(i2, i1) features/intersections.feature:77:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When i ← hit(xs) features/intersections.feature:78:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then i = i1 features/intersections.feature:79:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The hit, when some intersections have negative t [INFO] [stdout] features/intersections.feature:81:11 [INFO] [stdout] - Given s ← sphere() features/intersections.feature:82:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i1 ← intersection(-1, s) features/intersections.feature:83:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i2 ← intersection(1, s) features/intersections.feature:84:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(i2, i1) features/intersections.feature:85:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When i ← hit(xs) features/intersections.feature:86:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then i = i2 features/intersections.feature:87:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The hit, when all intersections have negative t [INFO] [stdout] features/intersections.feature:89:11 [INFO] [stdout] - Given s ← sphere() features/intersections.feature:90:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i1 ← intersection(-2, s) features/intersections.feature:91:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i2 ← intersection(-1, s) features/intersections.feature:92:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(i2, i1) features/intersections.feature:93:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When i ← hit(xs) features/intersections.feature:94:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then i is nothing features/intersections.feature:95:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The hit is always the lowest nonnegative intersection [INFO] [stdout] features/intersections.feature:97:11 [INFO] [stdout] - Given s ← sphere() features/intersections.feature:98:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i1 ← intersection(5, s) features/intersections.feature:99:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i2 ← intersection(7, s) features/intersections.feature:100:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i3 ← intersection(-3, s) features/intersections.feature:101:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i4 ← intersection(2, s) features/intersections.feature:102:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(i1, i2, i3, i4) features/intersections.feature:103:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When i ← hit(xs) features/intersections.feature:104:1 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then i = i4 features/intersections.feature:105:1 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Finding n1 and n2 at various intersections 0 [INFO] [stdout] features/intersections.feature:123:12 [INFO] [stdout] - Given A ← glass_sphere() with: features/intersections.feature:108:3 [INFO] [stdout] | transform | scaling(2, 2, 2) | [INFO] [stdout] | material.refractive_index | 1.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B ← glass_sphere() with: features/intersections.feature:111:5 [INFO] [stdout] | transform | translation(0, 0, -0.25) | [INFO] [stdout] | material.refractive_index | 2.0 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And C ← glass_sphere() with: features/intersections.feature:114:5 [INFO] [stdout] | transform | translation(0, 0, 0.25) | [INFO] [stdout] | material.refractive_index | 2.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -4), vector(0, 0, 1)) [INFO] [stdout] features/intersections.feature:117:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(2:A, 2.75:B, 3.25:C, 4.75:B, 5.25:C, 6:A) [INFO] [stdout] features/intersections.feature:118:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[0], r, xs) [INFO] [stdout] features/intersections.feature:119:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then comps.n1 = 1.0 features/intersections.feature:120:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.n2 = 1.5 features/intersections.feature:121:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Finding n1 and n2 at various intersections 1 [INFO] [stdout] features/intersections.feature:123:12 [INFO] [stdout] - Given A ← glass_sphere() with: features/intersections.feature:108:3 [INFO] [stdout] | transform | scaling(2, 2, 2) | [INFO] [stdout] | material.refractive_index | 1.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B ← glass_sphere() with: features/intersections.feature:111:5 [INFO] [stdout] | transform | translation(0, 0, -0.25) | [INFO] [stdout] | material.refractive_index | 2.0 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And C ← glass_sphere() with: features/intersections.feature:114:5 [INFO] [stdout] | transform | translation(0, 0, 0.25) | [INFO] [stdout] | material.refractive_index | 2.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -4), vector(0, 0, 1)) [INFO] [stdout] features/intersections.feature:117:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(2:A, 2.75:B, 3.25:C, 4.75:B, 5.25:C, 6:A) [INFO] [stdout] features/intersections.feature:118:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[1], r, xs) [INFO] [stdout] features/intersections.feature:119:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then comps.n1 = 1.5 features/intersections.feature:120:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.n2 = 2.0 features/intersections.feature:121:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Finding n1 and n2 at various intersections 2 [INFO] [stdout] features/intersections.feature:123:12 [INFO] [stdout] - Given A ← glass_sphere() with: features/intersections.feature:108:3 [INFO] [stdout] | transform | scaling(2, 2, 2) | [INFO] [stdout] | material.refractive_index | 1.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B ← glass_sphere() with: features/intersections.feature:111:5 [INFO] [stdout] | transform | translation(0, 0, -0.25) | [INFO] [stdout] | material.refractive_index | 2.0 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And C ← glass_sphere() with: features/intersections.feature:114:5 [INFO] [stdout] | transform | translation(0, 0, 0.25) | [INFO] [stdout] | material.refractive_index | 2.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -4), vector(0, 0, 1)) [INFO] [stdout] features/intersections.feature:117:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(2:A, 2.75:B, 3.25:C, 4.75:B, 5.25:C, 6:A) [INFO] [stdout] features/intersections.feature:118:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[2], r, xs) [INFO] [stdout] features/intersections.feature:119:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then comps.n1 = 2.0 features/intersections.feature:120:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.n2 = 2.5 features/intersections.feature:121:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Finding n1 and n2 at various intersections 3 [INFO] [stdout] features/intersections.feature:123:12 [INFO] [stdout] - Given A ← glass_sphere() with: features/intersections.feature:108:3 [INFO] [stdout] | transform | scaling(2, 2, 2) | [INFO] [stdout] | material.refractive_index | 1.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B ← glass_sphere() with: features/intersections.feature:111:5 [INFO] [stdout] | transform | translation(0, 0, -0.25) | [INFO] [stdout] | material.refractive_index | 2.0 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And C ← glass_sphere() with: features/intersections.feature:114:5 [INFO] [stdout] | transform | translation(0, 0, 0.25) | [INFO] [stdout] | material.refractive_index | 2.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -4), vector(0, 0, 1)) [INFO] [stdout] features/intersections.feature:117:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(2:A, 2.75:B, 3.25:C, 4.75:B, 5.25:C, 6:A) [INFO] [stdout] features/intersections.feature:118:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[3], r, xs) [INFO] [stdout] features/intersections.feature:119:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then comps.n1 = 2.5 features/intersections.feature:120:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.n2 = 2.5 features/intersections.feature:121:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Finding n1 and n2 at various intersections 4 [INFO] [stdout] features/intersections.feature:123:12 [INFO] [stdout] - Given A ← glass_sphere() with: features/intersections.feature:108:3 [INFO] [stdout] | transform | scaling(2, 2, 2) | [INFO] [stdout] | material.refractive_index | 1.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B ← glass_sphere() with: features/intersections.feature:111:5 [INFO] [stdout] | transform | translation(0, 0, -0.25) | [INFO] [stdout] | material.refractive_index | 2.0 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And C ← glass_sphere() with: features/intersections.feature:114:5 [INFO] [stdout] | transform | translation(0, 0, 0.25) | [INFO] [stdout] | material.refractive_index | 2.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -4), vector(0, 0, 1)) [INFO] [stdout] features/intersections.feature:117:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(2:A, 2.75:B, 3.25:C, 4.75:B, 5.25:C, 6:A) [INFO] [stdout] features/intersections.feature:118:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[4], r, xs) [INFO] [stdout] features/intersections.feature:119:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then comps.n1 = 2.5 features/intersections.feature:120:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.n2 = 1.5 features/intersections.feature:121:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Finding n1 and n2 at various intersections 5 [INFO] [stdout] features/intersections.feature:123:12 [INFO] [stdout] - Given A ← glass_sphere() with: features/intersections.feature:108:3 [INFO] [stdout] | transform | scaling(2, 2, 2) | [INFO] [stdout] | material.refractive_index | 1.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B ← glass_sphere() with: features/intersections.feature:111:5 [INFO] [stdout] | transform | translation(0, 0, -0.25) | [INFO] [stdout] | material.refractive_index | 2.0 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And C ← glass_sphere() with: features/intersections.feature:114:5 [INFO] [stdout] | transform | translation(0, 0, 0.25) | [INFO] [stdout] | material.refractive_index | 2.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -4), vector(0, 0, 1)) [INFO] [stdout] features/intersections.feature:117:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(2:A, 2.75:B, 3.25:C, 4.75:B, 5.25:C, 6:A) [INFO] [stdout] features/intersections.feature:118:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[5], r, xs) [INFO] [stdout] features/intersections.feature:119:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then comps.n1 = 1.5 features/intersections.feature:120:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps.n2 = 1.0 features/intersections.feature:121:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The Schlick approximation under total internal reflection [INFO] [stdout] features/intersections.feature:132:11 [INFO] [stdout] - Given shape ← glass_sphere() features/intersections.feature:133:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, √2/2), vector(0, 1, 0)) [INFO] [stdout] features/intersections.feature:134:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(-√2/2:shape, √2/2:shape) [INFO] [stdout] features/intersections.feature:135:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[1], r, xs) [INFO] [stdout] features/intersections.feature:136:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And reflectance ← schlick(comps) features/intersections.feature:137:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then reflectance = 1.0 features/intersections.feature:138:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The Schlick approximation with a perpendicular viewing angle [INFO] [stdout] features/intersections.feature:140:11 [INFO] [stdout] - Given shape ← glass_sphere() features/intersections.feature:141:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, 0), vector(0, 1, 0)) [INFO] [stdout] features/intersections.feature:142:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(-1:shape, 1:shape) [INFO] [stdout] features/intersections.feature:143:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[1], r, xs) [INFO] [stdout] features/intersections.feature:144:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And reflectance ← schlick(comps) features/intersections.feature:145:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then reflectance = 0.04 features/intersections.feature:146:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The Schlick approximation with small angle and n2 > n1 [INFO] [stdout] features/intersections.feature:148:11 [INFO] [stdout] - Given shape ← glass_sphere() features/intersections.feature:149:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0.99, -2), vector(0, 0, 1)) [INFO] [stdout] features/intersections.feature:150:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(1.8589:shape) features/intersections.feature:151:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[0], r, xs) [INFO] [stdout] features/intersections.feature:152:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And reflectance ← schlick(comps) features/intersections.feature:153:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then reflectance = 0.48873 features/intersections.feature:154:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: An intersection can encapsulate `u` and `v` [INFO] [stdout] features/intersections.feature:156:11 [INFO] [stdout] - Given s ← triangle(point(0, 1, 0), point(-1, 0, 0), point(1, 0, 0)) [INFO] [stdout] features/intersections.feature:157:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When i ← intersection_with_uv(3.5, s, 0.2, 0.4) [INFO] [stdout] features/intersections.feature:158:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then i.u = 0.2 features/intersections.feature:159:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i.v = 0.4 features/intersections.feature:160:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Lights features/lights.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: A point light has a position and intensity [INFO] [stdout] features/lights.feature:3:11 [INFO] [stdout] - Given intensity ← color(1, 1, 1) features/lights.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position ← point(0, 0, 0) features/lights.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When light ← point_light(position, intensity) features/lights.feature:6:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then light.position = position features/lights.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And light.intensity = intensity features/lights.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Materials features/materials.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: The default material features/materials.feature:7:11 [INFO] [stdout] - Given m ← material() features/materials.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position ← point(0, 0, 0) features/materials.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given m ← material() features/materials.feature:8:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then m.color = color(1, 1, 1) features/materials.feature:9:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m.ambient = 0.1 features/materials.feature:10:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m.diffuse = 0.9 features/materials.feature:11:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m.specular = 0.9 features/materials.feature:12:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m.shininess = 200.0 features/materials.feature:13:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Reflectivity for the default material [INFO] [stdout] features/materials.feature:15:11 [INFO] [stdout] - Given m ← material() features/materials.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position ← point(0, 0, 0) features/materials.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given m ← material() features/materials.feature:16:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then m.reflective = 0.0 features/materials.feature:17:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Transparency and Refractive Index for the default material [INFO] [stdout] features/materials.feature:19:11 [INFO] [stdout] - Given m ← material() features/materials.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position ← point(0, 0, 0) features/materials.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given m ← material() features/materials.feature:20:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then m.transparency = 0.0 features/materials.feature:21:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m.refractive_index = 1.0 features/materials.feature:22:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Lighting with the eye between the light and the surface [INFO] [stdout] features/materials.feature:24:11 [INFO] [stdout] - Given m ← material() features/materials.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position ← point(0, 0, 0) features/materials.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given eyev ← vector(0, 0, -1) features/materials.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And normalv ← vector(0, 0, -1) features/materials.feature:26:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And light ← point_light(point(0, 0, -10), color(1, 1, 1)) [INFO] [stdout] features/materials.feature:27:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When result ← lighting(m, light, position, eyev, normalv) [INFO] [stdout] features/materials.feature:28:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = color(1.9, 1.9, 1.9) features/materials.feature:29:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Lighting with the eye between light and surface, eye offset 45° [INFO] [stdout] features/materials.feature:31:11 [INFO] [stdout] - Given m ← material() features/materials.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position ← point(0, 0, 0) features/materials.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given eyev ← vector(0, √2/2, -√2/2) features/materials.feature:32:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And normalv ← vector(0, 0, -1) features/materials.feature:33:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And light ← point_light(point(0, 0, -10), color(1, 1, 1)) [INFO] [stdout] features/materials.feature:34:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When result ← lighting(m, light, position, eyev, normalv) [INFO] [stdout] features/materials.feature:35:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = color(1.0, 1.0, 1.0) features/materials.feature:36:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Lighting with eye opposite surface, light offset 45° [INFO] [stdout] features/materials.feature:38:11 [INFO] [stdout] - Given m ← material() features/materials.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position ← point(0, 0, 0) features/materials.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given eyev ← vector(0, 0, -1) features/materials.feature:39:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And normalv ← vector(0, 0, -1) features/materials.feature:40:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And light ← point_light(point(0, 10, -10), color(1, 1, 1)) [INFO] [stdout] features/materials.feature:41:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When result ← lighting(m, light, position, eyev, normalv) [INFO] [stdout] features/materials.feature:42:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = color(0.7364, 0.7364, 0.7364) features/materials.feature:43:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Lighting with eye in the path of the reflection vector [INFO] [stdout] features/materials.feature:45:11 [INFO] [stdout] - Given m ← material() features/materials.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position ← point(0, 0, 0) features/materials.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given eyev ← vector(0, -√2/2, -√2/2) features/materials.feature:46:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And normalv ← vector(0, 0, -1) features/materials.feature:47:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And light ← point_light(point(0, 10, -10), color(1, 1, 1)) [INFO] [stdout] features/materials.feature:48:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When result ← lighting(m, light, position, eyev, normalv) [INFO] [stdout] features/materials.feature:49:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = color(1.6364, 1.6364, 1.6364) features/materials.feature:50:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Lighting with the light behind the surface [INFO] [stdout] features/materials.feature:52:11 [INFO] [stdout] - Given m ← material() features/materials.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position ← point(0, 0, 0) features/materials.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given eyev ← vector(0, 0, -1) features/materials.feature:53:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And normalv ← vector(0, 0, -1) features/materials.feature:54:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And light ← point_light(point(0, 0, 10), color(1, 1, 1)) [INFO] [stdout] features/materials.feature:55:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When result ← lighting(m, light, position, eyev, normalv) [INFO] [stdout] features/materials.feature:56:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = color(0.1, 0.1, 0.1) features/materials.feature:57:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Lighting with the surface in shadow features/materials.feature:59:11 [INFO] [stdout] - Given m ← material() features/materials.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position ← point(0, 0, 0) features/materials.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given eyev ← vector(0, 0, -1) features/materials.feature:60:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And normalv ← vector(0, 0, -1) features/materials.feature:61:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And light ← point_light(point(0, 0, -10), color(1, 1, 1)) [INFO] [stdout] features/materials.feature:62:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And in_shadow ← true features/materials.feature:63:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When result ← lighting(m, light, position, eyev, normalv, in_shadow) [INFO] [stdout] features/materials.feature:64:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then result = color(0.1, 0.1, 0.1) features/materials.feature:65:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Lighting with a pattern applied features/materials.feature:67:11 [INFO] [stdout] - Given m ← material() features/materials.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position ← point(0, 0, 0) features/materials.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given m.pattern ← stripe_pattern(color(1, 1, 1), color(0, 0, 0)) [INFO] [stdout] features/materials.feature:68:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m.ambient ← 1 features/materials.feature:69:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m.diffuse ← 0 features/materials.feature:70:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m.specular ← 0 features/materials.feature:71:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And eyev ← vector(0, 0, -1) features/materials.feature:72:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And normalv ← vector(0, 0, -1) features/materials.feature:73:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And light ← point_light(point(0, 0, -10), color(1, 1, 1)) [INFO] [stdout] features/materials.feature:74:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When c1 ← lighting(m, light, point(0.9, 0, 0), eyev, normalv, false) [INFO] [stdout] features/materials.feature:75:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c2 ← lighting(m, light, point(1.1, 0, 0), eyev, normalv, false) [INFO] [stdout] features/materials.feature:76:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c1 = color(1, 1, 1) features/materials.feature:77:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c2 = color(0, 0, 0) features/materials.feature:78:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Matrices features/matrices.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: Constructing and inspecting a 4x4 matrix [INFO] [stdout] features/matrices.feature:3:11 [INFO] [stdout] - Given the following 4x4 matrix M: features/matrices.feature:4:3 [INFO] [stdout] | 1 | 2 | 3 | 4 | [INFO] [stdout] | 5.5 | 6.5 | 7.5 | 8.5 | [INFO] [stdout] | 9 | 10 | 11 | 12 | [INFO] [stdout] | 13.5 | 14.5 | 15.5 | 16.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then M[0,0] = 1 features/matrices.feature:9:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And M[0,3] = 4 features/matrices.feature:10:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And M[1,0] = 5.5 features/matrices.feature:11:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And M[1,2] = 7.5 features/matrices.feature:12:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And M[2,2] = 11 features/matrices.feature:13:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And M[3,0] = 13.5 features/matrices.feature:14:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And M[3,2] = 15.5 features/matrices.feature:15:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A 2x2 matrix ought to be representable [INFO] [stdout] features/matrices.feature:17:11 [INFO] [stdout] - Given the following 2x2 matrix M: features/matrices.feature:18:3 [INFO] [stdout] | -3 | 5 | [INFO] [stdout] | 1 | -2 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then M[0,0] = -3 features/matrices.feature:21:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And M[0,1] = 5 features/matrices.feature:22:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And M[1,0] = 1 features/matrices.feature:23:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And M[1,1] = -2 features/matrices.feature:24:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A 3x3 matrix ought to be representable [INFO] [stdout] features/matrices.feature:26:11 [INFO] [stdout] - Given the following 3x3 matrix M: features/matrices.feature:27:3 [INFO] [stdout] | -3 | 5 | 0 | [INFO] [stdout] | 1 | -2 | -7 | [INFO] [stdout] | 0 | 1 | 1 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then M[0,0] = -3 features/matrices.feature:31:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And M[1,1] = -2 features/matrices.feature:32:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And M[2,2] = 1 features/matrices.feature:33:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Matrix equality with identical matrices [INFO] [stdout] features/matrices.feature:35:11 [INFO] [stdout] - Given the following matrix A: features/matrices.feature:36:3 [INFO] [stdout] | 1 | 2 | 3 | 4 | [INFO] [stdout] | 5 | 6 | 7 | 8 | [INFO] [stdout] | 9 | 8 | 7 | 6 | [INFO] [stdout] | 5 | 4 | 3 | 2 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And the following matrix B: features/matrices.feature:41:5 [INFO] [stdout] | 1 | 2 | 3 | 4 | [INFO] [stdout] | 5 | 6 | 7 | 8 | [INFO] [stdout] | 9 | 8 | 7 | 6 | [INFO] [stdout] | 5 | 4 | 3 | 2 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then A = B features/matrices.feature:46:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Matrix equality with different matrices [INFO] [stdout] features/matrices.feature:48:11 [INFO] [stdout] - Given the following matrix A: features/matrices.feature:49:3 [INFO] [stdout] | 1 | 2 | 3 | 4 | [INFO] [stdout] | 5 | 6 | 7 | 8 | [INFO] [stdout] | 9 | 8 | 7 | 6 | [INFO] [stdout] | 5 | 4 | 3 | 2 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And the following matrix B: features/matrices.feature:54:5 [INFO] [stdout] | 2 | 3 | 4 | 5 | [INFO] [stdout] | 6 | 7 | 8 | 9 | [INFO] [stdout] | 8 | 7 | 6 | 5 | [INFO] [stdout] | 4 | 3 | 2 | 1 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then A != B features/matrices.feature:59:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Multiplying two matrices features/matrices.feature:61:11 [INFO] [stdout] - Given the following matrix A: features/matrices.feature:62:3 [INFO] [stdout] | 1 | 2 | 3 | 4 | [INFO] [stdout] | 5 | 6 | 7 | 8 | [INFO] [stdout] | 9 | 8 | 7 | 6 | [INFO] [stdout] | 5 | 4 | 3 | 2 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And the following matrix B: features/matrices.feature:67:5 [INFO] [stdout] | -2 | 1 | 2 | 3 | [INFO] [stdout] | 3 | 2 | 1 | -1 | [INFO] [stdout] | 4 | 3 | 6 | 5 | [INFO] [stdout] | 1 | 2 | 7 | 8 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then A * B is the following 4x4 matrix: features/matrices.feature:72:3 [INFO] [stdout] | 20 | 22 | 50 | 48 | [INFO] [stdout] | 44 | 54 | 114 | 108 | [INFO] [stdout] | 40 | 58 | 110 | 102 | [INFO] [stdout] | 16 | 26 | 46 | 42 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A matrix multiplied by a tuple features/matrices.feature:78:11 [INFO] [stdout] - Given the following matrix A: features/matrices.feature:79:3 [INFO] [stdout] | 1 | 2 | 3 | 4 | [INFO] [stdout] | 2 | 4 | 4 | 2 | [INFO] [stdout] | 8 | 6 | 4 | 1 | [INFO] [stdout] | 0 | 0 | 0 | 1 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And b ← tuple(1, 2, 3, 1) features/matrices.feature:84:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then A * b = tuple(18, 24, 33, 1) features/matrices.feature:85:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Multiplying a matrix by the identity matrix [INFO] [stdout] features/matrices.feature:87:11 [INFO] [stdout] - Given the following matrix A: features/matrices.feature:88:3 [INFO] [stdout] | 0 | 1 | 2 | 4 | [INFO] [stdout] | 1 | 2 | 4 | 8 | [INFO] [stdout] | 2 | 4 | 8 | 16 | [INFO] [stdout] | 4 | 8 | 16 | 32 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then A * identity_matrix = A features/matrices.feature:93:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Multiplying the identity matrix by a tuple [INFO] [stdout] features/matrices.feature:95:11 [INFO] [stdout] - Given a ← tuple(1, 2, 3, 4) features/matrices.feature:96:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then identity_matrix * a = a features/matrices.feature:97:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Transposing a matrix features/matrices.feature:99:11 [INFO] [stdout] - Given the following matrix A: features/matrices.feature:100:3 [INFO] [stdout] | 0 | 9 | 3 | 0 | [INFO] [stdout] | 9 | 8 | 0 | 8 | [INFO] [stdout] | 1 | 8 | 5 | 3 | [INFO] [stdout] | 0 | 0 | 5 | 8 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then transpose(A) is the following matrix: features/matrices.feature:105:3 [INFO] [stdout] | 0 | 9 | 1 | 0 | [INFO] [stdout] | 9 | 8 | 8 | 0 | [INFO] [stdout] | 3 | 0 | 5 | 5 | [INFO] [stdout] | 0 | 8 | 3 | 8 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Transposing the identity matrix features/matrices.feature:111:11 [INFO] [stdout] - Given A ← transpose(identity_matrix) features/matrices.feature:112:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then A = identity_matrix features/matrices.feature:113:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Calculating the determinant of a 2x2 matrix [INFO] [stdout] features/matrices.feature:115:11 [INFO] [stdout] - Given the following 2x2 matrix A: features/matrices.feature:116:3 [INFO] [stdout] | 1 | 5 | [INFO] [stdout] | -3 | 2 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then determinant(A) = 17 features/matrices.feature:119:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A submatrix of a 3x3 matrix is a 2x2 matrix [INFO] [stdout] features/matrices.feature:121:11 [INFO] [stdout] - Given the following 3x3 matrix A: features/matrices.feature:122:3 [INFO] [stdout] | 1 | 5 | 0 | [INFO] [stdout] | -3 | 2 | 7 | [INFO] [stdout] | 0 | 6 | -3 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then submatrix(A, 0, 2) is the following 2x2 matrix: [INFO] [stdout] features/matrices.feature:126:3 [INFO] [stdout] | -3 | 2 | [INFO] [stdout] | 0 | 6 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A submatrix of a 4x4 matrix is a 3x3 matrix [INFO] [stdout] features/matrices.feature:130:11 [INFO] [stdout] - Given the following 4x4 matrix A: features/matrices.feature:131:3 [INFO] [stdout] | -6 | 1 | 1 | 6 | [INFO] [stdout] | -8 | 5 | 8 | 6 | [INFO] [stdout] | -1 | 0 | 8 | 2 | [INFO] [stdout] | -7 | 1 | -1 | 1 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then submatrix(A, 2, 1) is the following 3x3 matrix: [INFO] [stdout] features/matrices.feature:136:3 [INFO] [stdout] | -6 | 1 | 6 | [INFO] [stdout] | -8 | 8 | 6 | [INFO] [stdout] | -7 | -1 | 1 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Calculating a minor of a 3x3 matrix features/matrices.feature:141:11 [INFO] [stdout] - Given the following 3x3 matrix A: features/matrices.feature:142:3 [INFO] [stdout] | 3 | 5 | 0 | [INFO] [stdout] | 2 | -1 | -7 | [INFO] [stdout] | 6 | -1 | 5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B ← submatrix(A, 1, 0) features/matrices.feature:146:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then determinant(B) = 25 features/matrices.feature:147:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And minor(A, 1, 0) = 25 features/matrices.feature:148:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Calculating a cofactor of a 3x3 matrix [INFO] [stdout] features/matrices.feature:150:11 [INFO] [stdout] - Given the following 3x3 matrix A: features/matrices.feature:151:3 [INFO] [stdout] | 3 | 5 | 0 | [INFO] [stdout] | 2 | -1 | -7 | [INFO] [stdout] | 6 | -1 | 5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then minor(A, 0, 0) = -12 features/matrices.feature:155:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cofactor(A, 0, 0) = -12 features/matrices.feature:156:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And minor(A, 1, 0) = 25 features/matrices.feature:157:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cofactor(A, 1, 0) = -25 features/matrices.feature:158:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Calculating the determinant of a 3x3 matrix [INFO] [stdout] features/matrices.feature:160:11 [INFO] [stdout] - Given the following 3x3 matrix A: features/matrices.feature:161:3 [INFO] [stdout] | 1 | 2 | 6 | [INFO] [stdout] | -5 | 8 | -4 | [INFO] [stdout] | 2 | 6 | 4 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then cofactor(A, 0, 0) = 56 features/matrices.feature:165:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cofactor(A, 0, 1) = 12 features/matrices.feature:166:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cofactor(A, 0, 2) = -46 features/matrices.feature:167:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And determinant(A) = -196 features/matrices.feature:168:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Calculating the determinant of a 4x4 matrix [INFO] [stdout] features/matrices.feature:170:11 [INFO] [stdout] - Given the following 4x4 matrix A: features/matrices.feature:171:3 [INFO] [stdout] | -2 | -8 | 3 | 5 | [INFO] [stdout] | -3 | 1 | 7 | 3 | [INFO] [stdout] | 1 | 2 | -9 | 6 | [INFO] [stdout] | -6 | 7 | 7 | -9 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then cofactor(A, 0, 0) = 690 features/matrices.feature:176:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cofactor(A, 0, 1) = 447 features/matrices.feature:177:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cofactor(A, 0, 2) = 210 features/matrices.feature:178:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cofactor(A, 0, 3) = 51 features/matrices.feature:179:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And determinant(A) = -4071 features/matrices.feature:180:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Testing an invertible matrix for invertibility [INFO] [stdout] features/matrices.feature:182:11 [INFO] [stdout] - Given the following 4x4 matrix A: features/matrices.feature:183:3 [INFO] [stdout] | 6 | 4 | 4 | 4 | [INFO] [stdout] | 5 | 5 | 7 | 6 | [INFO] [stdout] | 4 | -9 | 3 | -7 | [INFO] [stdout] | 9 | 1 | 7 | -6 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then determinant(A) = -2120 features/matrices.feature:188:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And A is invertible features/matrices.feature:189:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Testing a noninvertible matrix for invertibility [INFO] [stdout] features/matrices.feature:191:11 [INFO] [stdout] - Given the following 4x4 matrix A: features/matrices.feature:192:3 [INFO] [stdout] | -4 | 2 | -2 | -3 | [INFO] [stdout] | 9 | 6 | 2 | 6 | [INFO] [stdout] | 0 | -5 | 1 | -5 | [INFO] [stdout] | 0 | 0 | 0 | 0 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then determinant(A) = 0 features/matrices.feature:197:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And A is not invertible features/matrices.feature:198:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Calculating the inverse of a matrix features/matrices.feature:200:11 [INFO] [stdout] - Given the following 4x4 matrix A: features/matrices.feature:201:3 [INFO] [stdout] | -5 | 2 | 6 | -8 | [INFO] [stdout] | 1 | -5 | 1 | 8 | [INFO] [stdout] | 7 | 7 | -6 | -7 | [INFO] [stdout] | 1 | -3 | 7 | 4 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B ← inverse(A) features/matrices.feature:206:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then determinant(A) = 532 features/matrices.feature:207:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cofactor(A, 2, 3) = -160 features/matrices.feature:208:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B[3,2] = -160/532 features/matrices.feature:209:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cofactor(A, 3, 2) = 105 features/matrices.feature:210:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B[2,3] = 105/532 features/matrices.feature:211:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B is the following 4x4 matrix: features/matrices.feature:212:5 [INFO] [stdout] | 0.21805 | 0.45113 | 0.24060 | -0.04511 | [INFO] [stdout] | -0.80827 | -1.45677 | -0.44361 | 0.52068 | [INFO] [stdout] | -0.07895 | -0.22368 | -0.05263 | 0.19737 | [INFO] [stdout] | -0.52256 | -0.81391 | -0.30075 | 0.30639 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Calculating the inverse of another matrix [INFO] [stdout] features/matrices.feature:218:11 [INFO] [stdout] - Given the following 4x4 matrix A: features/matrices.feature:219:3 [INFO] [stdout] | 8 | -5 | 9 | 2 | [INFO] [stdout] | 7 | 5 | 6 | 1 | [INFO] [stdout] | -6 | 0 | 9 | 6 | [INFO] [stdout] | -3 | 0 | -9 | -4 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then inverse(A) is the following 4x4 matrix: [INFO] [stdout] features/matrices.feature:224:3 [INFO] [stdout] | -0.15385 | -0.15385 | -0.28205 | -0.53846 | [INFO] [stdout] | -0.07692 | 0.12308 | 0.02564 | 0.03077 | [INFO] [stdout] | 0.35897 | 0.35897 | 0.43590 | 0.92308 | [INFO] [stdout] | -0.69231 | -0.69231 | -0.76923 | -1.92308 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Calculating the inverse of a third matrix [INFO] [stdout] features/matrices.feature:230:11 [INFO] [stdout] - Given the following 4x4 matrix A: features/matrices.feature:231:3 [INFO] [stdout] | 9 | 3 | 0 | 9 | [INFO] [stdout] | -5 | -2 | -6 | -3 | [INFO] [stdout] | -4 | 9 | 6 | 4 | [INFO] [stdout] | -7 | 6 | 6 | 2 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then inverse(A) is the following 4x4 matrix: [INFO] [stdout] features/matrices.feature:236:3 [INFO] [stdout] | -0.04074 | -0.07778 | 0.14444 | -0.22222 | [INFO] [stdout] | -0.07778 | 0.03333 | 0.36667 | -0.33333 | [INFO] [stdout] | -0.02901 | -0.14630 | -0.10926 | 0.12963 | [INFO] [stdout] | 0.17778 | 0.06667 | -0.26667 | 0.33333 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Multiplying a product by its inverse [INFO] [stdout] features/matrices.feature:242:11 [INFO] [stdout] - Given the following 4x4 matrix A: features/matrices.feature:243:3 [INFO] [stdout] | 3 | -9 | 7 | 3 | [INFO] [stdout] | 3 | -8 | 2 | -9 | [INFO] [stdout] | -4 | 4 | 4 | 1 | [INFO] [stdout] | -6 | 5 | -1 | 1 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And the following 4x4 matrix B: features/matrices.feature:248:5 [INFO] [stdout] | 8 | 2 | 2 | 2 | [INFO] [stdout] | 3 | -1 | 7 | 0 | [INFO] [stdout] | 7 | 0 | 5 | 4 | [INFO] [stdout] | 6 | -2 | 0 | 5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And C ← A * B features/matrices.feature:253:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then C * inverse(B) = A features/matrices.feature:254:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: OBJ File Parser features/obj_file.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: Ignoring unrecognized lines features/obj_file.feature:3:11 [INFO] [stdout] - Given gibberish ← a file containing: features/obj_file.feature:4:3 [INFO] [stdout] """ [INFO] [stdout] There was a young lady named Bright [INFO] [stdout] who traveled much faster than light. [INFO] [stdout] She set out one day [INFO] [stdout] in a relative way, [INFO] [stdout] and came back the previous night. [INFO] [stdout] """ [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When parser ← parse_obj_file(gibberish) features/obj_file.feature:12:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then parser should have ignored 5 lines features/obj_file.feature:13:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Vertex records features/obj_file.feature:15:11 [INFO] [stdout] - Given file ← a file containing: features/obj_file.feature:16:3 [INFO] [stdout] """ [INFO] [stdout] v -1 1 0 [INFO] [stdout] v -1.0000 0.5000 0.0000 [INFO] [stdout] v 1 0 0 [INFO] [stdout] v 1 1 0 [INFO] [stdout] """ [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When parser ← parse_obj_file(file) features/obj_file.feature:23:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then parser.vertices[1] = point(-1, 1, 0) features/obj_file.feature:24:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And parser.vertices[2] = point(-1, 0.5, 0) features/obj_file.feature:25:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And parser.vertices[3] = point(1, 0, 0) features/obj_file.feature:26:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And parser.vertices[4] = point(1, 1, 0) features/obj_file.feature:27:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Parsing triangle faces features/obj_file.feature:29:11 [INFO] [stdout] - Given file ← a file containing: features/obj_file.feature:30:3 [INFO] [stdout] """ [INFO] [stdout] v -1 1 0 [INFO] [stdout] v -1 0 0 [INFO] [stdout] v 1 0 0 [INFO] [stdout] v 1 1 0 [INFO] [stdout] [INFO] [stdout] f 1 2 3 [INFO] [stdout] f 1 3 4 [INFO] [stdout] """ [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When parser ← parse_obj_file(file) features/obj_file.feature:40:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And g ← parser.default_group features/obj_file.feature:41:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1 ← first child of g features/obj_file.feature:42:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2 ← second child of g features/obj_file.feature:43:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then t1.p1 = parser.vertices[1] features/obj_file.feature:44:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1.p2 = parser.vertices[2] features/obj_file.feature:45:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1.p3 = parser.vertices[3] features/obj_file.feature:46:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2.p1 = parser.vertices[1] features/obj_file.feature:47:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2.p2 = parser.vertices[3] features/obj_file.feature:48:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2.p3 = parser.vertices[4] features/obj_file.feature:49:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Triangulating polygons features/obj_file.feature:51:11 [INFO] [stdout] - Given file ← a file containing: features/obj_file.feature:52:3 [INFO] [stdout] """ [INFO] [stdout] v -1 1 0 [INFO] [stdout] v -1 0 0 [INFO] [stdout] v 1 0 0 [INFO] [stdout] v 1 1 0 [INFO] [stdout] v 0 2 0 [INFO] [stdout] [INFO] [stdout] f 1 2 3 4 5 [INFO] [stdout] """ [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When parser ← parse_obj_file(file) features/obj_file.feature:62:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And g ← parser.default_group features/obj_file.feature:63:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1 ← first child of g features/obj_file.feature:64:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2 ← second child of g features/obj_file.feature:65:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t3 ← third child of g features/obj_file.feature:66:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then t1.p1 = parser.vertices[1] features/obj_file.feature:67:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1.p2 = parser.vertices[2] features/obj_file.feature:68:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1.p3 = parser.vertices[3] features/obj_file.feature:69:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2.p1 = parser.vertices[1] features/obj_file.feature:70:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2.p2 = parser.vertices[3] features/obj_file.feature:71:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2.p3 = parser.vertices[4] features/obj_file.feature:72:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t3.p1 = parser.vertices[1] features/obj_file.feature:73:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t3.p2 = parser.vertices[4] features/obj_file.feature:74:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t3.p3 = parser.vertices[5] features/obj_file.feature:75:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Triangles in groups features/obj_file.feature:77:11 [INFO] [stdout] - Given file ← the file "triangles.obj" features/obj_file.feature:78:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When parser ← parse_obj_file(file) features/obj_file.feature:79:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And g1 ← "FirstGroup" from parser features/obj_file.feature:80:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And g2 ← "SecondGroup" from parser features/obj_file.feature:81:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1 ← first child of g1 features/obj_file.feature:82:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2 ← first child of g2 features/obj_file.feature:83:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then t1.p1 = parser.vertices[1] features/obj_file.feature:84:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1.p2 = parser.vertices[2] features/obj_file.feature:85:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1.p3 = parser.vertices[3] features/obj_file.feature:86:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2.p1 = parser.vertices[1] features/obj_file.feature:87:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2.p2 = parser.vertices[3] features/obj_file.feature:88:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2.p3 = parser.vertices[4] features/obj_file.feature:89:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Converting an OBJ file to a group features/obj_file.feature:91:11 [INFO] [stdout] - Given file ← the file "triangles.obj" features/obj_file.feature:92:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And parser ← parse_obj_file(file) features/obj_file.feature:93:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When g ← obj_to_group(parser) features/obj_file.feature:94:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then g includes "FirstGroup" from parser features/obj_file.feature:95:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And g includes "SecondGroup" from parser features/obj_file.feature:96:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Vertex normal records features/obj_file.feature:98:11 [INFO] [stdout] - Given file ← a file containing: features/obj_file.feature:99:3 [INFO] [stdout] """ [INFO] [stdout] vn 0 0 1 [INFO] [stdout] vn 0.707 0 -0.707 [INFO] [stdout] vn 1 2 3 [INFO] [stdout] """ [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When parser ← parse_obj_file(file) features/obj_file.feature:105:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then parser.normals[1] = vector(0, 0, 1) features/obj_file.feature:106:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And parser.normals[2] = vector(0.707, 0, -0.707) [INFO] [stdout] features/obj_file.feature:107:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And parser.normals[3] = vector(1, 2, 3) features/obj_file.feature:108:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Faces with normals features/obj_file.feature:110:11 [INFO] [stdout] - Given file ← a file containing: features/obj_file.feature:111:3 [INFO] [stdout] """ [INFO] [stdout] v 0 1 0 [INFO] [stdout] v -1 0 0 [INFO] [stdout] v 1 0 0 [INFO] [stdout] [INFO] [stdout] vn -1 0 0 [INFO] [stdout] vn 1 0 0 [INFO] [stdout] vn 0 1 0 [INFO] [stdout] [INFO] [stdout] f 1//3 2//1 3//2 [INFO] [stdout] f 1/0/3 2/102/1 3/14/2 [INFO] [stdout] """ [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When parser ← parse_obj_file(file) features/obj_file.feature:124:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And g ← parser.default_group features/obj_file.feature:125:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1 ← first child of g features/obj_file.feature:126:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2 ← second child of g features/obj_file.feature:127:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then t1.p1 = parser.vertices[1] features/obj_file.feature:128:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1.p2 = parser.vertices[2] features/obj_file.feature:129:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1.p3 = parser.vertices[3] features/obj_file.feature:130:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1.n1 = parser.normals[3] features/obj_file.feature:131:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1.n2 = parser.normals[1] features/obj_file.feature:132:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t1.n3 = parser.normals[2] features/obj_file.feature:133:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t2 = t1 features/obj_file.feature:134:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Patterns features/patterns.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: Creating a stripe pattern features/patterns.feature:7:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given pattern ← stripe_pattern(white, black) features/patterns.feature:8:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then pattern.a = white features/patterns.feature:9:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern.b = black features/patterns.feature:10:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A stripe pattern is constant in y features/patterns.feature:12:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given pattern ← stripe_pattern(white, black) features/patterns.feature:13:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then stripe_at(pattern, point(0, 0, 0)) = white [INFO] [stdout] features/patterns.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And stripe_at(pattern, point(0, 1, 0)) = white [INFO] [stdout] features/patterns.feature:15:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And stripe_at(pattern, point(0, 2, 0)) = white [INFO] [stdout] features/patterns.feature:16:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A stripe pattern is constant in z features/patterns.feature:18:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given pattern ← stripe_pattern(white, black) features/patterns.feature:19:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then stripe_at(pattern, point(0, 0, 0)) = white [INFO] [stdout] features/patterns.feature:20:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And stripe_at(pattern, point(0, 0, 1)) = white [INFO] [stdout] features/patterns.feature:21:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And stripe_at(pattern, point(0, 0, 2)) = white [INFO] [stdout] features/patterns.feature:22:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A stripe pattern alternates in x features/patterns.feature:24:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given pattern ← stripe_pattern(white, black) features/patterns.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then stripe_at(pattern, point(0, 0, 0)) = white [INFO] [stdout] features/patterns.feature:26:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And stripe_at(pattern, point(0.9, 0, 0)) = white [INFO] [stdout] features/patterns.feature:27:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And stripe_at(pattern, point(1, 0, 0)) = black [INFO] [stdout] features/patterns.feature:28:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And stripe_at(pattern, point(-0.1, 0, 0)) = black [INFO] [stdout] features/patterns.feature:29:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And stripe_at(pattern, point(-1, 0, 0)) = black [INFO] [stdout] features/patterns.feature:30:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And stripe_at(pattern, point(-1.1, 0, 0)) = white [INFO] [stdout] features/patterns.feature:31:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Stripes with an object transformation [INFO] [stdout] features/patterns.feature:33:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given object ← sphere() features/patterns.feature:34:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(object, scaling(2, 2, 2)) features/patterns.feature:35:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern ← stripe_pattern(white, black) features/patterns.feature:36:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When c ← stripe_at_object(pattern, object, point(1.5, 0, 0)) [INFO] [stdout] features/patterns.feature:37:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = white features/patterns.feature:38:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Stripes with a pattern transformation [INFO] [stdout] features/patterns.feature:40:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given object ← sphere() features/patterns.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern ← stripe_pattern(white, black) features/patterns.feature:42:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_pattern_transform(pattern, scaling(2, 2, 2)) [INFO] [stdout] features/patterns.feature:43:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When c ← stripe_at_object(pattern, object, point(1.5, 0, 0)) [INFO] [stdout] features/patterns.feature:44:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = white features/patterns.feature:45:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Stripes with both an object and a pattern transformation [INFO] [stdout] features/patterns.feature:47:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given object ← sphere() features/patterns.feature:48:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(object, scaling(2, 2, 2)) features/patterns.feature:49:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern ← stripe_pattern(white, black) features/patterns.feature:50:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_pattern_transform(pattern, translation(0.5, 0, 0)) [INFO] [stdout] features/patterns.feature:51:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When c ← stripe_at_object(pattern, object, point(2.5, 0, 0)) [INFO] [stdout] features/patterns.feature:52:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = white features/patterns.feature:53:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The default pattern transformation features/patterns.feature:55:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given pattern ← test_pattern() features/patterns.feature:56:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then pattern.transform = identity_matrix features/patterns.feature:57:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Assigning a transformation features/patterns.feature:59:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given pattern ← test_pattern() features/patterns.feature:60:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When set_pattern_transform(pattern, translation(1, 2, 3)) [INFO] [stdout] features/patterns.feature:61:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then pattern.transform = translation(1, 2, 3) [INFO] [stdout] features/patterns.feature:62:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A pattern with an object transformation [INFO] [stdout] features/patterns.feature:64:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given shape ← sphere() features/patterns.feature:65:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(shape, scaling(2, 2, 2)) features/patterns.feature:66:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern ← test_pattern() features/patterns.feature:67:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When c ← pattern_at_shape(pattern, shape, point(2, 3, 4)) [INFO] [stdout] features/patterns.feature:68:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = color(1, 1.5, 2) features/patterns.feature:69:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A pattern with a pattern transformation [INFO] [stdout] features/patterns.feature:71:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given shape ← sphere() features/patterns.feature:72:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern ← test_pattern() features/patterns.feature:73:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_pattern_transform(pattern, scaling(2, 2, 2)) [INFO] [stdout] features/patterns.feature:74:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When c ← pattern_at_shape(pattern, shape, point(2, 3, 4)) [INFO] [stdout] features/patterns.feature:75:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = color(1, 1.5, 2) features/patterns.feature:76:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A pattern with both an object and a pattern transformation [INFO] [stdout] features/patterns.feature:78:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given shape ← sphere() features/patterns.feature:79:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(shape, scaling(2, 2, 2)) features/patterns.feature:80:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern ← test_pattern() features/patterns.feature:81:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_pattern_transform(pattern, translation(0.5, 1, 1.5)) [INFO] [stdout] features/patterns.feature:82:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When c ← pattern_at_shape(pattern, shape, point(2.5, 3, 3.5)) [INFO] [stdout] features/patterns.feature:83:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = color(0.75, 0.5, 0.25) features/patterns.feature:84:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A gradient linearly interpolates between colors [INFO] [stdout] features/patterns.feature:86:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given pattern ← gradient_pattern(white, black) [INFO] [stdout] features/patterns.feature:87:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then pattern_at(pattern, point(0, 0, 0)) = white [INFO] [stdout] features/patterns.feature:88:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern_at(pattern, point(0.25, 0, 0)) = color(0.75, 0.75, 0.75) [INFO] [stdout] features/patterns.feature:89:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern_at(pattern, point(0.5, 0, 0)) = color(0.5, 0.5, 0.5) [INFO] [stdout] features/patterns.feature:90:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern_at(pattern, point(0.75, 0, 0)) = color(0.25, 0.25, 0.25) [INFO] [stdout] features/patterns.feature:91:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ring should extend in both x and z features/patterns.feature:93:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given pattern ← ring_pattern(white, black) features/patterns.feature:94:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then pattern_at(pattern, point(0, 0, 0)) = white [INFO] [stdout] features/patterns.feature:95:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern_at(pattern, point(1, 0, 0)) = black [INFO] [stdout] features/patterns.feature:96:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern_at(pattern, point(0, 0, 1)) = black [INFO] [stdout] features/patterns.feature:97:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern_at(pattern, point(0.708, 0, 0.708)) = black [INFO] [stdout] features/patterns.feature:99:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Checkers should repeat in x features/patterns.feature:101:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given pattern ← checkers_pattern(white, black) [INFO] [stdout] features/patterns.feature:102:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then pattern_at(pattern, point(0, 0, 0)) = white [INFO] [stdout] features/patterns.feature:103:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern_at(pattern, point(0.99, 0, 0)) = white [INFO] [stdout] features/patterns.feature:104:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern_at(pattern, point(1.01, 0, 0)) = black [INFO] [stdout] features/patterns.feature:105:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Checkers should repeat in y features/patterns.feature:107:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given pattern ← checkers_pattern(white, black) [INFO] [stdout] features/patterns.feature:108:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then pattern_at(pattern, point(0, 0, 0)) = white [INFO] [stdout] features/patterns.feature:109:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern_at(pattern, point(0, 0.99, 0)) = white [INFO] [stdout] features/patterns.feature:110:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern_at(pattern, point(0, 1.01, 0)) = black [INFO] [stdout] features/patterns.feature:111:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Checkers should repeat in z features/patterns.feature:113:11 [INFO] [stdout] - Given black ← color(0, 0, 0) features/patterns.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And white ← color(1, 1, 1) features/patterns.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Given pattern ← checkers_pattern(white, black) [INFO] [stdout] features/patterns.feature:114:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then pattern_at(pattern, point(0, 0, 0)) = white [INFO] [stdout] features/patterns.feature:115:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern_at(pattern, point(0, 0, 0.99)) = white [INFO] [stdout] features/patterns.feature:116:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And pattern_at(pattern, point(0, 0, 1.01)) = black [INFO] [stdout] features/patterns.feature:117:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Planes features/planes.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: The normal of a plane is constant everywhere [INFO] [stdout] features/planes.feature:3:11 [INFO] [stdout] - Given p ← plane() features/planes.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n1 ← local_normal_at(p, point(0, 0, 0)) features/planes.feature:5:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n2 ← local_normal_at(p, point(10, 0, -10)) features/planes.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n3 ← local_normal_at(p, point(-5, 0, 150)) features/planes.feature:7:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n1 = vector(0, 1, 0) features/planes.feature:8:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n2 = vector(0, 1, 0) features/planes.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n3 = vector(0, 1, 0) features/planes.feature:10:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersect with a ray parallel to the plane [INFO] [stdout] features/planes.feature:12:11 [INFO] [stdout] - Given p ← plane() features/planes.feature:13:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 10, 0), vector(0, 0, 1)) features/planes.feature:14:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(p, r) features/planes.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs is empty features/planes.feature:16:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersect with a coplanar ray features/planes.feature:18:11 [INFO] [stdout] - Given p ← plane() features/planes.feature:19:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, 0), vector(0, 0, 1)) features/planes.feature:20:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(p, r) features/planes.feature:21:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs is empty features/planes.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray intersecting a plane from above features/planes.feature:24:11 [INFO] [stdout] - Given p ← plane() features/planes.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 1, 0), vector(0, -1, 0)) features/planes.feature:26:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(p, r) features/planes.feature:27:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 1 features/planes.feature:28:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 1 features/planes.feature:29:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].object = p features/planes.feature:30:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray intersecting a plane from below features/planes.feature:32:11 [INFO] [stdout] - Given p ← plane() features/planes.feature:33:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, -1, 0), vector(0, 1, 0)) features/planes.feature:34:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(p, r) features/planes.feature:35:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 1 features/planes.feature:36:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 1 features/planes.feature:37:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].object = p features/planes.feature:38:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Rays features/rays.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: Creating and querying a ray features/rays.feature:3:11 [INFO] [stdout] - Given origin ← point(1, 2, 3) features/rays.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And direction ← vector(4, 5, 6) features/rays.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When r ← ray(origin, direction) features/rays.feature:6:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then r.origin = origin features/rays.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r.direction = direction features/rays.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Computing a point from a distance features/rays.feature:10:11 [INFO] [stdout] - Given r ← ray(point(2, 3, 4), vector(1, 0, 0)) features/rays.feature:11:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then position(r, 0) = point(2, 3, 4) features/rays.feature:12:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position(r, 1) = point(3, 3, 4) features/rays.feature:13:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position(r, -1) = point(1, 3, 4) features/rays.feature:14:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And position(r, 2.5) = point(4.5, 3, 4) features/rays.feature:15:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Translating a ray features/rays.feature:17:11 [INFO] [stdout] - Given r ← ray(point(1, 2, 3), vector(0, 1, 0)) features/rays.feature:18:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m ← translation(3, 4, 5) features/rays.feature:19:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When r2 ← transform(r, m) features/rays.feature:20:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then r2.origin = point(4, 6, 8) features/rays.feature:21:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r2.direction = vector(0, 1, 0) features/rays.feature:22:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Scaling a ray features/rays.feature:24:11 [INFO] [stdout] - Given r ← ray(point(1, 2, 3), vector(0, 1, 0)) features/rays.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m ← scaling(2, 3, 4) features/rays.feature:26:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When r2 ← transform(r, m) features/rays.feature:27:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then r2.origin = point(2, 6, 12) features/rays.feature:28:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r2.direction = vector(0, 3, 0) features/rays.feature:29:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Abstract Shapes features/shapes.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: The default transformation features/shapes.feature:3:11 [INFO] [stdout] - Given s ← test_shape() features/shapes.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then s.transform = identity_matrix features/shapes.feature:5:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Assigning a transformation features/shapes.feature:7:11 [INFO] [stdout] - Given s ← test_shape() features/shapes.feature:8:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When set_transform(s, translation(2, 3, 4)) features/shapes.feature:9:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then s.transform = translation(2, 3, 4) features/shapes.feature:10:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The default material features/shapes.feature:12:11 [INFO] [stdout] - Given s ← test_shape() features/shapes.feature:13:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When m ← s.material features/shapes.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then m = material() features/shapes.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Assigning a material features/shapes.feature:17:11 [INFO] [stdout] - Given s ← test_shape() features/shapes.feature:18:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m ← material() features/shapes.feature:19:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m.ambient ← 1 features/shapes.feature:20:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When s.material ← m features/shapes.feature:21:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then s.material = m features/shapes.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a scaled shape with a ray features/shapes.feature:24:11 [INFO] [stdout] - Given r ← ray(point(0, 0, -5), vector(0, 0, 1)) [INFO] [stdout] features/shapes.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← test_shape() features/shapes.feature:26:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When set_transform(s, scaling(2, 2, 2)) features/shapes.feature:27:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersect(s, r) features/shapes.feature:28:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then s.saved_ray.origin = point(0, 0, -2.5) features/shapes.feature:29:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s.saved_ray.direction = vector(0, 0, 0.5) features/shapes.feature:30:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a translated shape with a ray [INFO] [stdout] features/shapes.feature:32:11 [INFO] [stdout] - Given r ← ray(point(0, 0, -5), vector(0, 0, 1)) [INFO] [stdout] features/shapes.feature:33:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← test_shape() features/shapes.feature:34:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When set_transform(s, translation(5, 0, 0)) features/shapes.feature:35:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersect(s, r) features/shapes.feature:36:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then s.saved_ray.origin = point(-5, 0, -5) features/shapes.feature:37:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s.saved_ray.direction = vector(0, 0, 1) features/shapes.feature:38:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Computing the normal on a translated shape [INFO] [stdout] features/shapes.feature:40:11 [INFO] [stdout] - Given s ← test_shape() features/shapes.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When set_transform(s, translation(0, 1, 0)) features/shapes.feature:42:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n ← normal_at(s, point(0, 1.70711, -0.70711)) [INFO] [stdout] features/shapes.feature:43:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, 0.70711, -0.70711) features/shapes.feature:44:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Computing the normal on a transformed shape [INFO] [stdout] features/shapes.feature:46:11 [INFO] [stdout] - Given s ← test_shape() features/shapes.feature:47:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m ← scaling(1, 0.5, 1) * rotation_z(π/5) features/shapes.feature:48:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When set_transform(s, m) features/shapes.feature:49:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n ← normal_at(s, point(0, √2/2, -√2/2)) features/shapes.feature:50:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, 0.97014, -0.24254) features/shapes.feature:51:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A shape has a parent attribute features/shapes.feature:53:11 [INFO] [stdout] - Given s ← test_shape() features/shapes.feature:54:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then s.parent is nothing features/shapes.feature:55:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Converting a point from world to object space [INFO] [stdout] features/shapes.feature:57:11 [INFO] [stdout] - Given g1 ← group() features/shapes.feature:58:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(g1, rotation_y(π/2)) features/shapes.feature:59:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And g2 ← group() features/shapes.feature:60:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(g2, scaling(2, 2, 2)) features/shapes.feature:61:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And add_child(g1, g2) features/shapes.feature:62:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← sphere() features/shapes.feature:63:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(s, translation(5, 0, 0)) features/shapes.feature:64:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And add_child(g2, s) features/shapes.feature:65:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When p ← world_to_object(s, point(-2, 0, -10)) features/shapes.feature:66:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then p = point(0, 0, -1) features/shapes.feature:67:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Converting a normal from object to world space [INFO] [stdout] features/shapes.feature:69:11 [INFO] [stdout] - Given g1 ← group() features/shapes.feature:70:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(g1, rotation_y(π/2)) features/shapes.feature:71:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And g2 ← group() features/shapes.feature:72:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(g2, scaling(1, 2, 3)) features/shapes.feature:73:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And add_child(g1, g2) features/shapes.feature:74:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← sphere() features/shapes.feature:75:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(s, translation(5, 0, 0)) features/shapes.feature:76:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And add_child(g2, s) features/shapes.feature:77:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← normal_to_world(s, vector(√3/3, √3/3, √3/3)) [INFO] [stdout] features/shapes.feature:78:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0.2857, 0.4286, -0.8571) features/shapes.feature:79:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Finding the normal on a child object features/shapes.feature:81:11 [INFO] [stdout] - Given g1 ← group() features/shapes.feature:82:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(g1, rotation_y(π/2)) features/shapes.feature:83:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And g2 ← group() features/shapes.feature:84:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(g2, scaling(1, 2, 3)) features/shapes.feature:85:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And add_child(g1, g2) features/shapes.feature:86:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← sphere() features/shapes.feature:87:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(s, translation(5, 0, 0)) features/shapes.feature:88:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And add_child(g2, s) features/shapes.feature:89:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← normal_at(s, point(1.7321, 1.1547, -5.5774)) [INFO] [stdout] features/shapes.feature:90:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0.2857, 0.4286, -0.8571) features/shapes.feature:91:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Smooth Triangles features/smooth-triangles.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: Constructing a smooth triangle [INFO] [stdout] features/smooth-triangles.feature:12:11 [INFO] [stdout] - Given p1 ← point(0, 1, 0) features/smooth-triangles.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p2 ← point(-1, 0, 0) features/smooth-triangles.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p3 ← point(1, 0, 0) features/smooth-triangles.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n1 ← vector(0, 1, 0) features/smooth-triangles.feature:7:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n2 ← vector(-1, 0, 0) features/smooth-triangles.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n3 ← vector(1, 0, 0) features/smooth-triangles.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When tri ← smooth_triangle(p1, p2, p3, n1, n2, n3) [INFO] [stdout] features/smooth-triangles.feature:10:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then tri.p1 = p1 features/smooth-triangles.feature:13:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And tri.p2 = p2 features/smooth-triangles.feature:14:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And tri.p3 = p3 features/smooth-triangles.feature:15:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And tri.n1 = n1 features/smooth-triangles.feature:16:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And tri.n2 = n2 features/smooth-triangles.feature:17:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And tri.n3 = n3 features/smooth-triangles.feature:18:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: An intersection with a smooth triangle stores u/v [INFO] [stdout] features/smooth-triangles.feature:20:11 [INFO] [stdout] - Given p1 ← point(0, 1, 0) features/smooth-triangles.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p2 ← point(-1, 0, 0) features/smooth-triangles.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p3 ← point(1, 0, 0) features/smooth-triangles.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n1 ← vector(0, 1, 0) features/smooth-triangles.feature:7:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n2 ← vector(-1, 0, 0) features/smooth-triangles.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n3 ← vector(1, 0, 0) features/smooth-triangles.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When tri ← smooth_triangle(p1, p2, p3, n1, n2, n3) [INFO] [stdout] features/smooth-triangles.feature:10:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When r ← ray(point(-0.2, 0.3, -2), vector(0, 0, 1)) [INFO] [stdout] features/smooth-triangles.feature:21:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← local_intersect(tri, r) features/smooth-triangles.feature:22:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs[0].u = 0.45 features/smooth-triangles.feature:23:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].v = 0.25 features/smooth-triangles.feature:24:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A smooth triangle uses u/v to interpolate the normal [INFO] [stdout] features/smooth-triangles.feature:26:11 [INFO] [stdout] - Given p1 ← point(0, 1, 0) features/smooth-triangles.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p2 ← point(-1, 0, 0) features/smooth-triangles.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p3 ← point(1, 0, 0) features/smooth-triangles.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n1 ← vector(0, 1, 0) features/smooth-triangles.feature:7:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n2 ← vector(-1, 0, 0) features/smooth-triangles.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n3 ← vector(1, 0, 0) features/smooth-triangles.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When tri ← smooth_triangle(p1, p2, p3, n1, n2, n3) [INFO] [stdout] features/smooth-triangles.feature:10:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When i ← intersection_with_uv(1, tri, 0.45, 0.25) [INFO] [stdout] features/smooth-triangles.feature:27:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n ← normal_at(tri, point(0, 0, 0), i) [INFO] [stdout] features/smooth-triangles.feature:28:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(-0.5547, 0.83205, 0) features/smooth-triangles.feature:29:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Preparing the normal on a smooth triangle [INFO] [stdout] features/smooth-triangles.feature:31:11 [INFO] [stdout] - Given p1 ← point(0, 1, 0) features/smooth-triangles.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p2 ← point(-1, 0, 0) features/smooth-triangles.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p3 ← point(1, 0, 0) features/smooth-triangles.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n1 ← vector(0, 1, 0) features/smooth-triangles.feature:7:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n2 ← vector(-1, 0, 0) features/smooth-triangles.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n3 ← vector(1, 0, 0) features/smooth-triangles.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When tri ← smooth_triangle(p1, p2, p3, n1, n2, n3) [INFO] [stdout] features/smooth-triangles.feature:10:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When i ← intersection_with_uv(1, tri, 0.45, 0.25) [INFO] [stdout] features/smooth-triangles.feature:32:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(-0.2, 0.3, -2), vector(0, 0, 1)) [INFO] [stdout] features/smooth-triangles.feature:33:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(i) features/smooth-triangles.feature:34:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And comps ← prepare_computations(i, r, xs) [INFO] [stdout] features/smooth-triangles.feature:35:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then comps.normalv = vector(-0.5547, 0.83205, 0) [INFO] [stdout] features/smooth-triangles.feature:36:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Spheres features/spheres.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: A ray intersects a sphere at two points [INFO] [stdout] features/spheres.feature:3:11 [INFO] [stdout] - Given r ← ray(point(0, 0, -5), vector(0, 0, 1)) [INFO] [stdout] features/spheres.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← sphere() features/spheres.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← intersect(s, r) features/spheres.feature:6:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/spheres.feature:7:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0] = 4.0 features/spheres.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1] = 6.0 features/spheres.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray intersects a sphere at a tangent [INFO] [stdout] features/spheres.feature:11:11 [INFO] [stdout] - Given r ← ray(point(0, 1, -5), vector(0, 0, 1)) [INFO] [stdout] features/spheres.feature:12:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← sphere() features/spheres.feature:13:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← intersect(s, r) features/spheres.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/spheres.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0] = 5.0 features/spheres.feature:16:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1] = 5.0 features/spheres.feature:17:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses a sphere features/spheres.feature:19:11 [INFO] [stdout] - Given r ← ray(point(0, 2, -5), vector(0, 0, 1)) [INFO] [stdout] features/spheres.feature:20:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← sphere() features/spheres.feature:21:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← intersect(s, r) features/spheres.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 0 features/spheres.feature:23:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray originates inside a sphere features/spheres.feature:25:11 [INFO] [stdout] - Given r ← ray(point(0, 0, 0), vector(0, 0, 1)) [INFO] [stdout] features/spheres.feature:26:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← sphere() features/spheres.feature:27:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← intersect(s, r) features/spheres.feature:28:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/spheres.feature:29:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0] = -1.0 features/spheres.feature:30:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1] = 1.0 features/spheres.feature:31:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A sphere is behind a ray features/spheres.feature:33:11 [INFO] [stdout] - Given r ← ray(point(0, 0, 5), vector(0, 0, 1)) [INFO] [stdout] features/spheres.feature:34:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← sphere() features/spheres.feature:35:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← intersect(s, r) features/spheres.feature:36:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/spheres.feature:37:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0] = -6.0 features/spheres.feature:38:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1] = -4.0 features/spheres.feature:39:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersect sets the object on the intersection [INFO] [stdout] features/spheres.feature:41:11 [INFO] [stdout] - Given r ← ray(point(0, 0, -5), vector(0, 0, 1)) [INFO] [stdout] features/spheres.feature:42:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← sphere() features/spheres.feature:43:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← intersect(s, r) features/spheres.feature:44:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/spheres.feature:45:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].object = s features/spheres.feature:46:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].object = s features/spheres.feature:47:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A sphere's default transformation features/spheres.feature:49:11 [INFO] [stdout] - Given s ← sphere() features/spheres.feature:50:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then s.transform = identity_matrix features/spheres.feature:51:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Changing a sphere's transformation features/spheres.feature:53:11 [INFO] [stdout] - Given s ← sphere() features/spheres.feature:54:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t ← translation(2, 3, 4) features/spheres.feature:55:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When set_transform(s, t) features/spheres.feature:56:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then s.transform = t features/spheres.feature:57:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a scaled sphere with a ray [INFO] [stdout] features/spheres.feature:59:11 [INFO] [stdout] - Given r ← ray(point(0, 0, -5), vector(0, 0, 1)) [INFO] [stdout] features/spheres.feature:60:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← sphere() features/spheres.feature:61:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When set_transform(s, scaling(2, 2, 2)) features/spheres.feature:62:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersect(s, r) features/spheres.feature:63:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 2 features/spheres.feature:64:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 3 features/spheres.feature:65:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 7 features/spheres.feature:66:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a translated sphere with a ray [INFO] [stdout] features/spheres.feature:68:11 [INFO] [stdout] - Given r ← ray(point(0, 0, -5), vector(0, 0, 1)) [INFO] [stdout] features/spheres.feature:69:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s ← sphere() features/spheres.feature:70:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When set_transform(s, translation(5, 0, 0)) features/spheres.feature:71:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersect(s, r) features/spheres.feature:72:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 0 features/spheres.feature:73:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal on a sphere at a point on the x axis [INFO] [stdout] features/spheres.feature:75:11 [INFO] [stdout] - Given s ← sphere() features/spheres.feature:76:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← normal_at(s, point(1, 0, 0)) features/spheres.feature:77:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(1, 0, 0) features/spheres.feature:78:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal on a sphere at a point on the y axis [INFO] [stdout] features/spheres.feature:80:11 [INFO] [stdout] - Given s ← sphere() features/spheres.feature:81:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← normal_at(s, point(0, 1, 0)) features/spheres.feature:82:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, 1, 0) features/spheres.feature:83:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal on a sphere at a point on the z axis [INFO] [stdout] features/spheres.feature:85:11 [INFO] [stdout] - Given s ← sphere() features/spheres.feature:86:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← normal_at(s, point(0, 0, 1)) features/spheres.feature:87:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, 0, 1) features/spheres.feature:88:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal on a sphere at a nonaxial point [INFO] [stdout] features/spheres.feature:90:11 [INFO] [stdout] - Given s ← sphere() features/spheres.feature:91:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← normal_at(s, point(√3/3, √3/3, √3/3)) [INFO] [stdout] features/spheres.feature:92:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(√3/3, √3/3, √3/3) features/spheres.feature:93:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The normal is a normalized vector features/spheres.feature:95:11 [INFO] [stdout] - Given s ← sphere() features/spheres.feature:96:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← normal_at(s, point(√3/3, √3/3, √3/3)) [INFO] [stdout] features/spheres.feature:97:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = normalize(n) features/spheres.feature:98:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Computing the normal on a translated sphere [INFO] [stdout] features/spheres.feature:100:11 [INFO] [stdout] - Given s ← sphere() features/spheres.feature:101:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(s, translation(0, 1, 0)) features/spheres.feature:102:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← normal_at(s, point(0, 1.70711, -0.70711)) [INFO] [stdout] features/spheres.feature:103:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, 0.70711, -0.70711) features/spheres.feature:104:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Computing the normal on a transformed sphere [INFO] [stdout] features/spheres.feature:106:11 [INFO] [stdout] - Given s ← sphere() features/spheres.feature:107:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m ← scaling(1, 0.5, 1) * rotation_z(π/5) features/spheres.feature:108:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And set_transform(s, m) features/spheres.feature:109:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n ← normal_at(s, point(0, √2/2, -√2/2)) features/spheres.feature:110:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n = vector(0, 0.97014, -0.24254) features/spheres.feature:111:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A sphere has a default material features/spheres.feature:113:11 [INFO] [stdout] - Given s ← sphere() features/spheres.feature:114:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When m ← s.material features/spheres.feature:115:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then m = material() features/spheres.feature:116:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A sphere may be assigned a material features/spheres.feature:118:11 [INFO] [stdout] - Given s ← sphere() features/spheres.feature:119:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m ← material() features/spheres.feature:120:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And m.ambient ← 1 features/spheres.feature:121:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When s.material ← m features/spheres.feature:122:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then s.material = m features/spheres.feature:123:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A helper for producing a sphere with a glassy material [INFO] [stdout] features/spheres.feature:125:11 [INFO] [stdout] - Given s ← glass_sphere() features/spheres.feature:126:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then s.transform = identity_matrix features/spheres.feature:127:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s.material.transparency = 1.0 features/spheres.feature:128:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s.material.refractive_index = 1.5 features/spheres.feature:129:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Matrix Transformations features/transformations.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: Multiplying by a translation matrix [INFO] [stdout] features/transformations.feature:3:11 [INFO] [stdout] - Given transform ← translation(5, -3, 2) [INFO] [stdout] features/transformations.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(-3, 4, 5) features/transformations.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then transform * p = point(2, 1, 7) features/transformations.feature:6:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Multiplying by the inverse of a translation matrix [INFO] [stdout] features/transformations.feature:8:11 [INFO] [stdout] - Given transform ← translation(5, -3, 2) [INFO] [stdout] features/transformations.feature:9:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And inv ← inverse(transform) features/transformations.feature:10:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(-3, 4, 5) features/transformations.feature:11:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then inv * p = point(-8, 7, 3) features/transformations.feature:12:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Translation does not affect vectors [INFO] [stdout] features/transformations.feature:14:11 [INFO] [stdout] - Given transform ← translation(5, -3, 2) [INFO] [stdout] features/transformations.feature:15:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And v ← vector(-3, 4, 5) features/transformations.feature:16:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then transform * v = v features/transformations.feature:17:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A scaling matrix applied to a point [INFO] [stdout] features/transformations.feature:19:11 [INFO] [stdout] - Given transform ← scaling(2, 3, 4) features/transformations.feature:20:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(-4, 6, 8) features/transformations.feature:21:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then transform * p = point(-8, 18, 32) [INFO] [stdout] features/transformations.feature:22:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A scaling matrix applied to a vector [INFO] [stdout] features/transformations.feature:24:11 [INFO] [stdout] - Given transform ← scaling(2, 3, 4) features/transformations.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And v ← vector(-4, 6, 8) features/transformations.feature:26:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then transform * v = vector(-8, 18, 32) [INFO] [stdout] features/transformations.feature:27:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Multiplying by the inverse of a scaling matrix [INFO] [stdout] features/transformations.feature:29:11 [INFO] [stdout] - Given transform ← scaling(2, 3, 4) features/transformations.feature:30:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And inv ← inverse(transform) features/transformations.feature:31:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And v ← vector(-4, 6, 8) features/transformations.feature:32:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then inv * v = vector(-2, 2, 2) features/transformations.feature:33:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Reflection is scaling by a negative value [INFO] [stdout] features/transformations.feature:35:11 [INFO] [stdout] - Given transform ← scaling(-1, 1, 1) features/transformations.feature:36:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(2, 3, 4) features/transformations.feature:37:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then transform * p = point(-2, 3, 4) features/transformations.feature:38:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Rotating a point around the x axis [INFO] [stdout] features/transformations.feature:40:11 [INFO] [stdout] - Given p ← point(0, 1, 0) features/transformations.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And half_quarter ← rotation_x(π / 4) features/transformations.feature:42:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And full_quarter ← rotation_x(π / 2) features/transformations.feature:43:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then half_quarter * p = point(0, √2/2, √2/2) [INFO] [stdout] features/transformations.feature:44:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And full_quarter * p = point(0, 0, 1) features/transformations.feature:45:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The inverse of an x-rotation rotates in the opposite direction [INFO] [stdout] features/transformations.feature:47:11 [INFO] [stdout] - Given p ← point(0, 1, 0) features/transformations.feature:48:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And half_quarter ← rotation_x(π / 4) features/transformations.feature:49:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And inv ← inverse(half_quarter) features/transformations.feature:50:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then inv * p = point(0, √2/2, -√2/2) features/transformations.feature:51:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Rotating a point around the y axis [INFO] [stdout] features/transformations.feature:53:11 [INFO] [stdout] - Given p ← point(0, 0, 1) features/transformations.feature:54:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And half_quarter ← rotation_y(π / 4) features/transformations.feature:55:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And full_quarter ← rotation_y(π / 2) features/transformations.feature:56:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then half_quarter * p = point(√2/2, 0, √2/2) [INFO] [stdout] features/transformations.feature:57:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And full_quarter * p = point(1, 0, 0) features/transformations.feature:58:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Rotating a point around the z axis [INFO] [stdout] features/transformations.feature:60:11 [INFO] [stdout] - Given p ← point(0, 1, 0) features/transformations.feature:61:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And half_quarter ← rotation_z(π / 4) features/transformations.feature:62:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And full_quarter ← rotation_z(π / 2) features/transformations.feature:63:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then half_quarter * p = point(-√2/2, √2/2, 0) [INFO] [stdout] features/transformations.feature:64:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And full_quarter * p = point(-1, 0, 0) [INFO] [stdout] features/transformations.feature:65:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A shearing transformation moves x in proportion to y [INFO] [stdout] features/transformations.feature:67:11 [INFO] [stdout] - Given transform ← shearing(1, 0, 0, 0, 0, 0) [INFO] [stdout] features/transformations.feature:68:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(2, 3, 4) features/transformations.feature:69:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then transform * p = point(5, 3, 4) features/transformations.feature:70:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A shearing transformation moves x in proportion to z [INFO] [stdout] features/transformations.feature:72:11 [INFO] [stdout] - Given transform ← shearing(0, 1, 0, 0, 0, 0) [INFO] [stdout] features/transformations.feature:73:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(2, 3, 4) features/transformations.feature:74:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then transform * p = point(6, 3, 4) features/transformations.feature:75:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A shearing transformation moves y in proportion to x [INFO] [stdout] features/transformations.feature:77:11 [INFO] [stdout] - Given transform ← shearing(0, 0, 1, 0, 0, 0) [INFO] [stdout] features/transformations.feature:78:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(2, 3, 4) features/transformations.feature:79:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then transform * p = point(2, 5, 4) features/transformations.feature:80:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A shearing transformation moves y in proportion to z [INFO] [stdout] features/transformations.feature:82:11 [INFO] [stdout] - Given transform ← shearing(0, 0, 0, 1, 0, 0) [INFO] [stdout] features/transformations.feature:83:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(2, 3, 4) features/transformations.feature:84:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then transform * p = point(2, 7, 4) features/transformations.feature:85:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A shearing transformation moves z in proportion to x [INFO] [stdout] features/transformations.feature:87:11 [INFO] [stdout] - Given transform ← shearing(0, 0, 0, 0, 1, 0) [INFO] [stdout] features/transformations.feature:88:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(2, 3, 4) features/transformations.feature:89:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then transform * p = point(2, 3, 6) features/transformations.feature:90:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A shearing transformation moves z in proportion to y [INFO] [stdout] features/transformations.feature:92:11 [INFO] [stdout] - Given transform ← shearing(0, 0, 0, 0, 0, 1) [INFO] [stdout] features/transformations.feature:93:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(2, 3, 4) features/transformations.feature:94:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then transform * p = point(2, 3, 7) features/transformations.feature:95:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Individual transformations are applied in sequence [INFO] [stdout] features/transformations.feature:97:11 [INFO] [stdout] - Given p ← point(1, 0, 1) features/transformations.feature:98:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And A ← rotation_x(π / 2) features/transformations.feature:99:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B ← scaling(5, 5, 5) features/transformations.feature:100:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And C ← translation(10, 5, 7) features/transformations.feature:101:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When p2 ← A * p features/transformations.feature:103:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then p2 = point(1, -1, 0) features/transformations.feature:104:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When p3 ← B * p2 features/transformations.feature:106:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then p3 = point(5, -5, 0) features/transformations.feature:107:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When p4 ← C * p3 features/transformations.feature:109:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then p4 = point(15, 0, 7) features/transformations.feature:110:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Chained transformations must be applied in reverse order [INFO] [stdout] features/transformations.feature:112:11 [INFO] [stdout] - Given p ← point(1, 0, 1) features/transformations.feature:113:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And A ← rotation_x(π / 2) features/transformations.feature:114:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B ← scaling(5, 5, 5) features/transformations.feature:115:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And C ← translation(10, 5, 7) features/transformations.feature:116:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When T ← C * B * A features/transformations.feature:117:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then T * p = point(15, 0, 7) features/transformations.feature:118:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The transformation matrix for the default orientation [INFO] [stdout] features/transformations.feature:120:11 [INFO] [stdout] - Given from ← point(0, 0, 0) features/transformations.feature:121:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And to ← point(0, 0, -1) features/transformations.feature:122:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And up ← vector(0, 1, 0) features/transformations.feature:123:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When t ← view_transform(from, to, up) [INFO] [stdout] features/transformations.feature:124:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then t = identity_matrix features/transformations.feature:125:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A view transformation matrix looking in positive z direction [INFO] [stdout] features/transformations.feature:127:11 [INFO] [stdout] - Given from ← point(0, 0, 0) features/transformations.feature:128:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And to ← point(0, 0, 1) features/transformations.feature:129:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And up ← vector(0, 1, 0) features/transformations.feature:130:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When t ← view_transform(from, to, up) [INFO] [stdout] features/transformations.feature:131:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then t = scaling(-1, 1, -1) features/transformations.feature:132:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The view transformation moves the world [INFO] [stdout] features/transformations.feature:134:11 [INFO] [stdout] - Given from ← point(0, 0, 8) features/transformations.feature:135:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And to ← point(0, 0, 0) features/transformations.feature:136:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And up ← vector(0, 1, 0) features/transformations.feature:137:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When t ← view_transform(from, to, up) [INFO] [stdout] features/transformations.feature:138:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then t = translation(0, 0, -8) features/transformations.feature:139:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: An arbitrary view transformation [INFO] [stdout] features/transformations.feature:141:11 [INFO] [stdout] - Given from ← point(1, 3, 2) features/transformations.feature:142:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And to ← point(4, -2, 8) features/transformations.feature:143:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And up ← vector(1, 1, 0) features/transformations.feature:144:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When t ← view_transform(from, to, up) [INFO] [stdout] features/transformations.feature:145:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then t is the following 4x4 matrix: features/transformations.feature:146:3 [INFO] [stdout] | -0.50709 | 0.50709 | 0.67612 | -2.36643 | [INFO] [stdout] | 0.76772 | 0.60609 | 0.12122 | -2.82843 | [INFO] [stdout] | -0.35857 | 0.59761 | -0.71714 | 0.00000 | [INFO] [stdout] | 0.00000 | 0.00000 | 0.00000 | 1.00000 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Triangles features/triangles.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: Constructing a triangle features/triangles.feature:3:11 [INFO] [stdout] - Given p1 ← point(0, 1, 0) features/triangles.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p2 ← point(-1, 0, 0) features/triangles.feature:5:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p3 ← point(1, 0, 0) features/triangles.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t ← triangle(p1, p2, p3) features/triangles.feature:7:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then t.p1 = p1 features/triangles.feature:8:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t.p2 = p2 features/triangles.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t.p3 = p3 features/triangles.feature:10:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t.e1 = vector(-1, -1, 0) features/triangles.feature:11:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t.e2 = vector(1, -1, 0) features/triangles.feature:12:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And t.normal = vector(0, 0, -1) features/triangles.feature:13:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersecting a ray parallel to the triangle [INFO] [stdout] features/triangles.feature:15:11 [INFO] [stdout] - Given t ← triangle(point(0, 1, 0), point(-1, 0, 0), point(1, 0, 0)) [INFO] [stdout] features/triangles.feature:16:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, -1, -2), vector(0, 1, 0)) [INFO] [stdout] features/triangles.feature:17:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(t, r) features/triangles.feature:18:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs is empty features/triangles.feature:19:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses the p1-p3 edge features/triangles.feature:21:11 [INFO] [stdout] - Given t ← triangle(point(0, 1, 0), point(-1, 0, 0), point(1, 0, 0)) [INFO] [stdout] features/triangles.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(1, 1, -2), vector(0, 0, 1)) [INFO] [stdout] features/triangles.feature:23:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(t, r) features/triangles.feature:24:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs is empty features/triangles.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses the p1-p2 edge features/triangles.feature:27:11 [INFO] [stdout] - Given t ← triangle(point(0, 1, 0), point(-1, 0, 0), point(1, 0, 0)) [INFO] [stdout] features/triangles.feature:28:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(-1, 1, -2), vector(0, 0, 1)) [INFO] [stdout] features/triangles.feature:29:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(t, r) features/triangles.feature:30:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs is empty features/triangles.feature:31:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray misses the p2-p3 edge features/triangles.feature:33:11 [INFO] [stdout] - Given t ← triangle(point(0, 1, 0), point(-1, 0, 0), point(1, 0, 0)) [INFO] [stdout] features/triangles.feature:34:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, -1, -2), vector(0, 0, 1)) [INFO] [stdout] features/triangles.feature:35:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(t, r) features/triangles.feature:36:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs is empty features/triangles.feature:37:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A ray strikes a triangle features/triangles.feature:39:11 [INFO] [stdout] - Given t ← triangle(point(0, 1, 0), point(-1, 0, 0), point(1, 0, 0)) [INFO] [stdout] features/triangles.feature:40:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0.5, -2), vector(0, 0, 1)) [INFO] [stdout] features/triangles.feature:41:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← local_intersect(t, r) features/triangles.feature:42:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 1 features/triangles.feature:43:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 2 features/triangles.feature:44:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Finding the normal on a triangle features/triangles.feature:46:11 [INFO] [stdout] - Given t ← triangle(point(0, 1, 0), point(-1, 0, 0), point(1, 0, 0)) [INFO] [stdout] features/triangles.feature:47:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When n1 ← local_normal_at(t, point(0, 0.5, 0)) [INFO] [stdout] features/triangles.feature:48:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n2 ← local_normal_at(t, point(-0.5, 0.75, 0)) [INFO] [stdout] features/triangles.feature:49:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n3 ← local_normal_at(t, point(0.5, 0.25, 0)) [INFO] [stdout] features/triangles.feature:50:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then n1 = t.normal features/triangles.feature:51:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n2 = t.normal features/triangles.feature:52:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n3 = t.normal features/triangles.feature:53:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: Tuples, Vectors, and Points features/tuples.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: A tuple with w=1.0 is a point features/tuples.feature:3:11 [INFO] [stdout] - Given a ← tuple(4.3, -4.2, 3.1, 1.0) features/tuples.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then a.x = 4.3 features/tuples.feature:5:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And a.y = -4.2 features/tuples.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And a.z = 3.1 features/tuples.feature:7:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And a.w = 1.0 features/tuples.feature:8:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And a is a point features/tuples.feature:9:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And a is not a vector features/tuples.feature:10:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: A tuple with w=0 is a vector features/tuples.feature:12:11 [INFO] [stdout] - Given a ← tuple(4.3, -4.2, 3.1, 0.0) features/tuples.feature:13:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then a.x = 4.3 features/tuples.feature:14:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And a.y = -4.2 features/tuples.feature:15:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And a.z = 3.1 features/tuples.feature:16:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And a.w = 0.0 features/tuples.feature:17:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And a is not a point features/tuples.feature:18:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And a is a vector features/tuples.feature:19:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: point() creates tuples with w=1 features/tuples.feature:21:11 [INFO] [stdout] - Given p ← point(4, -4, 3) features/tuples.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then p = tuple(4, -4, 3, 1) features/tuples.feature:23:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: vector() creates tuples with w=0 features/tuples.feature:25:11 [INFO] [stdout] - Given v ← vector(4, -4, 3) features/tuples.feature:26:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then v = tuple(4, -4, 3, 0) features/tuples.feature:27:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Adding two tuples features/tuples.feature:29:11 [INFO] [stdout] - Given a1 ← tuple(3, -2, 5, 1) features/tuples.feature:30:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And a2 ← tuple(-2, 3, 1, 0) features/tuples.feature:31:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then a1 + a2 = tuple(1, 1, 6, 1) features/tuples.feature:32:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Subtracting two points features/tuples.feature:34:11 [INFO] [stdout] - Given p1 ← point(3, 2, 1) features/tuples.feature:35:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p2 ← point(5, 6, 7) features/tuples.feature:36:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then p1 - p2 = vector(-2, -4, -6) features/tuples.feature:37:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Subtracting a vector from a point features/tuples.feature:39:11 [INFO] [stdout] - Given p ← point(3, 2, 1) features/tuples.feature:40:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And v ← vector(5, 6, 7) features/tuples.feature:41:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then p - v = point(-2, -4, -6) features/tuples.feature:42:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Subtracting two vectors features/tuples.feature:44:11 [INFO] [stdout] - Given v1 ← vector(3, 2, 1) features/tuples.feature:45:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And v2 ← vector(5, 6, 7) features/tuples.feature:46:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then v1 - v2 = vector(-2, -4, -6) features/tuples.feature:47:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Subtracting a vector from the zero vector [INFO] [stdout] features/tuples.feature:49:11 [INFO] [stdout] - Given zero ← vector(0, 0, 0) features/tuples.feature:50:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And v ← vector(1, -2, 3) features/tuples.feature:51:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then zero - v = vector(-1, 2, -3) features/tuples.feature:52:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Negating a tuple features/tuples.feature:54:11 [INFO] [stdout] - Given a ← tuple(1, -2, 3, -4) features/tuples.feature:55:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then -a = tuple(-1, 2, -3, 4) features/tuples.feature:56:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Multiplying a tuple by a scalar features/tuples.feature:58:11 [INFO] [stdout] - Given a ← tuple(1, -2, 3, -4) features/tuples.feature:59:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then a * 3.5 = tuple(3.5, -7, 10.5, -14) features/tuples.feature:60:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Multiplying a tuple by a fraction features/tuples.feature:62:11 [INFO] [stdout] - Given a ← tuple(1, -2, 3, -4) features/tuples.feature:63:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then a * 0.5 = tuple(0.5, -1, 1.5, -2) features/tuples.feature:64:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Dividing a tuple by a scalar features/tuples.feature:66:11 [INFO] [stdout] - Given a ← tuple(1, -2, 3, -4) features/tuples.feature:67:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then a / 2 = tuple(0.5, -1, 1.5, -2) features/tuples.feature:68:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Computing the magnitude of vector(1, 0, 0) [INFO] [stdout] features/tuples.feature:70:11 [INFO] [stdout] - Given v ← vector(1, 0, 0) features/tuples.feature:71:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then magnitude(v) = 1 features/tuples.feature:72:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Computing the magnitude of vector(0, 1, 0) [INFO] [stdout] features/tuples.feature:74:11 [INFO] [stdout] - Given v ← vector(0, 1, 0) features/tuples.feature:75:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then magnitude(v) = 1 features/tuples.feature:76:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Computing the magnitude of vector(0, 0, 1) [INFO] [stdout] features/tuples.feature:78:11 [INFO] [stdout] - Given v ← vector(0, 0, 1) features/tuples.feature:79:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then magnitude(v) = 1 features/tuples.feature:80:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Computing the magnitude of vector(1, 2, 3) [INFO] [stdout] features/tuples.feature:82:11 [INFO] [stdout] - Given v ← vector(1, 2, 3) features/tuples.feature:83:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then magnitude(v) = √14 features/tuples.feature:84:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Computing the magnitude of vector(-1, -2, -3) [INFO] [stdout] features/tuples.feature:86:11 [INFO] [stdout] - Given v ← vector(-1, -2, -3) features/tuples.feature:87:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then magnitude(v) = √14 features/tuples.feature:88:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Normalizing vector(4, 0, 0) gives (1, 0, 0) [INFO] [stdout] features/tuples.feature:90:11 [INFO] [stdout] - Given v ← vector(4, 0, 0) features/tuples.feature:91:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then normalize(v) = vector(1, 0, 0) features/tuples.feature:92:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Normalizing vector(1, 2, 3) features/tuples.feature:94:11 [INFO] [stdout] - Given v ← vector(1, 2, 3) features/tuples.feature:95:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then normalize(v) = approximately vector(0.26726, 0.53452, 0.80178) [INFO] [stdout] features/tuples.feature:97:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The magnitude of a normalized vector features/tuples.feature:99:11 [INFO] [stdout] - Given v ← vector(1, 2, 3) features/tuples.feature:100:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When norm ← normalize(v) features/tuples.feature:101:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then magnitude(norm) = 1 features/tuples.feature:102:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The dot product of two tuples features/tuples.feature:104:11 [INFO] [stdout] - Given a ← vector(1, 2, 3) features/tuples.feature:105:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And b ← vector(2, 3, 4) features/tuples.feature:106:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then dot(a, b) = 20 features/tuples.feature:107:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The cross product of two vectors features/tuples.feature:109:11 [INFO] [stdout] - Given a ← vector(1, 2, 3) features/tuples.feature:110:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And b ← vector(2, 3, 4) features/tuples.feature:111:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then cross(a, b) = vector(-1, 2, -1) features/tuples.feature:112:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And cross(b, a) = vector(1, -2, 1) features/tuples.feature:113:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Colors are (red, green, blue) tuples features/tuples.feature:115:11 [INFO] [stdout] - Given c ← color(-0.5, 0.4, 1.7) features/tuples.feature:116:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c.red = -0.5 features/tuples.feature:117:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c.green = 0.4 features/tuples.feature:118:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c.blue = 1.7 features/tuples.feature:119:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Adding colors features/tuples.feature:121:11 [INFO] [stdout] - Given c1 ← color(0.9, 0.6, 0.75) features/tuples.feature:122:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c2 ← color(0.7, 0.1, 0.25) features/tuples.feature:123:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c1 + c2 = color(1.6, 0.7, 1.0) features/tuples.feature:124:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Subtracting colors features/tuples.feature:126:11 [INFO] [stdout] - Given c1 ← color(0.9, 0.6, 0.75) features/tuples.feature:127:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c2 ← color(0.7, 0.1, 0.25) features/tuples.feature:128:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c1 - c2 = color(0.2, 0.5, 0.5) features/tuples.feature:129:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Multiplying a color by a scalar features/tuples.feature:131:11 [INFO] [stdout] - Given c ← color(0.2, 0.3, 0.4) features/tuples.feature:132:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c * 2 = color(0.4, 0.6, 0.8) features/tuples.feature:133:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Multiplying colors features/tuples.feature:135:11 [INFO] [stdout] - Given c1 ← color(1, 0.2, 0.4) features/tuples.feature:136:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c2 ← color(0.9, 1, 0.1) features/tuples.feature:137:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c1 * c2 = color(0.9, 0.2, 0.04) features/tuples.feature:138:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Reflecting a vector approaching at 45° [INFO] [stdout] features/tuples.feature:140:11 [INFO] [stdout] - Given v ← vector(1, -1, 0) features/tuples.feature:141:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n ← vector(0, 1, 0) features/tuples.feature:142:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When r ← reflect(v, n) features/tuples.feature:143:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then r = vector(1, 1, 0) features/tuples.feature:144:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Reflecting a vector off a slanted surface [INFO] [stdout] features/tuples.feature:146:11 [INFO] [stdout] - Given v ← vector(0, -1, 0) features/tuples.feature:147:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And n ← vector(√2/2, √2/2, 0) features/tuples.feature:148:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When r ← reflect(v, n) features/tuples.feature:149:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then r = vector(1, 0, 0) features/tuples.feature:150:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Feature: World features/world.feature:1:1 [INFO] [stdout] [INFO] [stdout] Scenario: Creating a world features/world.feature:3:11 [INFO] [stdout] - Given w ← world() features/world.feature:4:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then w contains no objects features/world.feature:5:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And w has no light source features/world.feature:6:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The default world features/world.feature:8:11 [INFO] [stdout] - Given light ← point_light(point(-10, 10, -10), color(1, 1, 1)) [INFO] [stdout] features/world.feature:9:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s1 ← sphere() with: features/world.feature:10:5 [INFO] [stdout] | material.color | (0.8, 1.0, 0.6) | [INFO] [stdout] | material.diffuse | 0.7 | [INFO] [stdout] | material.specular | 0.2 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s2 ← sphere() with: features/world.feature:14:5 [INFO] [stdout] | | | [INFO] [stdout] | transform | scaling(0.5, 0.5, 0.5) | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When w ← default_world() features/world.feature:16:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then w.light = light features/world.feature:17:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And w contains s1 features/world.feature:18:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And w contains s2 features/world.feature:19:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Intersect a world with a ray features/world.feature:21:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:22:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -5), vector(0, 0, 1)) features/world.feature:23:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When xs ← intersect_world(w, r) features/world.feature:24:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then xs.count = 4 features/world.feature:25:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[0].t = 4 features/world.feature:26:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[1].t = 4.5 features/world.feature:27:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[2].t = 5.5 features/world.feature:28:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs[3].t = 6 features/world.feature:29:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Shading an intersection features/world.feature:31:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:32:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -5), vector(0, 0, 1)) features/world.feature:33:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← the first object in w features/world.feature:34:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i ← intersection(4, shape) features/world.feature:35:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(i, r) features/world.feature:36:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c ← shade_hit(w, comps) features/world.feature:37:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = color(0.38066, 0.47583, 0.2855) features/world.feature:38:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: Shading an intersection from the inside features/world.feature:40:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:41:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And w.light ← point_light(point(0, 0.25, 0), color(1, 1, 1)) [INFO] [stdout] features/world.feature:42:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, 0), vector(0, 0, 1)) features/world.feature:43:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← the second object in w features/world.feature:44:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i ← intersection(0.5, shape) features/world.feature:45:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(i, r) features/world.feature:46:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c ← shade_hit(w, comps) features/world.feature:47:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = color(0.90498, 0.90498, 0.90498) features/world.feature:48:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The color when a ray misses features/world.feature:50:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:51:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -5), vector(0, 1, 0)) features/world.feature:52:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When c ← color_at(w, r) features/world.feature:53:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = color(0, 0, 0) features/world.feature:54:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The color when a ray hits features/world.feature:56:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:57:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -5), vector(0, 0, 1)) features/world.feature:58:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When c ← color_at(w, r) features/world.feature:59:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = color(0.38066, 0.47583, 0.2855) features/world.feature:60:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The color with an intersection behind the ray [INFO] [stdout] features/world.feature:62:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:63:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And outer ← the first object in w features/world.feature:64:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And outer.material.ambient ← 1 features/world.feature:65:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And inner ← the second object in w features/world.feature:66:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And inner.material.ambient ← 1 features/world.feature:67:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, 0.75), vector(0, 0, -1)) [INFO] [stdout] features/world.feature:68:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When c ← color_at(w, r) features/world.feature:69:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = inner.material.color features/world.feature:70:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: There is no shadow when nothing is collinear with point and light [INFO] [stdout] features/world.feature:72:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:73:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(0, 10, 0) features/world.feature:74:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then is_shadowed(w, p) is false features/world.feature:75:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The shadow when an object is between the point and the light [INFO] [stdout] features/world.feature:77:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:78:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(10, -10, 10) features/world.feature:79:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then is_shadowed(w, p) is true features/world.feature:80:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: There is no shadow when an object is behind the light [INFO] [stdout] features/world.feature:82:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:83:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(-20, 20, -20) features/world.feature:84:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then is_shadowed(w, p) is false features/world.feature:85:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: There is no shadow when an object is behind the point [INFO] [stdout] features/world.feature:87:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:88:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And p ← point(-2, 2, -2) features/world.feature:89:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then is_shadowed(w, p) is false features/world.feature:90:4 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: shade_hit() is given an intersection in shadow [INFO] [stdout] features/world.feature:92:11 [INFO] [stdout] - Given w ← world() features/world.feature:93:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And w.light ← point_light(point(0, 0, -10), color(1, 1, 1)) [INFO] [stdout] features/world.feature:94:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s1 ← sphere() features/world.feature:95:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s1 is added to w features/world.feature:96:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s2 ← sphere() with: features/world.feature:97:5 [INFO] [stdout] | | | [INFO] [stdout] | transform | translation(0, 0, 10) | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And s2 is added to w features/world.feature:99:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, 5), vector(0, 0, 1)) features/world.feature:100:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i ← intersection(4, s2) features/world.feature:101:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(i, r) features/world.feature:102:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c ← shade_hit(w, comps) features/world.feature:103:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = color(0.1, 0.1, 0.1) features/world.feature:104:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The reflected color for a nonreflective material [INFO] [stdout] features/world.feature:106:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:107:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, 0), vector(0, 0, 1)) features/world.feature:108:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← the second object in w features/world.feature:109:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape.material.ambient ← 1 features/world.feature:110:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i ← intersection(1, shape) features/world.feature:111:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(i, r) features/world.feature:112:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And color ← reflected_color(w, comps) features/world.feature:113:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then color = color(0, 0, 0) features/world.feature:114:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The reflected color for a reflective material [INFO] [stdout] features/world.feature:116:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:117:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← plane() with: features/world.feature:118:5 [INFO] [stdout] | material.reflective | 0.5 | [INFO] [stdout] | transform | translation(0, -1, 0) | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape is added to w features/world.feature:121:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -3), vector(0, -√2/2, √2/2)) [INFO] [stdout] features/world.feature:122:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i ← intersection(√2, shape) features/world.feature:123:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(i, r) features/world.feature:124:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And color ← reflected_color(w, comps) features/world.feature:125:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then color = color(0.19032, 0.2379, 0.14274) features/world.feature:126:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: shade_hit() with a reflective material features/world.feature:128:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:129:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← plane() with: features/world.feature:130:5 [INFO] [stdout] | material.reflective | 0.5 | [INFO] [stdout] | transform | translation(0, -1, 0) | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape is added to w features/world.feature:133:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -3), vector(0, -√2/2, √2/2)) [INFO] [stdout] features/world.feature:134:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i ← intersection(√2, shape) features/world.feature:135:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(i, r) features/world.feature:136:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And color ← shade_hit(w, comps) features/world.feature:137:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then color = color(0.87677, 0.92436, 0.82918) features/world.feature:138:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: color_at() with mutually reflective surfaces [INFO] [stdout] features/world.feature:140:11 [INFO] [stdout] - Given w ← world() features/world.feature:141:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And w.light ← point_light(point(0, 0, 0), color(1, 1, 1)) [INFO] [stdout] features/world.feature:142:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And lower ← plane() with: features/world.feature:143:5 [INFO] [stdout] | material.reflective | 1 | [INFO] [stdout] | transform | translation(0, -1, 0) | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And lower is added to w features/world.feature:146:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And upper ← plane() with: features/world.feature:147:5 [INFO] [stdout] | material.reflective | 1 | [INFO] [stdout] | transform | translation(0, 1, 0) | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And upper is added to w features/world.feature:150:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, 0), vector(0, 1, 0)) features/world.feature:151:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then color_at(w, r) should terminate successfully [INFO] [stdout] features/world.feature:152:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The reflected color at the maximum recursive depth [INFO] [stdout] features/world.feature:154:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:155:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← plane() with: features/world.feature:156:5 [INFO] [stdout] | material.reflective | 0.5 | [INFO] [stdout] | transform | translation(0, -1, 0) | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape is added to w features/world.feature:159:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -3), vector(0, -√2/2, √2/2)) [INFO] [stdout] features/world.feature:160:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And i ← intersection(√2, shape) features/world.feature:161:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(i, r) features/world.feature:162:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And color ← reflected_color(w, comps, 0) features/world.feature:163:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then color = color(0, 0, 0) features/world.feature:164:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The refracted color with an opaque surface [INFO] [stdout] features/world.feature:166:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:167:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← the first object in w features/world.feature:168:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -5), vector(0, 0, 1)) features/world.feature:169:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(4:shape, 6:shape) features/world.feature:170:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[0], r, xs) [INFO] [stdout] features/world.feature:171:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c ← refracted_color(w, comps, 5) features/world.feature:172:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = color(0, 0, 0) features/world.feature:173:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The refracted color at the maximum recursive depth [INFO] [stdout] features/world.feature:175:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:176:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← the first object in w features/world.feature:177:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape has: features/world.feature:178:5 [INFO] [stdout] | material.transparency | 1.0 | [INFO] [stdout] | material.refractive_index | 1.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -5), vector(0, 0, 1)) features/world.feature:181:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(4:shape, 6:shape) features/world.feature:182:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[0], r, xs) [INFO] [stdout] features/world.feature:183:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c ← refracted_color(w, comps, 0) features/world.feature:184:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = color(0, 0, 0) features/world.feature:185:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The refracted color under total internal reflection [INFO] [stdout] features/world.feature:187:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:188:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape ← the first object in w features/world.feature:189:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And shape has: features/world.feature:190:5 [INFO] [stdout] | material.transparency | 1.0 | [INFO] [stdout] | material.refractive_index | 1.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, √2/2), vector(0, 1, 0)) [INFO] [stdout] features/world.feature:193:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(-√2/2:shape, √2/2:shape) [INFO] [stdout] features/world.feature:194:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[1], r, xs) [INFO] [stdout] features/world.feature:197:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c ← refracted_color(w, comps, 5) features/world.feature:198:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = color(0, 0, 0) features/world.feature:199:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: The refracted color with a refracted ray [INFO] [stdout] features/world.feature:201:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:202:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And A ← the first object in w features/world.feature:203:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And A has: features/world.feature:204:5 [INFO] [stdout] | material.ambient | 1.0 | [INFO] [stdout] | material.pattern | test_pattern() | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B ← the second object in w features/world.feature:207:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And B has: features/world.feature:208:5 [INFO] [stdout] | material.transparency | 1.0 | [INFO] [stdout] | material.refractive_index | 1.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, 0.1), vector(0, 1, 0)) features/world.feature:211:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(-0.9899:A, -0.4899:B, 0.4899:B, 0.9899:A) [INFO] [stdout] features/world.feature:212:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[2], r, xs) [INFO] [stdout] features/world.feature:213:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And c ← refracted_color(w, comps, 5) features/world.feature:214:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then c = color(0, 0.99888, 0.04725) features/world.feature:215:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: shade_hit() with a transparent material [INFO] [stdout] features/world.feature:217:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:218:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And floor ← plane() with: features/world.feature:219:5 [INFO] [stdout] | transform | translation(0, -1, 0) | [INFO] [stdout] | material.transparency | 0.5 | [INFO] [stdout] | material.refractive_index | 1.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And floor is added to w features/world.feature:223:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And ball ← sphere() with: features/world.feature:224:5 [INFO] [stdout] | material.color | (1, 0, 0) | [INFO] [stdout] | material.ambient | 0.5 | [INFO] [stdout] | transform | translation(0, -3.5, -0.5) | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And ball is added to w features/world.feature:228:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -3), vector(0, -√2/2, √2/2)) [INFO] [stdout] features/world.feature:229:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(√2:floor) features/world.feature:230:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[0], r, xs) [INFO] [stdout] features/world.feature:231:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And color ← shade_hit(w, comps, 5) features/world.feature:232:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then color = color(0.93642, 0.68642, 0.68642) features/world.feature:233:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] Scenario: shade_hit() with a reflective, transparent material [INFO] [stdout] features/world.feature:235:11 [INFO] [stdout] - Given w ← default_world() features/world.feature:236:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And r ← ray(point(0, 0, -3), vector(0, -√2/2, √2/2)) [INFO] [stdout] features/world.feature:237:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And floor ← plane() with: features/world.feature:238:5 [INFO] [stdout] | transform | translation(0, -1, 0) | [INFO] [stdout] | material.reflective | 0.5 | [INFO] [stdout] | material.transparency | 0.5 | [INFO] [stdout] | material.refractive_index | 1.5 | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And floor is added to w features/world.feature:243:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And ball ← sphere() with: features/world.feature:244:5 [INFO] [stdout] | material.color | (1, 0, 0) | [INFO] [stdout] | material.ambient | 0.5 | [INFO] [stdout] | transform | translation(0, -3.5, -0.5) | [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And ball is added to w features/world.feature:248:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And xs ← intersections(√2:floor) features/world.feature:249:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - When comps ← prepare_computations(xs[0], r, xs) [INFO] [stdout] features/world.feature:250:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - And color ← shade_hit(w, comps, 5) features/world.feature:251:5 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] - Then color = color(0.93391, 0.69643, 0.69243) features/world.feature:252:3 [INFO] [stdout] ⚡ Not yet implemented (skipped) [INFO] [stdout] [INFO] [stdout] 22 features [INFO] [stdout] 318 scenarios (318 skipped, 0 passed) [INFO] [stdout] 1637 steps (1637 skipped, 0 passed) [INFO] [stdout] [INFO] running `Command { std: "docker" "inspect" "5c897d955e20fee26b3d60f8040c961ede71c78202b93ff1e9a2bcd1ba2cb609", kill_on_drop: false }` [INFO] running `Command { std: "docker" "rm" "-f" "5c897d955e20fee26b3d60f8040c961ede71c78202b93ff1e9a2bcd1ba2cb609", kill_on_drop: false }` [INFO] [stdout] 5c897d955e20fee26b3d60f8040c961ede71c78202b93ff1e9a2bcd1ba2cb609