mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 14:52:01 +03:00
Integration Test Framework (#3257)
This commit is contained in:
parent
1814d3c4f1
commit
c68ac5c0d6
395
Cargo.lock
generated
395
Cargo.lock
generated
@ -44,15 +44,6 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.45"
|
||||
@ -109,22 +100,11 @@ dependencies = [
|
||||
"Inflector",
|
||||
"enso-macro-utils",
|
||||
"enso-prelude",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ast-new"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"itertools 0.10.1",
|
||||
"proc-macro2 1.0.32",
|
||||
"syn",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-std"
|
||||
version = "1.5.0"
|
||||
@ -385,12 +365,6 @@ version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
@ -423,13 +397,9 @@ version = "2.33.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -459,16 +429,6 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "combine"
|
||||
version = "4.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2b2f5d0ee456f3928812dfc8c6d9a1d592b98678f6d56db9b0cd2b7bc6c8db5"
|
||||
dependencies = [
|
||||
"bytes 1.1.0",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "config-reader"
|
||||
version = "0.1.0"
|
||||
@ -488,10 +448,6 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "controller"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
@ -678,7 +634,7 @@ version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa"
|
||||
dependencies = [
|
||||
"quote 1.0.10",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@ -719,8 +675,8 @@ version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@ -731,8 +687,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version 0.3.3",
|
||||
"syn",
|
||||
]
|
||||
@ -768,7 +724,7 @@ dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
"uuid",
|
||||
"wasm-bindgen-test 0.3.8",
|
||||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -804,10 +760,6 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "engine-model"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "engine-protocol"
|
||||
version = "0.1.0"
|
||||
@ -834,7 +786,7 @@ dependencies = [
|
||||
"sha3",
|
||||
"tokio",
|
||||
"uuid",
|
||||
"wasm-bindgen-test 0.3.8",
|
||||
"wasm-bindgen-test",
|
||||
"zip",
|
||||
"zip-extensions",
|
||||
]
|
||||
@ -903,12 +855,12 @@ dependencies = [
|
||||
"enso-prelude",
|
||||
"itertools 0.8.2",
|
||||
"nonempty",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"unicode-segmentation",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test 0.2.50",
|
||||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -983,11 +935,24 @@ dependencies = [
|
||||
"span-tree",
|
||||
"uuid",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test 0.3.8",
|
||||
"wasm-bindgen-test",
|
||||
"web-sys",
|
||||
"websocket",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enso-integration-test"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"enso-frp",
|
||||
"enso-gui",
|
||||
"enso-prelude",
|
||||
"enso-web",
|
||||
"ensogl",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enso-lazy-reader"
|
||||
version = "0.2.0"
|
||||
@ -1011,10 +976,10 @@ dependencies = [
|
||||
name = "enso-macro-utils"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-test 0.2.50",
|
||||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1052,7 +1017,7 @@ dependencies = [
|
||||
"shrinkwraprs 0.3.0",
|
||||
"smallvec 1.7.0",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test 0.2.50",
|
||||
"wasm-bindgen-test",
|
||||
"weak-table",
|
||||
"web-sys",
|
||||
]
|
||||
@ -1071,8 +1036,8 @@ name = "enso-profiler-macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@ -1086,7 +1051,7 @@ dependencies = [
|
||||
"paste 0.1.18",
|
||||
"rustversion",
|
||||
"shrinkwraprs 0.3.0",
|
||||
"wasm-bindgen-test 0.2.50",
|
||||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1097,10 +1062,10 @@ dependencies = [
|
||||
"boolinator",
|
||||
"enso-macro-utils",
|
||||
"itertools 0.8.2",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-test 0.2.50",
|
||||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1120,39 +1085,6 @@ dependencies = [
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enso-shortcuts-examples"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"enso-automata",
|
||||
"enso-frp",
|
||||
"enso-logger",
|
||||
"enso-prelude",
|
||||
"enso-shortcuts",
|
||||
"enso-web",
|
||||
"js-sys",
|
||||
"nalgebra 0.26.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enso-span-tree-example"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ast",
|
||||
"enso-logger",
|
||||
"enso-prelude",
|
||||
"enso-text",
|
||||
"enso-web",
|
||||
"span-tree",
|
||||
"uuid",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enso-text"
|
||||
version = "0.1.0"
|
||||
@ -1186,7 +1118,7 @@ dependencies = [
|
||||
"js-sys",
|
||||
"nalgebra 0.26.2",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test 0.3.8",
|
||||
"wasm-bindgen-test",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
@ -1250,7 +1182,7 @@ dependencies = [
|
||||
"smallvec 1.7.0",
|
||||
"typenum",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test 0.3.8",
|
||||
"wasm-bindgen-test",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
@ -1275,7 +1207,7 @@ dependencies = [
|
||||
"enso-web",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures 0.4.8",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
@ -1316,7 +1248,7 @@ dependencies = [
|
||||
"ensogl-core",
|
||||
"ensogl-drop-manager",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures 0.4.8",
|
||||
"wasm-bindgen-futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1469,7 +1401,7 @@ dependencies = [
|
||||
"enso-logger",
|
||||
"ensogl-core",
|
||||
"float_eq",
|
||||
"wasm-bindgen-test 0.3.8",
|
||||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1555,7 +1487,7 @@ dependencies = [
|
||||
"ensogl-hardcoded-theme",
|
||||
"ensogl-text-embedded-fonts",
|
||||
"ensogl-text-msdf-sys",
|
||||
"wasm-bindgen-test 0.3.8",
|
||||
"wasm-bindgen-test",
|
||||
"xi-rope",
|
||||
]
|
||||
|
||||
@ -1579,7 +1511,7 @@ dependencies = [
|
||||
"js-sys",
|
||||
"nalgebra 0.26.2",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test 0.3.8",
|
||||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1597,18 +1529,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd53b3fde38a39a06b2e66dc282f3e86191e53bd04cc499929c15742beae3df8"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "eval-tt"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"paste 1.0.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "failure"
|
||||
version = "0.1.8"
|
||||
@ -1625,8 +1550,8 @@ version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
@ -1661,21 +1586,6 @@ dependencies = [
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flexer-test-definition"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"enso-flexer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flexer-test-generation"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"enso-flexer",
|
||||
"flexer-test-definition",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flo_stream"
|
||||
version = "0.4.0"
|
||||
@ -1822,8 +1732,8 @@ checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb"
|
||||
dependencies = [
|
||||
"autocfg 1.0.1",
|
||||
"proc-macro-hack",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@ -2195,8 +2105,8 @@ checksum = "e50385662f423431a619ab28ba2beeab3063b581a0d1a943765e23911c502904"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"proc-macro-hack",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"syn",
|
||||
]
|
||||
@ -2259,26 +2169,6 @@ version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec"
|
||||
dependencies = [
|
||||
"cesu8",
|
||||
"combine",
|
||||
"jni-sys",
|
||||
"log 0.4.14",
|
||||
"thiserror",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.35"
|
||||
@ -2572,8 +2462,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a673cb441f78cd9af4f5919c28576a3cc325fb6b54e42f7047dacce3c718c17b"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@ -2817,8 +2707,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "486ea01961c4a818096de679a8b740b26d9033146ac5291b1c98557658f8cdd9"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@ -2957,18 +2847,10 @@ dependencies = [
|
||||
"tokio",
|
||||
"uuid",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test 0.3.8",
|
||||
"wasm-bindgen-test",
|
||||
"websocket",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parser-jni"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ast-new",
|
||||
"jni",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parser-new"
|
||||
version = "0.1.0"
|
||||
@ -3048,8 +2930,8 @@ version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@ -3146,31 +3028,13 @@ version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3179,7 +3043,7 @@ version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3495,7 +3359,7 @@ dependencies = [
|
||||
"tokio-tls 0.3.1",
|
||||
"url 2.2.2",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures 0.4.8",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"winreg",
|
||||
]
|
||||
@ -3678,8 +3542,8 @@ version = "1.0.130"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@ -3745,8 +3609,8 @@ checksum = "83695fde96cbe9e08f0e4eb96b1b56fdbd44f2098ee27462dda964c7745fddc7"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"itertools 0.8.2",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@ -3758,8 +3622,8 @@ checksum = "e63e6744142336dfb606fe2b068afa2e1cca1ee6a5d8377277a92945d81fa331"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"itertools 0.8.2",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@ -3851,24 +3715,18 @@ dependencies = [
|
||||
"enso-text",
|
||||
"failure",
|
||||
"parser",
|
||||
"wasm-bindgen-test 0.3.8",
|
||||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"unicode-xid 0.2.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3877,10 +3735,10 @@ version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"unicode-xid 0.2.2",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3927,8 +3785,8 @@ version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@ -4024,8 +3882,8 @@ version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
@ -4228,12 +4086,6 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
@ -4290,12 +4142,6 @@ version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.1.5"
|
||||
@ -4362,25 +4208,12 @@ dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log 0.4.14",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"futures 0.1.31",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.8"
|
||||
@ -4399,7 +4232,7 @@ version = "0.2.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3"
|
||||
dependencies = [
|
||||
"quote 1.0.10",
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
@ -4409,8 +4242,8 @@ version = "0.2.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
@ -4422,21 +4255,6 @@ version = "0.2.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test"
|
||||
version = "0.2.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2d9693b63a742d481c7f80587e057920e568317b2806988c59cd71618bc26c1"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"futures 0.1.31",
|
||||
"js-sys",
|
||||
"scoped-tls",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures 0.3.27",
|
||||
"wasm-bindgen-test-macro 0.2.50",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test"
|
||||
version = "0.3.8"
|
||||
@ -4447,18 +4265,8 @@ dependencies = [
|
||||
"js-sys",
|
||||
"scoped-tls",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures 0.4.8",
|
||||
"wasm-bindgen-test-macro 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test-macro"
|
||||
version = "0.2.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0789dac148a8840bbcf9efe13905463b733fa96543bfbf263790535c11af7ba5"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-bindgen-test-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4467,8 +4275,8 @@ version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97837a6e83ab24a4b3a38d44a257e13335b54f4b4548b2c9d71edd0bf570cb4f"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4480,8 +4288,8 @@ dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
"log 0.4.14",
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"weedle",
|
||||
@ -4506,31 +4314,6 @@ dependencies = [
|
||||
"wasm-bindgen-webidl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-test"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"enso-prelude",
|
||||
"enso-web",
|
||||
"ensogl",
|
||||
"js-sys",
|
||||
"shrinkwraprs 0.3.0",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test 0.3.8",
|
||||
"web-sys",
|
||||
"web-test-proc-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-test-proc-macro"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.32",
|
||||
"quote 1.0.10",
|
||||
"syn",
|
||||
"wasm-bindgen-test 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "websocket"
|
||||
version = "0.23.0"
|
||||
|
103
Cargo.toml
103
Cargo.toml
@ -1,97 +1,22 @@
|
||||
[workspace]
|
||||
|
||||
# Listing only the "root" crates of each app/library. All path dependencies are included in the workspace automatically.
|
||||
# If you want to add sub crate (like `app/gui/config` or `lib/rust/ensogl/example`), just add it as a path dependency
|
||||
# where plausible.
|
||||
members = [
|
||||
"app/gui",
|
||||
"app/gui/controller",
|
||||
"app/gui/controller/double-representation",
|
||||
"app/gui/controller/engine-model",
|
||||
"app/gui/controller/engine-protocol",
|
||||
"app/gui/analytics",
|
||||
"app/gui/config",
|
||||
"app/gui/language/ast/impl",
|
||||
"app/gui/language/ast/macros",
|
||||
"app/gui/language/parser",
|
||||
"app/gui/language/span-tree",
|
||||
"app/gui/language/span-tree/example",
|
||||
"app/gui/view",
|
||||
"app/gui/view/debug_scene",
|
||||
"app/gui/view/debug_scene/interface",
|
||||
"app/gui/view/debug_scene/visualization",
|
||||
"app/gui/view/graph-editor",
|
||||
"app/gui/view/welcome-screen",
|
||||
"build/rust-scripts",
|
||||
"lib/rust/automata",
|
||||
"lib/rust/build-utils",
|
||||
"lib/rust/callback",
|
||||
"lib/rust/code-builder",
|
||||
"lib/rust/config-reader",
|
||||
"lib/rust/data-structures",
|
||||
"lib/rust/ensogl",
|
||||
"lib/rust/ensogl/app/theme/hardcoded",
|
||||
"lib/rust/ensogl/core",
|
||||
"lib/rust/ensogl/component",
|
||||
"lib/rust/ensogl/component/drop-down-menu",
|
||||
"lib/rust/ensogl/component/drop-manager",
|
||||
"lib/rust/ensogl/component/file-browser",
|
||||
"lib/rust/ensogl/component/gui",
|
||||
"lib/rust/ensogl/component/label",
|
||||
"lib/rust/ensogl/component/list-view",
|
||||
"lib/rust/ensogl/component/scroll-area",
|
||||
"lib/rust/ensogl/component/scrollbar",
|
||||
"lib/rust/ensogl/component/selector",
|
||||
"lib/rust/ensogl/component/shadow",
|
||||
"lib/rust/ensogl/component/text",
|
||||
"lib/rust/ensogl/component/text/embedded-fonts",
|
||||
"lib/rust/ensogl/component/text/msdf-sys",
|
||||
"lib/rust/ensogl/component/toggle-button",
|
||||
"lib/rust/ensogl/example",
|
||||
"lib/rust/ensogl/example/animation",
|
||||
"lib/rust/ensogl/example/complex-shape-system",
|
||||
"lib/rust/ensogl/example/dom-symbols",
|
||||
"lib/rust/ensogl/example/drop-manager",
|
||||
"lib/rust/ensogl/example/easing-animator",
|
||||
"lib/rust/ensogl/example/glyph-system",
|
||||
"lib/rust/ensogl/example/list-view",
|
||||
"lib/rust/ensogl/example/mouse-events",
|
||||
"lib/rust/ensogl/example/scroll-area",
|
||||
"lib/rust/ensogl/example/shape-system",
|
||||
"lib/rust/ensogl/example/slider",
|
||||
"lib/rust/ensogl/example/sprite-system",
|
||||
"lib/rust/ensogl/example/sprite-system-benchmark",
|
||||
"lib/rust/ensogl/example/stats",
|
||||
"lib/rust/ensogl/example/text-area",
|
||||
"lib/rust/frp",
|
||||
"lib/rust/fuzzly",
|
||||
"lib/rust/generics",
|
||||
"lib/rust/json-rpc",
|
||||
"lib/rust/launcher-shims",
|
||||
"lib/rust/logger",
|
||||
"lib/rust/macro-utils",
|
||||
"lib/rust/optics",
|
||||
"lib/rust/parser",
|
||||
"lib/rust/parser/ast",
|
||||
"lib/rust/parser/flexer",
|
||||
"lib/rust/prelude",
|
||||
"lib/rust/profiler",
|
||||
"lib/rust/profiler/macros",
|
||||
"lib/rust/parser/flexer-testing/definition",
|
||||
"lib/rust/parser/flexer-testing/generation",
|
||||
"lib/rust/parser/lexer/definition",
|
||||
"lib/rust/parser/lexer/generation",
|
||||
"lib/rust/parser/parser-jni",
|
||||
"lib/rust/parser/lazy-reader",
|
||||
"lib/rust/shapely/impl",
|
||||
"lib/rust/shapely/macros",
|
||||
"lib/rust/shortcuts",
|
||||
"lib/rust/shortcuts/example",
|
||||
"lib/rust/text",
|
||||
"lib/rust/types",
|
||||
"lib/rust/web",
|
||||
"lib/rust/not-used/eval-tt",
|
||||
"lib/rust/not-used/web-test",
|
||||
"lib/rust/not-used/web-test-proc-macro",
|
||||
"lib/rust/*",
|
||||
"lib/rust/not-used/*",
|
||||
"integration-test"
|
||||
]
|
||||
|
||||
# This directory is not a crate
|
||||
exclude = ["lib/rust/not-used"]
|
||||
|
||||
# The default memebers are those we want to check and test by default.
|
||||
default-members = ["app/gui", "lib/rust/*"]
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 0
|
||||
lto = false
|
||||
@ -115,3 +40,7 @@ opt-level = 0
|
||||
lto = false
|
||||
debug = true
|
||||
debug-assertions = true
|
||||
|
||||
[profile.integration-test]
|
||||
inherits = "test"
|
||||
opt-level = 2
|
||||
|
@ -18,7 +18,7 @@ enso-frp = { path = "../../lib/rust/frp" }
|
||||
enso-logger = { path = "../../lib/rust/logger"}
|
||||
enso-prelude = { path = "../../lib/rust/prelude"}
|
||||
enso-profiler = { path = "../../lib/rust/profiler" }
|
||||
enso-shapely = { path = "../../lib/rust/shapely/impl"}
|
||||
enso-shapely = { path = "../../lib/rust/shapely"}
|
||||
enso-text = { path = "../../lib/rust/text" }
|
||||
enso-web = { path = "../../lib/rust/web" }
|
||||
ensogl = { path = "../../lib/rust/ensogl" }
|
||||
|
@ -376,7 +376,7 @@ mod tests {
|
||||
name: impl Str,
|
||||
ast: &Ast,
|
||||
expected: Vec<Range<usize>>,
|
||||
actual: &Vec<LocatedName>,
|
||||
actual: &[LocatedName],
|
||||
) {
|
||||
let mut checker = IdentifierValidator::new(name, ast, expected);
|
||||
checker.validate_identifiers(actual);
|
||||
|
@ -149,8 +149,8 @@ impl<'a> IdentifierValidator<'a> {
|
||||
let crumbs = &identifier.crumbs;
|
||||
let ast_result = self.ast.get_traversing(crumbs);
|
||||
let ast = ast_result.expect("failed to retrieve ast from crumb");
|
||||
let name_err = || iformat!("Failed to use AST {ast.repr()} as an identifier name");
|
||||
let name = NormalizedName::try_from_ast(ast).expect(&name_err());
|
||||
let name_err = || ipanic!("Failed to use AST {ast.repr()} as an identifier name");
|
||||
let name = NormalizedName::try_from_ast(ast).unwrap_or_else(name_err);
|
||||
assert_eq!(name, identifier.item)
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ mod tests {
|
||||
|
||||
impl TestRun {
|
||||
fn from_definition(definition: DefinitionInfo) -> TestRun {
|
||||
let graph = GraphInfo::from_definition(definition.clone());
|
||||
let graph = GraphInfo::from_definition(definition);
|
||||
let repr_of = |connection: &Connection| {
|
||||
let endpoint = &connection.source;
|
||||
let node = graph.find_node(endpoint.node).unwrap();
|
||||
@ -177,7 +177,7 @@ mod tests {
|
||||
};
|
||||
|
||||
let mut connections = graph.connections();
|
||||
connections.sort_by(|lhs, rhs| repr_of(&lhs).cmp(&repr_of(&rhs)));
|
||||
connections.sort_by_key(|con| repr_of(con));
|
||||
|
||||
TestRun { graph, connections }
|
||||
}
|
||||
@ -273,7 +273,7 @@ f = fun 2";
|
||||
for node in nodes {
|
||||
let node_repr = node.ast().repr();
|
||||
let expected = expected_dependent_nodes.get(node_repr.as_str()).unwrap();
|
||||
let result = dependent_nodes_in_def(&graph.source.body().item, node.id());
|
||||
let result = dependent_nodes_in_def(graph.source.body().item, node.id());
|
||||
let result_node = result.iter().map(|id| graph.find_node(*id).unwrap());
|
||||
let mut result_repr = result_node.map(|n| n.ast().repr()).collect_vec();
|
||||
result_repr.sort();
|
||||
|
@ -556,7 +556,7 @@ mod tests {
|
||||
assert_eq!(lhs, rhs)
|
||||
}
|
||||
|
||||
fn to_names(defs: &Vec<DefinitionInfo>) -> Vec<String> {
|
||||
fn to_names(defs: &[DefinitionInfo]) -> Vec<String> {
|
||||
defs.iter().map(|def| def.name.to_string()).collect()
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,7 @@ mod tests {
|
||||
|
||||
fn find_graph(parser: &parser::Parser, program: impl Str, name: impl Str) -> GraphInfo {
|
||||
let module = parser.parse_module(program.into(), default()).unwrap();
|
||||
let crumbs = name.into().split(".").map(|name| DefinitionName::new_plain(name)).collect();
|
||||
let crumbs = name.into().split('.').map(DefinitionName::new_plain).collect();
|
||||
let id = Id { crumbs };
|
||||
let definition = get_definition(&module, &id).unwrap();
|
||||
GraphInfo::from_definition(definition)
|
||||
@ -230,7 +230,7 @@ mod tests {
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn detect_a_node() {
|
||||
let mut parser = parser::Parser::new_or_panic();
|
||||
let parser = parser::Parser::new_or_panic();
|
||||
// Each of these programs should have a `main` definition with a single `2+2` node.
|
||||
let programs = vec![
|
||||
"main = 2+2",
|
||||
@ -239,7 +239,7 @@ mod tests {
|
||||
"main = \n foo = 2+2\n bar b = 2+2", // `bar` is a definition, not a node
|
||||
];
|
||||
for program in programs {
|
||||
let graph = main_graph(&mut parser, program);
|
||||
let graph = main_graph(&parser, program);
|
||||
let nodes = graph.nodes();
|
||||
assert_eq!(nodes.len(), 1);
|
||||
let node = &nodes[0];
|
||||
@ -300,14 +300,14 @@ mod tests {
|
||||
foo = node
|
||||
foo a = not_node
|
||||
print "hello""#;
|
||||
let mut parser = parser::Parser::new_or_panic();
|
||||
let mut graph = main_graph(&mut parser, program);
|
||||
let parser = parser::Parser::new_or_panic();
|
||||
let mut graph = main_graph(&parser, program);
|
||||
|
||||
let node_to_add0 = new_expression_node(&mut parser, "4 + 4");
|
||||
let node_to_add1 = new_expression_node(&mut parser, "a + b");
|
||||
let node_to_add2 = new_expression_node(&mut parser, "x * x");
|
||||
let node_to_add3 = new_expression_node(&mut parser, "x / x");
|
||||
let node_to_add4 = new_expression_node(&mut parser, "2 - 2");
|
||||
let node_to_add0 = new_expression_node(&parser, "4 + 4");
|
||||
let node_to_add1 = new_expression_node(&parser, "a + b");
|
||||
let node_to_add2 = new_expression_node(&parser, "x * x");
|
||||
let node_to_add3 = new_expression_node(&parser, "x / x");
|
||||
let node_to_add4 = new_expression_node(&parser, "2 - 2");
|
||||
|
||||
graph.add_node(&node_to_add0, LocationHint::Start).unwrap();
|
||||
graph.add_node(&node_to_add1, LocationHint::Before(graph.nodes()[0].id())).unwrap();
|
||||
@ -339,7 +339,7 @@ mod tests {
|
||||
x / x"#;
|
||||
graph.expect_code(expected_code);
|
||||
|
||||
let mut graph = find_graph(&mut parser, program, "main.foo");
|
||||
let mut graph = find_graph(&parser, program, "main.foo");
|
||||
assert_eq!(graph.nodes().len(), 1);
|
||||
graph.add_node(&node_to_add4, LocationHint::Start).unwrap();
|
||||
assert_eq!(graph.nodes().len(), 2);
|
||||
@ -359,14 +359,14 @@ mod tests {
|
||||
node2
|
||||
|
||||
foo = 5";
|
||||
let mut parser = parser::Parser::new_or_panic();
|
||||
let mut graph = main_graph(&mut parser, program);
|
||||
let parser = parser::Parser::new_or_panic();
|
||||
let mut graph = main_graph(&parser, program);
|
||||
|
||||
let id2 = graph.nodes()[0].id();
|
||||
let node_to_add0 = new_expression_node(&mut parser, "node0");
|
||||
let node_to_add1 = new_expression_node(&mut parser, "node1");
|
||||
let node_to_add3 = new_expression_node(&mut parser, "node3");
|
||||
let node_to_add4 = new_expression_node(&mut parser, "node4");
|
||||
let node_to_add0 = new_expression_node(&parser, "node0");
|
||||
let node_to_add1 = new_expression_node(&parser, "node1");
|
||||
let node_to_add3 = new_expression_node(&parser, "node3");
|
||||
let node_to_add4 = new_expression_node(&parser, "node4");
|
||||
|
||||
graph.add_node(&node_to_add0, LocationHint::Start).unwrap();
|
||||
graph.add_node(&node_to_add1, LocationHint::Before(id2)).unwrap();
|
||||
@ -387,7 +387,7 @@ foo = 5";
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn multiple_node_graph() {
|
||||
let mut parser = parser::Parser::new_or_panic();
|
||||
let parser = parser::Parser::new_or_panic();
|
||||
let program = r"
|
||||
main =
|
||||
## Faux docstring
|
||||
@ -403,7 +403,7 @@ main =
|
||||
// TODO [mwu]
|
||||
// Add case like `Int.+ a = not_node` once https://github.com/enso-org/enso/issues/565 is fixed
|
||||
|
||||
let graph = main_graph(&mut parser, program);
|
||||
let graph = main_graph(&parser, program);
|
||||
let nodes = graph.nodes();
|
||||
assert_eq!(nodes[0].documentation_text(), Some(" Docstring 0".into()));
|
||||
assert_eq!(nodes[0].ast().repr(), "foo = node0");
|
||||
@ -418,12 +418,12 @@ main =
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn removing_node_from_graph() {
|
||||
let mut parser = parser::Parser::new_or_panic();
|
||||
let parser = parser::Parser::new_or_panic();
|
||||
let program = r"
|
||||
main =
|
||||
foo = 2 + 2
|
||||
bar = 3 + 17";
|
||||
let mut graph = main_graph(&mut parser, program);
|
||||
let mut graph = main_graph(&parser, program);
|
||||
let nodes = graph.nodes();
|
||||
assert_eq!(nodes.len(), 2);
|
||||
assert_eq!(nodes[0].expression().repr(), "2 + 2");
|
||||
@ -444,11 +444,11 @@ main =
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn removing_last_node_from_graph() {
|
||||
let mut parser = parser::Parser::new_or_panic();
|
||||
let parser = parser::Parser::new_or_panic();
|
||||
let program = r"
|
||||
main =
|
||||
foo = 2 + 2";
|
||||
let mut graph = main_graph(&mut parser, program);
|
||||
let mut graph = main_graph(&parser, program);
|
||||
DEBUG!("aa");
|
||||
let (node,) = graph.nodes().expect_tuple();
|
||||
assert_eq!(node.expression().repr(), "2 + 2");
|
||||
@ -464,7 +464,7 @@ main =
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn editing_nodes_expression_in_graph() {
|
||||
let mut parser = parser::Parser::new_or_panic();
|
||||
let parser = parser::Parser::new_or_panic();
|
||||
let program = r"
|
||||
main =
|
||||
foo = 2 + 2
|
||||
@ -472,7 +472,7 @@ main =
|
||||
let new_expression = parser.parse("print \"HELLO\"".to_string(), default()).unwrap();
|
||||
let new_expression = expect_single_line(&new_expression).clone();
|
||||
|
||||
let mut graph = main_graph(&mut parser, program);
|
||||
let mut graph = main_graph(&parser, program);
|
||||
let nodes = graph.nodes();
|
||||
assert_eq!(nodes.len(), 2);
|
||||
assert_eq!(nodes[0].expression().repr(), "2 + 2");
|
||||
|
@ -212,7 +212,7 @@ mod tests {
|
||||
let code = DocumentationCommentInfo::text_to_repr(main.indent(), &text);
|
||||
let ast2 = parser.parse_line(&code).unwrap();
|
||||
let doc2 = DocumentationCommentInfo::new(&ast2.as_ref(), main.indent())
|
||||
.expect(&format!("Failed to parse `{}` as comment", code));
|
||||
.unwrap_or_else(|| panic!("Failed to parse `{code}` as comment"));
|
||||
assert_eq!(doc.line().repr(), doc2.line().repr())
|
||||
}
|
||||
|
||||
|
@ -997,11 +997,11 @@ main = here.method1 10"#;
|
||||
repr_after_insertion(Placement::Begin)
|
||||
);
|
||||
assert_eq!(
|
||||
repr_after_insertion(Placement::After(method1_id.clone())),
|
||||
repr_after_insertion(Placement::After(method1_id)),
|
||||
repr_after_insertion(Placement::Before(main_id.clone()))
|
||||
);
|
||||
assert_eq!(
|
||||
repr_after_insertion(Placement::After(main_id.clone())),
|
||||
repr_after_insertion(Placement::After(main_id)),
|
||||
repr_after_insertion(Placement::End)
|
||||
);
|
||||
|
||||
|
@ -418,7 +418,7 @@ mod tests {
|
||||
let main_crumb = Crumb::from(main.crumb());
|
||||
module.ast = module.ast.set(&main_crumb, new_main.ast().clone()).unwrap();
|
||||
module.add_method(collapsed.new_method, placement, parser).unwrap();
|
||||
ast::test_utils::assert_unique_ids(&module.ast.as_ref());
|
||||
ast::test_utils::assert_unique_ids(module.ast.as_ref());
|
||||
info!(logger, "Updated method:\n{&module.ast}");
|
||||
assert_eq!(new_method.repr(), self.expected_generated);
|
||||
assert_eq!(new_main.repr(), self.expected_refactored);
|
||||
|
@ -11,7 +11,7 @@ crate-type = ["cdylib", "rlib"]
|
||||
enso-data-structures = { path = "../../../../lib/rust/data-structures" }
|
||||
enso-logger = { path = "../../../../lib/rust/logger"}
|
||||
enso-prelude = { path = "../../../../lib/rust/prelude"}
|
||||
enso-shapely = { path = "../../../../lib/rust/shapely/impl"}
|
||||
enso-shapely = { path = "../../../../lib/rust/shapely"}
|
||||
enso-text = { path = "../../../../lib/rust/text"}
|
||||
json-rpc = { path = "../../../../lib/rust/json-rpc" }
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
|
@ -317,7 +317,7 @@ mod tests {
|
||||
let mock_error_message = "This is error".to_string();
|
||||
let mut mock_reply = MessageFromServer::new(FromServerPayloadOwned::Error {
|
||||
code: mock_error_code,
|
||||
message: mock_error_message.clone(),
|
||||
message: mock_error_message,
|
||||
data: None,
|
||||
});
|
||||
mock_reply.correlation_id = Some(generated_message.message_id);
|
||||
@ -359,7 +359,7 @@ mod tests {
|
||||
|client| client.read_file(&path),
|
||||
data.clone(),
|
||||
ToServerPayloadOwned::ReadFile { path: path.clone() },
|
||||
FromServerPayloadOwned::FileContentsReply { contents: data.clone() },
|
||||
FromServerPayloadOwned::FileContentsReply { contents: data },
|
||||
);
|
||||
}
|
||||
|
||||
@ -384,8 +384,8 @@ mod tests {
|
||||
};
|
||||
let data = Vec::from("Hello".as_bytes());
|
||||
let message = MessageFromServer::new(FromServerPayloadOwned::VisualizationUpdate {
|
||||
data: data.clone(),
|
||||
context: context.clone(),
|
||||
data: data.clone(),
|
||||
context,
|
||||
});
|
||||
|
||||
|
||||
|
@ -346,7 +346,7 @@ fn test_computed_value_update() {
|
||||
assert_eq!(expression_updates.context_id, context_id);
|
||||
let update = &expression_updates.updates.first().unwrap();
|
||||
assert_eq!(update.expression_id, id);
|
||||
assert_eq!(update.typename.as_ref().map(|ty| ty.as_str()), Some(typename));
|
||||
assert_eq!(update.typename.as_deref(), Some(typename));
|
||||
assert!(update.method_pointer.is_none());
|
||||
assert!(update.from_cache);
|
||||
assert!(matches!(update.payload, ExpressionUpdatePayload::Value))
|
||||
|
@ -392,7 +392,7 @@ mod remote_client_tests {
|
||||
let project_id = Uuid::default();
|
||||
let missing_component_action = MissingComponentAction::Install;
|
||||
let engine_version = "1.0.0".to_owned();
|
||||
let engine_version_opt = Some(engine_version.clone());
|
||||
let engine_version_opt = Some(engine_version);
|
||||
let create_project_response = response::CreateProject { project_id };
|
||||
let project_id_json = json!({"projectId":"00000000-0000-0000-0000-000000000000"});
|
||||
let project_id_and_mca = json!({
|
||||
|
@ -152,6 +152,8 @@ The subdirectories of interests are:
|
||||
paradigm in rust.
|
||||
- `build`: All building scripts and utilities, mostly the logic of the `./run`
|
||||
script.
|
||||
- `integration-test`: A single crate with all integration tests of our
|
||||
applications.
|
||||
|
||||
Other directories are auto-generated `dist` and `target`, or (currently) are the
|
||||
Engine files, which will be moved to `app/engine` soon.
|
||||
@ -278,6 +280,19 @@ have prepared several scripts which maximally automate the process:
|
||||
[official source](https://chromedriver.chromium.org/downloads) and ensure it
|
||||
is in your `PATH`.
|
||||
|
||||
- **Integration Tests** The integration tests are gathered in `integration-test`
|
||||
crate. One test suite can be run with
|
||||
`node ./run integration-test -- --test <suite-name>`. This will spawn required
|
||||
Engine process and then set up a server on localhost:8000 - open the page in
|
||||
Chrome browser to see the tests running. The `<suite-name>` is a name of the
|
||||
file in `integration-test/tests` directory without extension, for example
|
||||
`graph_editor`.
|
||||
- The integration test can create and leave new Enso projects. **Keep it in
|
||||
mind when running the script with your own backend (the `--no-backend`
|
||||
option)**. The Engine spawned by the script will use a dedicated workspace
|
||||
created in temporary directory, so the user workspace will not be affected.
|
||||
- Note: in the future there will be possibility to run all tests suite
|
||||
headlessly.
|
||||
- **Linting** Please be sure to fix all errors reported by `node ./run lint`
|
||||
before creating a pull request to this repository.
|
||||
|
||||
@ -285,7 +300,7 @@ have prepared several scripts which maximally automate the process:
|
||||
|
||||
The following branches are used to develop the product:
|
||||
|
||||
- **wip/[initials]/[feature]**
|
||||
- **wip/[github_user_name]/[feature]**
|
||||
Feature branches. These are temporary branches used by the team to develop a
|
||||
particular feature.
|
||||
- **develop**
|
||||
|
@ -20,4 +20,4 @@ ast-macros = { path = "../macros" }
|
||||
enso-data-structures = { path = "../../../../../lib/rust/data-structures" }
|
||||
enso-text = { path = "../../../../../lib/rust/text" }
|
||||
enso-prelude = { path = "../../../../../lib/rust/prelude" }
|
||||
enso-shapely = { path = "../../../../../lib/rust/shapely/impl" }
|
||||
enso-shapely = { path = "../../../../../lib/rust/shapely" }
|
||||
|
@ -74,11 +74,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_applicative() {
|
||||
assert_eq!(is_applicative("<$>"), true);
|
||||
assert_eq!(is_applicative("<*>"), true);
|
||||
assert_eq!(is_applicative("<*"), true);
|
||||
assert_eq!(is_applicative("*>"), true);
|
||||
assert_eq!(is_applicative("="), false);
|
||||
assert_eq!(is_applicative("++"), false);
|
||||
assert!(is_applicative("<$>"));
|
||||
assert!(is_applicative("<*>"));
|
||||
assert!(is_applicative("<*"));
|
||||
assert!(is_applicative("*>"));
|
||||
assert!(!is_applicative("="));
|
||||
assert!(!is_applicative("++"));
|
||||
}
|
||||
}
|
||||
|
@ -1723,14 +1723,8 @@ mod tests {
|
||||
set(to_crumb_enum, &infix, InfixCrumb::LeftOperand, baz.clone())?.repr(),
|
||||
"baz + bar"
|
||||
);
|
||||
assert_eq!(
|
||||
set(to_crumb_enum, &infix, InfixCrumb::Operator, times.clone())?.repr(),
|
||||
"foo * bar"
|
||||
);
|
||||
assert_eq!(
|
||||
set(to_crumb_enum, &infix, InfixCrumb::RightOperand, baz.clone())?.repr(),
|
||||
"foo + baz"
|
||||
);
|
||||
assert_eq!(set(to_crumb_enum, &infix, InfixCrumb::Operator, times)?.repr(), "foo * bar");
|
||||
assert_eq!(set(to_crumb_enum, &infix, InfixCrumb::RightOperand, baz)?.repr(), "foo + baz");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1935,8 +1929,8 @@ mod tests {
|
||||
assert_eq!(get(PrefixCrumb::Func)?.repr(), "func");
|
||||
assert_eq!(get(PrefixCrumb::Arg)?.repr(), "arg");
|
||||
|
||||
assert_eq!(set(PrefixCrumb::Func, foo.clone())?.repr(), "foo arg");
|
||||
assert_eq!(set(PrefixCrumb::Arg, x.clone())?.repr(), "func x");
|
||||
assert_eq!(set(PrefixCrumb::Func, foo)?.repr(), "foo arg");
|
||||
assert_eq!(set(PrefixCrumb::Arg, x)?.repr(), "func x");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1975,8 +1969,8 @@ mod tests {
|
||||
assert_eq!(get(SectionLeftCrumb::Arg)?.repr(), "foo");
|
||||
assert_eq!(get(SectionLeftCrumb::Opr)?.repr(), "bar");
|
||||
|
||||
assert_eq!(set(SectionLeftCrumb::Arg, arg.clone())?.repr(), "arg bar");
|
||||
assert_eq!(set(SectionLeftCrumb::Opr, opr.clone())?.repr(), "foo opr");
|
||||
assert_eq!(set(SectionLeftCrumb::Arg, arg)?.repr(), "arg bar");
|
||||
assert_eq!(set(SectionLeftCrumb::Opr, opr)?.repr(), "foo opr");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -2014,8 +2008,8 @@ mod tests {
|
||||
assert_eq!(get(SectionRightCrumb::Opr)?.repr(), "foo");
|
||||
assert_eq!(get(SectionRightCrumb::Arg)?.repr(), "bar");
|
||||
|
||||
assert_eq!(set(SectionRightCrumb::Opr, opr.clone())?.repr(), "opr bar");
|
||||
assert_eq!(set(SectionRightCrumb::Arg, arg.clone())?.repr(), "foo arg");
|
||||
assert_eq!(set(SectionRightCrumb::Opr, opr)?.repr(), "opr bar");
|
||||
assert_eq!(set(SectionRightCrumb::Arg, arg)?.repr(), "foo arg");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -2050,7 +2044,7 @@ mod tests {
|
||||
assert_eq!(app.repr(), "foo");
|
||||
|
||||
assert_eq!(get(SectionSidesCrumb)?.repr(), "foo");
|
||||
assert_eq!(set(SectionSidesCrumb, opr.clone())?.repr(), "opr");
|
||||
assert_eq!(set(SectionSidesCrumb, opr)?.repr(), "opr");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -2132,14 +2126,14 @@ mod tests {
|
||||
elem: Shifted { off: 0, wrapped: var.clone() },
|
||||
}));
|
||||
let body = Rc::new(MacroPatternMatchRaw::Seq(MacroPatternMatchRawSeq {
|
||||
pat: MacroPatternRawSeq { pat1: pat.clone(), pat2: pat.clone() },
|
||||
elem: (tok.clone(), tok.clone()),
|
||||
pat: MacroPatternRawSeq { pat1: pat.clone(), pat2: pat },
|
||||
elem: (tok.clone(), tok),
|
||||
}));
|
||||
let segs = ShiftedVec1 {
|
||||
head: MacroMatchSegment { head: var.clone(), body: body.clone() },
|
||||
tail: vec![],
|
||||
};
|
||||
Match { pfx: Some(body), segs, resolved: Some(var.clone()) }
|
||||
Match { pfx: Some(body), segs, resolved: Some(var) }
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -545,7 +545,7 @@ mod tests {
|
||||
let b = Ast::var("b");
|
||||
let c = Ast::var("c");
|
||||
let a_plus_b = Ast::infix(a.clone(), "+", b.clone());
|
||||
let a_plus_b_plus_c = Ast::infix(a_plus_b.clone(), "+", c.clone());
|
||||
let a_plus_b_plus_c = Ast::infix(a_plus_b, "+", c.clone());
|
||||
let chain = Chain::try_new(&a_plus_b_plus_c).unwrap();
|
||||
expect_at(&chain.target, &a);
|
||||
expect_at(&chain.args[0].operand, &b);
|
||||
@ -560,7 +560,7 @@ mod tests {
|
||||
let b = Ast::var("b");
|
||||
let c = Ast::var("c");
|
||||
let b_comma_c = Ast::infix(b.clone(), ",", c.clone());
|
||||
let a_comma_b_comma_c = Ast::infix(a.clone(), ",", b_comma_c.clone());
|
||||
let a_comma_b_comma_c = Ast::infix(a.clone(), ",", b_comma_c);
|
||||
let chain = Chain::try_new(&a_comma_b_comma_c).unwrap();
|
||||
expect_at(&chain.target, &c);
|
||||
expect_at(&chain.args[0].operand, &b);
|
||||
|
@ -281,7 +281,7 @@ mod tests {
|
||||
}
|
||||
|
||||
{
|
||||
let mut chain = chain.clone();
|
||||
let mut chain = chain;
|
||||
chain.insert_arg(4, arg("arg"));
|
||||
assert_eq!(chain.repr(), "a b c _ _ arg");
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ mod test {
|
||||
{expected_metadata}"#
|
||||
);
|
||||
|
||||
assert_eq!(serialized.content, expected_content.to_string());
|
||||
assert_eq!(serialized.content, expected_content);
|
||||
assert_eq!(serialized.code_slice(), "main = 2 + 2");
|
||||
assert_eq!(serialized.id_map_slice(), expected_id_map.as_str());
|
||||
assert_eq!(serialized.metadata_slice(), expected_metadata.as_str());
|
||||
|
@ -80,7 +80,7 @@ pub fn flatten_prefix_test() {
|
||||
let case = |code: &str, expected_pieces: Vec<&str>| {
|
||||
let ast = parser.parse(code.into(), default()).unwrap();
|
||||
let ast = ast::test_utils::expect_single_line(&ast);
|
||||
let flattened = prefix::Chain::from_ast_non_strict(&ast);
|
||||
let flattened = prefix::Chain::from_ast_non_strict(ast);
|
||||
expect_pieces(&flattened, expected_pieces);
|
||||
assert_eq!(flattened.repr(), code);
|
||||
};
|
||||
@ -107,7 +107,7 @@ pub fn flatten_infix_test() {
|
||||
let case = |code: &str, target: &str, expected_pieces: Vec<&str>| {
|
||||
let ast = parser.parse(code.into(), default()).unwrap();
|
||||
let ast = ast::test_utils::expect_single_line(&ast);
|
||||
let flattened = opr::Chain::try_new(&ast).unwrap();
|
||||
let flattened = opr::Chain::try_new(ast).unwrap();
|
||||
expect_pieces(&flattened, target, expected_pieces);
|
||||
};
|
||||
|
||||
|
@ -82,7 +82,7 @@ impl Fixture {
|
||||
fn test_shape<T, F>(&mut self, program: &str, tester: F)
|
||||
where
|
||||
for<'t> &'t Shape<Ast>: TryInto<&'t T>,
|
||||
F: FnOnce(&T) -> (), {
|
||||
F: FnOnce(&T), {
|
||||
let ast = self.parser.parse_line_ast(program).unwrap();
|
||||
let shape = expect_shape(&ast);
|
||||
tester(shape);
|
||||
@ -203,7 +203,7 @@ impl Fixture {
|
||||
}
|
||||
|
||||
fn test_text_fmt_segment<F>(&mut self, program: &str, tester: F)
|
||||
where F: FnOnce(&SegmentFmt<Ast>) -> () {
|
||||
where F: FnOnce(&SegmentFmt<Ast>) {
|
||||
self.test_shape(program, |shape: &TextLineFmt<Ast>| {
|
||||
let (segment,) = (&shape.text).expect_tuple();
|
||||
tester(segment)
|
||||
@ -357,7 +357,7 @@ impl Fixture {
|
||||
assert_eq!(block.ty, BlockType::Continuous {});
|
||||
assert_eq!(block.indent, 1);
|
||||
assert_eq!(block.empty_lines.len(), 0);
|
||||
assert_eq!(block.is_orphan, true);
|
||||
assert!(block.is_orphan);
|
||||
|
||||
let first_line = &block.first_line;
|
||||
assert_eq!(first_line.off, 0);
|
||||
@ -501,7 +501,7 @@ fn nested_macros() {
|
||||
main =
|
||||
operator13 = Json.from_pairs [["a", 42], ["foo", [1,2,3]]]
|
||||
var1 = [operator13, operator13]"#;
|
||||
roundtrip_program_with(&parser, &program);
|
||||
roundtrip_program_with(&parser, program);
|
||||
|
||||
let program = r#"triplets n = 1.up_to n . to_vector . flat_map a->
|
||||
a+1 . up_to n . to_vector . flat_map b->
|
||||
@ -510,7 +510,7 @@ main =
|
||||
n = 10
|
||||
here.triplets n
|
||||
IO.println(here.triplets n)"#;
|
||||
roundtrip_program_with(&parser, &program);
|
||||
roundtrip_program_with(&parser, program);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
|
@ -257,9 +257,9 @@ mod test {
|
||||
let ast_id = ast.id;
|
||||
let tree = ast.generate_tree(&context::Empty).unwrap(): SpanTree;
|
||||
let node = tree.root_ref().find_by_span(&self.span.clone().into());
|
||||
let node = node.expect(
|
||||
format!("Invalid case {:?}: no node with span {:?}", self, self.span).as_str(),
|
||||
);
|
||||
let node = node.unwrap_or_else(|| {
|
||||
panic!("Invalid case {:?}: no node with span {:?}", self, self.span)
|
||||
});
|
||||
let arg = Ast::new(ast::Var { name: "foo".to_string() }, None);
|
||||
let result = match &self.action {
|
||||
Set => node.set(&ast, arg),
|
||||
@ -341,9 +341,9 @@ mod test {
|
||||
let ast = parser.parse_line_ast(self.expr).unwrap();
|
||||
let tree: SpanTree = ast.generate_tree(&context::Empty).unwrap();
|
||||
let node = tree.root_ref().find_by_span(&self.span.clone().into());
|
||||
let node = node.expect(
|
||||
format!("Invalid case {:?}: no node with span {:?}", self, self.span).as_str(),
|
||||
);
|
||||
let node = node.unwrap_or_else(|| {
|
||||
panic!("Invalid case {:?}: no node with span {:?}", self, self.span)
|
||||
});
|
||||
|
||||
let expected: HashSet<Action> = self.expected.iter().cloned().collect();
|
||||
for action in &[Set, Erase] {
|
||||
|
@ -1023,9 +1023,8 @@ mod test {
|
||||
// === Partial application chain - this argument ===
|
||||
|
||||
let ast = parser.parse_line_ast("here.foo").unwrap();
|
||||
let invocation_info = CalledMethodInfo {
|
||||
parameters: vec![this_param.clone(), param1.clone(), param2.clone()],
|
||||
};
|
||||
let invocation_info =
|
||||
CalledMethodInfo { parameters: vec![this_param, param1.clone(), param2.clone()] };
|
||||
let ctx = MockContext::new_single(ast.id.unwrap(), invocation_info);
|
||||
let mut tree = SpanTree::new(&ast, &ctx).unwrap(): SpanTree;
|
||||
match tree.root_ref().leaf_iter().collect_vec().as_slice() {
|
||||
@ -1056,9 +1055,9 @@ mod test {
|
||||
|
||||
fn segment_body_crumbs(
|
||||
index: usize,
|
||||
pattern_crumb: &Vec<PatternMatchCrumb>,
|
||||
pattern_crumb: &[PatternMatchCrumb],
|
||||
) -> ast::crumbs::MatchCrumb {
|
||||
let val = ast::crumbs::SegmentMatchCrumb::Body { val: pattern_crumb.clone() };
|
||||
let val = ast::crumbs::SegmentMatchCrumb::Body { val: pattern_crumb.to_vec() };
|
||||
ast::crumbs::MatchCrumb::Segs { val, index }
|
||||
}
|
||||
|
||||
|
@ -927,7 +927,7 @@ mod test {
|
||||
|
||||
for case in cases {
|
||||
let (crumbs, expected_crumbs, expected_remaining_ast_crumbs) = case;
|
||||
let result = root.clone().get_descendant_by_ast_crumbs(&crumbs).unwrap();
|
||||
let result = root.clone().get_descendant_by_ast_crumbs(crumbs).unwrap();
|
||||
assert_eq!(result.node.crumbs.as_slice(), *expected_crumbs);
|
||||
assert_eq!(result.ast_crumbs, expected_remaining_ast_crumbs.as_slice());
|
||||
}
|
||||
|
@ -1304,7 +1304,7 @@ pub mod test {
|
||||
let entry3 = model::suggestion_database::Entry {
|
||||
name: "testMethod1".to_string(),
|
||||
kind: Kind::Method,
|
||||
self_type: Some(module_name.clone().into()),
|
||||
self_type: Some(module_name.into()),
|
||||
scope: Scope::Everywhere,
|
||||
arguments: vec![
|
||||
Argument {
|
||||
@ -1796,7 +1796,7 @@ pub mod test {
|
||||
.use_suggestion(action::Suggestion::FromDatabase(f.entry1.clone()))
|
||||
.unwrap();
|
||||
let new_parsed_input =
|
||||
ParsedInput::new("var.testFunction1", &f.searcher.ide.parser());
|
||||
ParsedInput::new("var.testFunction1", f.searcher.ide.parser());
|
||||
f.searcher.data.borrow_mut().input = new_parsed_input.unwrap();
|
||||
}),
|
||||
// Variable name already present, need to use it. And not break it.
|
||||
|
@ -706,8 +706,8 @@ mod test {
|
||||
fn data_dir_attributes() -> FileAttributes {
|
||||
let dummy_time = UTCDateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00").unwrap();
|
||||
FileAttributes {
|
||||
creation_time: dummy_time.clone(),
|
||||
last_access_time: dummy_time.clone(),
|
||||
creation_time: dummy_time,
|
||||
last_access_time: dummy_time,
|
||||
last_modified_time: dummy_time,
|
||||
kind: FileSystemObject::Directory {
|
||||
name: DATA_DIR_NAME.to_owned(),
|
||||
|
@ -275,7 +275,7 @@ mod tests {
|
||||
vec![embedded_visualization, javascript_vis0, javascript_vis1];
|
||||
let zipped = visualizations.iter().zip(expected_visualizations.iter());
|
||||
for (visualization, expected_definition) in zipped {
|
||||
let loaded_definition = vis_controller.load_visualization(&visualization).await;
|
||||
let loaded_definition = vis_controller.load_visualization(visualization).await;
|
||||
let loaded_definition =
|
||||
loaded_definition.expect("Couldn't load visualization's content.");
|
||||
let loaded_signature = &loaded_definition.signature;
|
||||
|
@ -26,6 +26,41 @@ use crate::prelude::*;
|
||||
use futures::task::LocalSpawn;
|
||||
use futures::task::LocalSpawnExt;
|
||||
|
||||
/// Global spawner container. This structure is kept in the global variable `SPAWNER`. See module
|
||||
/// docs for details.
|
||||
struct GlobalSpawner {
|
||||
logger: Logger,
|
||||
spawner: RefCell<Option<Box<dyn LocalSpawn>>>,
|
||||
}
|
||||
|
||||
impl Default for GlobalSpawner {
|
||||
fn default() -> Self {
|
||||
Self { logger: Logger::new("GlobalSpawner"), spawner: default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl GlobalSpawner {
|
||||
fn set_spawner(&self, spawner_to_set: impl LocalSpawn + 'static) {
|
||||
info!(self.logger, "Setting new spawner");
|
||||
*self.spawner.borrow_mut() = Some(Box::new(spawner_to_set))
|
||||
}
|
||||
|
||||
fn spawn(&self, f: impl Future<Output = ()> + 'static) {
|
||||
// Note [Global Executor Safety]
|
||||
let mut borrowed = self.spawner.borrow_mut();
|
||||
if let Some(unwrapped) = borrowed.as_mut() {
|
||||
if unwrapped.spawn_local(f).is_err() {
|
||||
error!(
|
||||
self.logger,
|
||||
"Failed to spawn the task. Global executor might have been dropped."
|
||||
);
|
||||
}
|
||||
} else {
|
||||
error!(self.logger, "Fail to spawn the task. No global executor has been provided.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
/// Global spawner handle.
|
||||
///
|
||||
@ -34,7 +69,7 @@ thread_local! {
|
||||
///
|
||||
/// This is made thread local for tests which may be run in parallel; Each test should set
|
||||
/// executor independently.
|
||||
static SPAWNER: RefCell<Option<Box<dyn LocalSpawn>>> = default();
|
||||
static SPAWNER: GlobalSpawner = default();
|
||||
}
|
||||
|
||||
/// Sets the global spawner. It will remain accessible until it is set again to
|
||||
@ -44,21 +79,14 @@ thread_local! {
|
||||
/// time, so e.g. it must not drop the executor connected with this spawner.
|
||||
pub fn set_spawner(spawner_to_set: impl LocalSpawn + 'static) {
|
||||
// Note [Global Executor Safety]
|
||||
SPAWNER.with(|s| *s.borrow_mut() = Some(Box::new(spawner_to_set)));
|
||||
SPAWNER.with(|s| s.set_spawner(spawner_to_set));
|
||||
}
|
||||
|
||||
/// Spawns a task using the global spawner.
|
||||
/// Panics, if called when there is no global spawner set or if it fails to
|
||||
/// spawn task (e.g. because the connected executor was prematurely dropped).
|
||||
pub fn spawn(f: impl Future<Output = ()> + 'static) {
|
||||
SPAWNER.with(|spawner| {
|
||||
let error_msg = "No global executor has been provided.";
|
||||
// Note [Global Executor Safety]
|
||||
let mut borrowed = spawner.borrow_mut();
|
||||
let unwrapped = borrowed.as_mut().expect(error_msg);
|
||||
let error_msg = "Failed to spawn the task. Global executor might have been dropped.";
|
||||
unwrapped.spawn_local(f).expect(error_msg);
|
||||
});
|
||||
SPAWNER.with(|s| s.spawn(f));
|
||||
}
|
||||
/// Process stream elements while object under `weak` handle exists.
|
||||
///
|
||||
|
@ -10,7 +10,6 @@ use crate::presenter::Presenter;
|
||||
|
||||
use analytics::AnonymousData;
|
||||
use enso_frp as frp;
|
||||
use ensogl::application::Application;
|
||||
use ensogl::system::web::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
@ -36,26 +35,24 @@ const ALIVE_LOG_INTERVAL_SEC: u64 = 60;
|
||||
///
|
||||
/// This structure is a root of all objects in our application. It includes both layers:
|
||||
/// Controllers and Views, and an integration between them.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Debug)]
|
||||
pub struct Ide {
|
||||
application: Application,
|
||||
#[allow(dead_code)]
|
||||
/// The presenter layer is never directly accessed, but needs to be kept alive to keep
|
||||
/// performing its function.
|
||||
presenter: Presenter,
|
||||
network: frp::Network,
|
||||
pub ensogl_app: ensogl::application::Application,
|
||||
pub presenter: Presenter,
|
||||
network: frp::Network,
|
||||
}
|
||||
|
||||
impl Ide {
|
||||
/// Constructor.
|
||||
pub async fn new(
|
||||
application: Application,
|
||||
pub fn new(
|
||||
ensogl_app: ensogl::application::Application,
|
||||
view: ide_view::root::View,
|
||||
controller: controller::Ide,
|
||||
) -> Self {
|
||||
let presenter = Presenter::new(controller, view);
|
||||
let network = frp::Network::new("Ide");
|
||||
Ide { application, presenter, network }.init()
|
||||
Ide { ensogl_app, presenter, network }.init()
|
||||
}
|
||||
|
||||
fn init(self) -> Self {
|
||||
@ -65,7 +62,7 @@ impl Ide {
|
||||
|
||||
fn alive_log_sending_loop(&self) -> impl Future<Output = ()> + 'static {
|
||||
let network = &self.network;
|
||||
let scene = self.application.display.scene();
|
||||
let scene = self.ensogl_app.display.scene();
|
||||
let mouse = &scene.mouse.frp;
|
||||
let keyboard = &scene.keyboard.frp;
|
||||
|
||||
@ -90,6 +87,16 @@ impl Ide {
|
||||
}
|
||||
}
|
||||
|
||||
/// A reduced version of [`Ide`] structure, representing an application which failed to initialize.
|
||||
///
|
||||
/// It contains only the view displaying the error. No connection to the backend is maintained.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Debug)]
|
||||
pub struct FailedIde {
|
||||
pub view: ide_view::root::View,
|
||||
}
|
||||
|
||||
|
||||
/// The Path of the module initially opened after opening project in IDE.
|
||||
pub fn initial_module_path(project: &model::Project) -> FallibleResult<model::module::Path> {
|
||||
model::module::Path::from_name_segments(project.project_content_root_id(), &[
|
||||
|
@ -5,6 +5,7 @@ use crate::prelude::*;
|
||||
use crate::config;
|
||||
use crate::ide::Ide;
|
||||
use crate::transport::web::WebSocket;
|
||||
use crate::FailedIde;
|
||||
|
||||
use engine_protocol::project_manager;
|
||||
use engine_protocol::project_manager::ProjectName;
|
||||
@ -49,7 +50,6 @@ pub struct Initializer {
|
||||
logger: Logger,
|
||||
}
|
||||
|
||||
|
||||
impl Initializer {
|
||||
/// Create [`Initializer`] with given configuration.
|
||||
pub fn new(config: config::Startup) -> Self {
|
||||
@ -62,51 +62,52 @@ impl Initializer {
|
||||
pub fn start_and_forget(self) {
|
||||
let executor = setup_global_executor();
|
||||
executor::global::spawn(async move {
|
||||
info!(self.logger, "Starting IDE with the following config: {self.config:?}");
|
||||
|
||||
let application = Application::new(&web::get_html_element_by_id("root").unwrap());
|
||||
Initializer::register_views(&application);
|
||||
let view = application.new_view::<ide_view::root::View>();
|
||||
|
||||
// IDE was opened with `project` argument, we should skip the Welcome Screen.
|
||||
// We are doing it early, because Controllers initialization
|
||||
// takes some time and Welcome Screen might be visible for a brief moment while
|
||||
// controllers are not ready.
|
||||
if self.config.project_name.is_some() {
|
||||
view.switch_view_to_project();
|
||||
}
|
||||
|
||||
let status_bar = view.status_bar().clone_ref();
|
||||
application.display.add_child(&view);
|
||||
// TODO [mwu] Once IDE gets some well-defined mechanism of reporting
|
||||
// issues to user, such information should be properly passed
|
||||
// in case of setup failure.
|
||||
let result: FallibleResult<Ide> = (async {
|
||||
let controller = self.initialize_ide_controller().await?;
|
||||
Ok(Ide::new(application, view.clone_ref(), controller).await)
|
||||
})
|
||||
.await;
|
||||
|
||||
match result {
|
||||
Ok(ide) => {
|
||||
info!(self.logger, "Setup done.");
|
||||
std::mem::forget(ide);
|
||||
}
|
||||
Err(err) => {
|
||||
let message = iformat!("Failed to initialize application: {err}");
|
||||
error!(self.logger, "{message}");
|
||||
status_bar.add_event(ide_view::status_bar::event::Label::new(message));
|
||||
std::mem::forget(view);
|
||||
}
|
||||
}
|
||||
|
||||
let ide = self.start();
|
||||
web::get_element_by_id("loader")
|
||||
.map(|t| t.parent_node().map(|p| p.remove_child(&t).unwrap()))
|
||||
.ok();
|
||||
std::mem::forget(ide);
|
||||
});
|
||||
std::mem::forget(executor);
|
||||
}
|
||||
|
||||
/// Initialize all Ide objects and structures (executor, views, controllers, integration etc.)
|
||||
pub async fn start(self) -> Result<Ide, FailedIde> {
|
||||
info!(self.logger, "Starting IDE with the following config: {self.config:?}");
|
||||
|
||||
let root_element = web::get_html_element_by_id("root").unwrap();
|
||||
let ensogl_app = ensogl::application::Application::new(&root_element);
|
||||
Initializer::register_views(&ensogl_app);
|
||||
let view = ensogl_app.new_view::<ide_view::root::View>();
|
||||
|
||||
// IDE was opened with `project` argument, we should skip the Welcome Screen.
|
||||
// We are doing it early, because Controllers initialization
|
||||
// takes some time and Welcome Screen might be visible for a brief moment while
|
||||
// controllers are not ready.
|
||||
if self.config.project_name.is_some() {
|
||||
view.switch_view_to_project();
|
||||
}
|
||||
|
||||
let status_bar = view.status_bar().clone_ref();
|
||||
ensogl_app.display.add_child(&view);
|
||||
// TODO [mwu] Once IDE gets some well-defined mechanism of reporting
|
||||
// issues to user, such information should be properly passed
|
||||
// in case of setup failure.
|
||||
match self.initialize_ide_controller().await {
|
||||
Ok(controller) => {
|
||||
let ide = Ide::new(ensogl_app, view.clone_ref(), controller);
|
||||
info!(self.logger, "Setup done.");
|
||||
Ok(ide)
|
||||
}
|
||||
Err(error) => {
|
||||
let message = format!("Failed to initialize application: {error}");
|
||||
error!(self.logger, "{message}");
|
||||
status_bar.add_event(ide_view::status_bar::event::Label::new(message));
|
||||
Err(FailedIde { view })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn register_views(app: &Application) {
|
||||
app.views.register::<ide_view::root::View>();
|
||||
app.views.register::<ide_view::graph_editor::GraphEditor>();
|
||||
|
@ -340,7 +340,7 @@ pub mod test {
|
||||
data: &MockData,
|
||||
ls: &mut language_server::MockClient,
|
||||
) {
|
||||
Self::mock_create_destroy_calls(&data, ls);
|
||||
Self::mock_create_destroy_calls(data, ls);
|
||||
let id = data.context_id;
|
||||
let root_frame = language_server::ExplicitCall {
|
||||
method_pointer: data.main_method_pointer(),
|
||||
|
@ -587,6 +587,9 @@ pub trait API: Debug + model::undo_redo::Aware {
|
||||
fn info(&self) -> double_representation::module::Info {
|
||||
double_representation::module::Info::from(self.ast())
|
||||
}
|
||||
|
||||
/// Returns self as any. Used for casting down the [`Module`] object.
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
}
|
||||
|
||||
/// Trait for methods that cannot be defined in `API` because it is a trait object.
|
||||
@ -620,6 +623,7 @@ pub type Plain = plain::Module;
|
||||
pub type Synchronized = synchronized::Module;
|
||||
|
||||
|
||||
|
||||
// ============
|
||||
// === Test ===
|
||||
// ============
|
||||
|
@ -214,6 +214,10 @@ impl model::module::API for Module {
|
||||
content.metadata.ide.project = Some(data);
|
||||
})
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl model::undo_redo::Aware for Module {
|
||||
@ -286,13 +290,13 @@ mod test {
|
||||
// Metadata update
|
||||
let id = Uuid::new_v4();
|
||||
let node_metadata = NodeMetadata { position: Some(Position::new(1.0, 2.0)), ..default() };
|
||||
module.set_node_metadata(id.clone(), node_metadata.clone()).unwrap();
|
||||
module.set_node_metadata(id, node_metadata.clone()).unwrap();
|
||||
expect_notification(NotificationKind::MetadataChanged);
|
||||
|
||||
module.remove_node_metadata(id.clone()).unwrap();
|
||||
module.remove_node_metadata(id).unwrap();
|
||||
expect_notification(NotificationKind::MetadataChanged);
|
||||
|
||||
module.with_node_metadata(id.clone(), Box::new(|md| *md = node_metadata.clone())).unwrap();
|
||||
module.with_node_metadata(id, Box::new(|md| *md = node_metadata.clone())).unwrap();
|
||||
expect_notification(NotificationKind::MetadataChanged);
|
||||
|
||||
// Whole update
|
||||
@ -312,17 +316,17 @@ mod test {
|
||||
let module = model::module::test::plain_from_code("");
|
||||
|
||||
let id = Uuid::new_v4();
|
||||
let initial_md = module.node_metadata(id.clone());
|
||||
let initial_md = module.node_metadata(id);
|
||||
assert!(initial_md.is_err());
|
||||
|
||||
let md_to_set = NodeMetadata { position: Some(Position::new(1.0, 2.0)), ..default() };
|
||||
module.set_node_metadata(id.clone(), md_to_set.clone()).unwrap();
|
||||
assert_eq!(md_to_set.position, module.node_metadata(id.clone()).unwrap().position);
|
||||
module.set_node_metadata(id, md_to_set.clone()).unwrap();
|
||||
assert_eq!(md_to_set.position, module.node_metadata(id).unwrap().position);
|
||||
|
||||
let new_pos = Position::new(4.0, 5.0);
|
||||
module
|
||||
.with_node_metadata(
|
||||
id.clone(),
|
||||
id,
|
||||
Box::new(|md| {
|
||||
assert_eq!(md_to_set.position, md.position);
|
||||
md.position = Some(new_pos);
|
||||
|
@ -250,6 +250,10 @@ impl API for Module {
|
||||
) -> FallibleResult {
|
||||
self.model.boxed_update_project_metadata(fun)
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -538,7 +542,7 @@ pub mod test {
|
||||
client.expect.apply_text_file_edit(move |edits| {
|
||||
let content_so_far = this.current_ls_content.get();
|
||||
let result = f(edits);
|
||||
let new_content = apply_edits(content_so_far, &edits);
|
||||
let new_content = apply_edits(content_so_far, edits);
|
||||
let actual_old = this.current_ls_version.get();
|
||||
let actual_new =
|
||||
Sha3_224::from_parts(new_content.iter_chunks(..).map(|s| s.as_bytes()));
|
||||
|
@ -752,7 +752,11 @@ mod test {
|
||||
|
||||
assert_eq!(path, *module.path());
|
||||
assert_eq!(another_path, *another_module.path());
|
||||
assert!(Rc::ptr_eq(&module, &same_module));
|
||||
// We have to downcast module, otherwise we would compare vtable pointers. See
|
||||
// https://rust-lang.github.io/rust-clippy/master/index.html#vtable_address_comparisons
|
||||
let module = module.as_any().downcast_ref::<module::Synchronized>().unwrap();
|
||||
let same_module = same_module.as_any().downcast_ref::<module::Synchronized>().unwrap();
|
||||
assert!(std::ptr::eq(module, same_module));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ impl Model {
|
||||
*self.current_project.borrow_mut() = None;
|
||||
|
||||
if let Some(project_model) = self.controller.current_project() {
|
||||
self.view.switch_view_to_project();
|
||||
// We know the name of new project before it loads. We set it right now to avoid
|
||||
// displaying placeholder on the scene during loading.
|
||||
let project_view = self.view.project();
|
||||
@ -228,3 +229,17 @@ impl Presenter {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === Getters ===
|
||||
|
||||
#[allow(missing_docs)]
|
||||
impl Presenter {
|
||||
pub fn view(&self) -> &view::root::View {
|
||||
&self.model.view
|
||||
}
|
||||
|
||||
pub fn controller(&self) -> &controller::Ide {
|
||||
&self.model.controller
|
||||
}
|
||||
}
|
||||
|
@ -777,33 +777,33 @@ mod tests {
|
||||
let ast_con2 = AstConnection { source: src.clone(), destination: dest2.clone() };
|
||||
let view_con1 = ensogl::display::object::Id::from(1).into();
|
||||
let view_con2 = ensogl::display::object::Id::from(2).into();
|
||||
let view_src = EdgeEndpoint { node_id: nodes[0].view, port: src.port.clone() };
|
||||
let view_tgt1 = EdgeEndpoint { node_id: nodes[1].view, port: dest1.port.clone() };
|
||||
let view_tgt2 = EdgeEndpoint { node_id: nodes[1].view, port: dest2.port.clone() };
|
||||
let view_src = EdgeEndpoint { node_id: nodes[0].view, port: src.port };
|
||||
let view_tgt1 = EdgeEndpoint { node_id: nodes[1].view, port: dest1.port };
|
||||
let view_tgt2 = EdgeEndpoint { node_id: nodes[1].view, port: dest2.port };
|
||||
let view_pair1 = (view_src.clone(), view_tgt1.clone());
|
||||
|
||||
let from_controller = state.update_from_controller();
|
||||
let from_view = state.update_from_view();
|
||||
|
||||
assert_eq!(from_controller.set_connection(ast_con1.clone()), Some(view_pair1.clone()));
|
||||
assert_eq!(from_controller.set_connection(ast_con1.clone()), Some(view_pair1));
|
||||
|
||||
assert_eq!(
|
||||
from_view.create_connection_from_endpoints(view_con1, view_src.clone(), view_tgt1),
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
from_view.create_connection_from_endpoints(view_con2, view_src.clone(), view_tgt2),
|
||||
from_view.create_connection_from_endpoints(view_con2, view_src, view_tgt2),
|
||||
Some(ast_con2.clone())
|
||||
);
|
||||
|
||||
let all_connections = [ast_con1.clone(), ast_con2.clone()].into_iter().collect();
|
||||
let all_connections = [ast_con1, ast_con2.clone()].into_iter().collect();
|
||||
assert_eq!(from_controller.retain_connections(&all_connections), vec![]);
|
||||
assert_eq!(
|
||||
from_controller.retain_connections(&[ast_con2.clone()].into_iter().collect()),
|
||||
vec![view_con1]
|
||||
);
|
||||
|
||||
assert_eq!(from_view.remove_connection(view_con2), Some(ast_con2.clone()));
|
||||
assert_eq!(from_view.remove_connection(view_con2), Some(ast_con2));
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
|
@ -615,7 +615,7 @@ mod tests {
|
||||
ready(Ok(faux_vis.clone())).boxed_local()
|
||||
});
|
||||
|
||||
let sender = request_sender.clone();
|
||||
let sender = request_sender;
|
||||
execution_context.expect_modify_visualization().returning_st(
|
||||
move |id, expression, module| {
|
||||
let request = ExecutionContextRequest::Modify { id, expression, module };
|
||||
@ -644,7 +644,7 @@ mod tests {
|
||||
) -> bool {
|
||||
let PreprocessorConfiguration { module, code } = &metadata.preprocessor;
|
||||
visualization.preprocessor_code == code.to_string()
|
||||
&& visualization.context_module == manager.resolve_context_module(&module).unwrap()
|
||||
&& visualization.context_module == manager.resolve_context_module(module).unwrap()
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
@ -678,7 +678,7 @@ mod tests {
|
||||
// Multiple detach-attach requests are collapsed into a single modify request.
|
||||
requests.expect_pending();
|
||||
manager.remove_visualization(node_id);
|
||||
manager.request_visualization(node_id, desired_vis_2.clone());
|
||||
manager.request_visualization(node_id, desired_vis_2);
|
||||
manager.remove_visualization(node_id);
|
||||
manager.remove_visualization(node_id);
|
||||
manager.request_visualization(node_id, desired_vis_1.clone());
|
||||
@ -701,7 +701,7 @@ mod tests {
|
||||
let desired_vis_3 = Desired {
|
||||
visualization_id: VisualizationId::from_u128(900),
|
||||
expression_id: node_id,
|
||||
metadata: desired_vis_1.clone(),
|
||||
metadata: desired_vis_1,
|
||||
};
|
||||
let visualization_so_far = manager.get_cloned(node_id).unwrap().status.get_cloned();
|
||||
manager.write_new_desired(node_id, Some(desired_vis_3.clone()));
|
||||
|
@ -114,14 +114,14 @@ mod tests {
|
||||
let mut fixture = TestWithLocalPoolExecutor::set_up();
|
||||
|
||||
let flag = Synchronized::new(false);
|
||||
assert_eq!(*flag.borrow(), false);
|
||||
assert!(!*flag.borrow());
|
||||
|
||||
// If condition was already met, be immediately ready.
|
||||
let mut on_false = flag.when(|f| *f == false).boxed_local();
|
||||
let mut on_false = flag.when(|&f| !f).boxed_local();
|
||||
assert_eq!(on_false.expect_ready(), Some(()));
|
||||
|
||||
// Otherwise not ready.
|
||||
let mut on_true = flag.when(|f| *f == true).boxed_local();
|
||||
let mut on_true = flag.when(|&f| f).boxed_local();
|
||||
on_true.expect_pending();
|
||||
|
||||
// Faux no-op change. Should not spawn a new task.
|
||||
@ -135,7 +135,7 @@ mod tests {
|
||||
assert_eq!(on_true.expect_ready(), Some(()));
|
||||
|
||||
// After dropping the flag, pending future should complete with None.
|
||||
let mut on_false = flag.when(|f| *f == false).boxed_local();
|
||||
let mut on_false = flag.when(|&f| !f).boxed_local();
|
||||
on_false.expect_pending();
|
||||
drop(flag);
|
||||
assert_eq!(on_false.expect_ready(), None);
|
||||
|
@ -388,7 +388,7 @@ pub mod mock {
|
||||
pub fn synchronized_module(&self) -> Rc<model::module::Synchronized> {
|
||||
let parser = self.data.parser.clone();
|
||||
let path = self.data.module_path.clone();
|
||||
let ls = self.project.json_rpc().clone();
|
||||
let ls = self.project.json_rpc();
|
||||
let repository = self.project.urm().repository.clone_ref();
|
||||
let module_future = model::module::Synchronized::open(path, ls, parser, repository);
|
||||
// We can `expect_ready`, because in fact this is synchronous in test conditions.
|
||||
|
@ -188,7 +188,7 @@ async fn ls_text_protocol_test() {
|
||||
client.delete_file(&move_path).await.expect("Couldn't delete file");
|
||||
let file = client.file_exists(&move_path).await;
|
||||
let file = file.expect("Couldn't check if file exists.");
|
||||
assert_eq!(file.exists, false);
|
||||
assert!(!file.exists);
|
||||
}
|
||||
|
||||
client.move_file(&new_path, &move_path).await.expect("Couldn't move file");
|
||||
@ -248,7 +248,7 @@ async fn file_events() {
|
||||
client.delete_file(&path).await.expect("Couldn't delete file");
|
||||
let file = client.file_exists(&path).await;
|
||||
let file = file.expect("Couldn't check if file exists.");
|
||||
assert_eq!(file.exists, false);
|
||||
assert!(!file.exists);
|
||||
}
|
||||
|
||||
let path = Path { root_id, segments: vec![] };
|
||||
|
@ -13,7 +13,7 @@ enso-config = { path = "../config" }
|
||||
enso-frp = { path = "../../../lib/rust/frp" }
|
||||
enso-logger = { path = "../../../lib/rust/logger"}
|
||||
enso-prelude = { path = "../../../lib/rust/prelude"}
|
||||
enso-shapely = { path = "../../../lib/rust/shapely/impl"}
|
||||
enso-shapely = { path = "../../../lib/rust/shapely"}
|
||||
engine-protocol = { path = "../controller/engine-protocol" }
|
||||
ensogl = { path = "../../../lib/rust/ensogl" }
|
||||
ensogl-component = { path = "../../../lib/rust/ensogl/component" }
|
||||
|
@ -17,7 +17,7 @@ enso-frp = { version = "0.1.0", path = "../../../../lib/rust/frp" }
|
||||
enso-logger = { path = "../../../../lib/rust/logger"}
|
||||
enso-prelude = { path = "../../../../lib/rust/prelude"}
|
||||
engine-protocol = { version = "0.1.0", path = "../../controller/engine-protocol" }
|
||||
enso-shapely = { path = "../../../../lib/rust/shapely/impl"}
|
||||
enso-shapely = { path = "../../../../lib/rust/shapely"}
|
||||
enso-text = { version = "0.1.0", path = "../../../../lib/rust/text" }
|
||||
ensogl = { version = "0.1.0", path = "../../../../lib/rust/ensogl" }
|
||||
ensogl-component = { path = "../../../../lib/rust/ensogl/component" }
|
||||
|
@ -465,6 +465,10 @@ impl Area {
|
||||
pub fn get_crumbs_by_id(&self, id: ast::Id) -> Option<Crumbs> {
|
||||
self.model.id_crumbs_map.borrow().get(&id).cloned()
|
||||
}
|
||||
|
||||
pub fn label(&self) -> &text::Area {
|
||||
&self.model.label
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -339,6 +339,14 @@ where
|
||||
}
|
||||
|
||||
impl<K, V, S> SharedHashMap<K, V, S> {
|
||||
pub fn len(&self) -> usize {
|
||||
self.raw.borrow().len()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.raw.borrow().is_empty()
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
self.raw.borrow_mut().clear()
|
||||
}
|
||||
|
48
build/run.js
48
build/run.js
@ -74,16 +74,16 @@ async function build_project_manager() {
|
||||
}
|
||||
|
||||
/// Run the local project manager binary.
|
||||
function run_project_manager() {
|
||||
function run_project_manager(options = {}) {
|
||||
const bin_path = paths.get_project_manager_path(paths.dist.bin)
|
||||
console.log(`Starting the project manager from "${bin_path}".`)
|
||||
child_process.execFile(bin_path, [], (error, stdout, stderr) => {
|
||||
return child_process.execFile(bin_path, [], options, (error, stdout, stderr) => {
|
||||
console.log(`Project manager finished.`)
|
||||
console.error(stderr)
|
||||
if (error) {
|
||||
if (error && !error.killed) {
|
||||
throw error
|
||||
}
|
||||
console.log(stdout)
|
||||
console.log(`Project manager running.`)
|
||||
})
|
||||
}
|
||||
|
||||
@ -115,7 +115,13 @@ commands.clean.rust = async function () {
|
||||
|
||||
commands.check = command(`Fast check if project builds (only Rust target)`)
|
||||
commands.check.rust = async function () {
|
||||
await run_cargo('cargo', ['check'])
|
||||
await run_cargo('cargo', [
|
||||
'check',
|
||||
'--workspace',
|
||||
' -p',
|
||||
'enso-integration-test',
|
||||
'--all-targets',
|
||||
])
|
||||
}
|
||||
|
||||
// === Build ===
|
||||
@ -248,11 +254,41 @@ commands.test.rust = async function (argv) {
|
||||
}
|
||||
}
|
||||
|
||||
// === Integration Test ===
|
||||
|
||||
commands['integration-test'] = command('Run integration test suite')
|
||||
commands['integration-test'].rust = async function (argv) {
|
||||
let pm_process = null
|
||||
if (argv.backend !== 'false') {
|
||||
let env = { ...process.env, PROJECTS_ROOT: path.resolve(os.tmpdir(), 'enso') }
|
||||
pm_process = await build_project_manager().then(() => run_project_manager({ env: env }))
|
||||
}
|
||||
try {
|
||||
console.log(`Running Rust WASM test suite.`)
|
||||
let args = ['test', '--chrome', 'integration-test', '--profile=integration-test']
|
||||
await run_cargo('wasm-pack', args)
|
||||
} finally {
|
||||
console.log(`Shutting down Project Manager`)
|
||||
if (pm_process !== null) {
|
||||
pm_process.kill()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// === Lint ===
|
||||
|
||||
commands.lint = command(`Lint the codebase`)
|
||||
commands.lint.rust = async function () {
|
||||
await run_cargo('cargo', ['clippy', '--', '-D', 'warnings'])
|
||||
await run_cargo('cargo', [
|
||||
'clippy',
|
||||
'--workspace',
|
||||
'-p',
|
||||
'enso-integration-test',
|
||||
'--all-targets',
|
||||
'--',
|
||||
'-D',
|
||||
'warnings',
|
||||
])
|
||||
await run_cargo('cargo', ['fmt', '--', '--check'])
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// List of workspace members that, despite having should not be tested by wasm-pack test.
|
||||
const PACKAGE_BLACKLIST: [&str; 0] = [];
|
||||
/// List of crates that should not be tested by wasm-pack test.
|
||||
const PACKAGE_BLACKLIST: [&str; 1] = ["integration-test"];
|
||||
|
||||
/// Attributes that denote WASM tests.
|
||||
const WASM_TEST_ATTRIBUTES: [&str; 2] = ["#[wasm_bindgen_test]", "#[wasm_bindgen_test(async)]"];
|
||||
@ -13,17 +13,44 @@ const WASM_TEST_ATTRIBUTES: [&str; 2] = ["#[wasm_bindgen_test]", "#[wasm_bindgen
|
||||
const SOURCE_SUBDIRECTORIES: [&str; 4] = ["src", "benches", "examples", "tests"];
|
||||
|
||||
/// Lists members of given Cargo.toml workspace.
|
||||
fn get_workspace_members(cargo_toml_root: toml::Value) -> Vec<String> {
|
||||
let workspace = cargo_toml_root.get("workspace").expect("not a workspace");
|
||||
match &workspace["members"] {
|
||||
toml::Value::Array(list) => list
|
||||
.iter()
|
||||
.map(|val| match val {
|
||||
toml::Value::String(s) => s.clone(),
|
||||
_ => panic!("Workspace member is not a string"),
|
||||
})
|
||||
.collect(),
|
||||
_ => panic!("Invalid workspace element"),
|
||||
fn get_all_crates() -> Vec<PathBuf> {
|
||||
let all_paths = glob::glob("./**/Cargo.toml").expect("Searching for crates failed");
|
||||
let valid_paths = all_paths.filter_map(|path| match path {
|
||||
Ok(path) => Some(path.parent().unwrap().to_owned()),
|
||||
Err(err) => {
|
||||
println!("cargo:warning={}", err);
|
||||
None
|
||||
}
|
||||
});
|
||||
valid_paths.collect()
|
||||
}
|
||||
|
||||
/// Check if the given line of source code is an attribute denoting wasm test.
|
||||
fn is_wasm_test_attribute(line: &str) -> bool {
|
||||
WASM_TEST_ATTRIBUTES.contains(&line.trim())
|
||||
}
|
||||
|
||||
/// Check if the given workspace member contains any wasm tests in the sources.
|
||||
fn has_wasm_tests(member: &Path) -> bool {
|
||||
if let Some(member) = member.to_str() {
|
||||
// We go over selected subdirectories only to avoid entering into sources of other crates
|
||||
// that are nested within this crate subtree.
|
||||
for subdir in SOURCE_SUBDIRECTORIES {
|
||||
let pattern = format!("{}/{}/**/*.rs", member, subdir);
|
||||
for entry in glob::glob(&pattern).unwrap() {
|
||||
let contents = std::fs::read_to_string(entry.unwrap()).unwrap();
|
||||
if contents.lines().any(is_wasm_test_attribute) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
} else {
|
||||
println!(
|
||||
"cargo:warning=Skipping the crate {} containing non-UTF-8 characters in its path. ",
|
||||
member.to_string_lossy()
|
||||
);
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,35 +61,14 @@ fn parse_toml(path: impl AsRef<Path>) -> toml::Value {
|
||||
data.parse().unwrap()
|
||||
}
|
||||
|
||||
/// Check if the given line of source code is an attribute denoting wasm test.
|
||||
fn is_wasm_test_attribute(line: &str) -> bool {
|
||||
WASM_TEST_ATTRIBUTES.contains(&line.trim())
|
||||
}
|
||||
|
||||
/// Check if the given workspace member contains any wasm tests in the sources.
|
||||
fn has_wasm_tests(member: &str) -> bool {
|
||||
// We go over selected subdirectories only to avoid entering into sources of other crates that
|
||||
// are nested within this crate subtree.
|
||||
for subdir in SOURCE_SUBDIRECTORIES {
|
||||
let pattern = format!("{}/{}/**/*.rs", member, subdir);
|
||||
for entry in glob::glob(&pattern).unwrap() {
|
||||
let contents = std::fs::read_to_string(entry.unwrap()).unwrap();
|
||||
if contents.lines().any(is_wasm_test_attribute) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Checks if the given member is blacklisted from running the tests.
|
||||
fn blacklisted(memeber: &str) -> bool {
|
||||
PACKAGE_BLACKLIST.contains(&memeber)
|
||||
fn blacklisted(memeber: &Path) -> bool {
|
||||
PACKAGE_BLACKLIST.contains(&memeber.to_string_lossy().as_ref())
|
||||
}
|
||||
|
||||
/// Checks if given workspace member is a proc-macro crate.
|
||||
fn is_proc_macro_crate(member: &str) -> bool {
|
||||
let cargo_toml_path = PathBuf::from(member).join("Cargo.toml");
|
||||
fn is_proc_macro_crate(member: &Path) -> bool {
|
||||
let cargo_toml_path = member.join("Cargo.toml");
|
||||
let cargo_toml_root = parse_toml(cargo_toml_path);
|
||||
get_proc_macro(cargo_toml_root).contains(&true)
|
||||
}
|
||||
@ -78,28 +84,28 @@ fn get_proc_macro(cargo_toml: toml::Value) -> Option<bool> {
|
||||
/// `wasm-pack test` each member. All script arguments are passed to `wasm-pack` process.
|
||||
fn main() {
|
||||
let wasm_pack_args = std::env::args().skip(1).collect::<Vec<_>>();
|
||||
let cargo_toml_root = parse_toml("Cargo.toml");
|
||||
let all_members = get_workspace_members(cargo_toml_root);
|
||||
let all_members = get_all_crates();
|
||||
|
||||
for member in all_members {
|
||||
let member_str = member.to_string_lossy();
|
||||
if blacklisted(&member) {
|
||||
println!("Skipping blacklisted crate {}", member);
|
||||
println!("Skipping blacklisted crate {}", member_str);
|
||||
} else if is_proc_macro_crate(&member) {
|
||||
println!("Skipping proc-macro crate {}", member);
|
||||
println!("Skipping proc-macro crate {}", member_str);
|
||||
} else if has_wasm_tests(&member) {
|
||||
println!("Running tests for {}", member);
|
||||
println!("Running tests for {}", member_str);
|
||||
let mut command = std::process::Command::new("wasm-pack");
|
||||
command.arg("test").args(&wasm_pack_args).arg(&member);
|
||||
println!("{:?}", command);
|
||||
let status = command.status().unwrap();
|
||||
if !status.success() {
|
||||
panic!("Process for {} failed!{}", member, match status.code() {
|
||||
panic!("Process for {} failed!{}", member_str, match status.code() {
|
||||
Some(code) => format!(" Code: {}", code),
|
||||
None => String::new(),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
println!("No wasm tests in {}", member);
|
||||
println!("No wasm tests in {}", member_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
integration-test/Cargo.toml
Normal file
15
integration-test/Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "enso-integration-test"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ensogl = { path = "../lib/rust/ensogl" }
|
||||
enso-frp = { path = "../lib/rust/frp" }
|
||||
enso-prelude = { path = "../lib/rust/prelude" }
|
||||
enso-gui = { path = "../app/gui" }
|
||||
enso-web = { path = "../lib/rust/web" }
|
||||
wasm-bindgen = { version = "=0.2.58" }
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.3.8"
|
65
integration-test/src/lib.rs
Normal file
65
integration-test/src/lib.rs
Normal file
@ -0,0 +1,65 @@
|
||||
//! Enso Integration Tests
|
||||
//!
|
||||
//! This crate contains all integration tests of Enso applications: the IDE and the backend
|
||||
//! (engine). All of those are placed in `tests` directory. The sources (`src`) contain only
|
||||
//! fixtures and helpers.
|
||||
//!
|
||||
//! These tests require the Project Manager for working.
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![warn(trivial_casts)]
|
||||
#![warn(trivial_numeric_casts)]
|
||||
#![warn(unused_import_braces)]
|
||||
#![warn(unused_qualifications)]
|
||||
#![warn(unsafe_code)]
|
||||
#![warn(missing_copy_implementations)]
|
||||
#![warn(missing_debug_implementations)]
|
||||
|
||||
pub use enso_prelude as prelude;
|
||||
|
||||
use enso_prelude::*;
|
||||
|
||||
use enso_gui::executor::web::EventLoopExecutor;
|
||||
use enso_gui::initializer::setup_global_executor;
|
||||
use enso_gui::Ide;
|
||||
use enso_web::HtmlDivElement;
|
||||
use enso_web::NodeInserter;
|
||||
use enso_web::StyleSetter;
|
||||
|
||||
|
||||
|
||||
// =======================
|
||||
// === IntegrationTest ===
|
||||
// =======================
|
||||
|
||||
/// A fixture for each IDE integration tests. During setup, the executor and [`Ide`] structure are
|
||||
/// initialized.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Debug)]
|
||||
pub struct IntegrationTest {
|
||||
pub executor: EventLoopExecutor,
|
||||
pub ide: Ide,
|
||||
pub root_div: HtmlDivElement,
|
||||
}
|
||||
|
||||
impl IntegrationTest {
|
||||
/// Initializes the executor and `Ide` structure and returns new Fixture
|
||||
pub async fn setup() -> Self {
|
||||
enso_web::forward_panic_hook_to_error();
|
||||
let executor = setup_global_executor();
|
||||
let root_div = enso_web::create_div();
|
||||
root_div.set_id("root");
|
||||
root_div.set_style_or_panic("display", "none");
|
||||
enso_web::body().append_or_panic(&root_div);
|
||||
|
||||
let initializer = enso_gui::ide::Initializer::new(default());
|
||||
let ide = initializer.start().await.expect("Failed to initialize the application.");
|
||||
Self { executor, ide, root_div }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for IntegrationTest {
|
||||
fn drop(&mut self) {
|
||||
self.root_div.remove();
|
||||
}
|
||||
}
|
31
integration-test/tests/graph_editor.rs
Normal file
31
integration-test/tests/graph_editor.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use enso_frp::future::EventOutputExt;
|
||||
use enso_integration_test::IntegrationTest;
|
||||
use wasm_bindgen_test::wasm_bindgen_test;
|
||||
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn create_new_project_and_add_nodes() {
|
||||
let test = IntegrationTest::setup().await;
|
||||
let ide = &test.ide;
|
||||
let project = ide.presenter.view().project();
|
||||
let graph_editor = project.graph();
|
||||
let controller = ide.presenter.controller();
|
||||
let project_management =
|
||||
controller.manage_projects().expect("Cannot access Managing Project API");
|
||||
|
||||
let expect_prompt = project.show_prompt.next_event();
|
||||
project_management.create_new_project(None).await.expect("Failed to create new project");
|
||||
expect_prompt.await;
|
||||
|
||||
assert_eq!(graph_editor.model.nodes.all.len(), 2);
|
||||
let expect_node_added = graph_editor.node_added.next_event();
|
||||
graph_editor.add_node();
|
||||
let added_node_id = expect_node_added.expect();
|
||||
assert_eq!(graph_editor.model.nodes.all.len(), 3);
|
||||
|
||||
let added_node =
|
||||
graph_editor.model.nodes.get_cloned_ref(&added_node_id).expect("Added node is not added");
|
||||
assert_eq!(added_node.view.expression.value().to_string(), "");
|
||||
}
|
5
integration-test/webdriver.json
Normal file
5
integration-test/webdriver.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"goog:chromeOptions": {
|
||||
"args": ["--no-proxy-server", "--no-sandbox"]
|
||||
}
|
||||
}
|
@ -88,9 +88,7 @@ fn map_in_place(c: &mut Criterion) {
|
||||
c.bench_function("Map in Place", |b| {
|
||||
b.iter(|| {
|
||||
let mut tree = tree.clone();
|
||||
black_box(
|
||||
tree.iter_mut().for_each(black_box(|(_, v): (Vec<&usize>, &mut usize)| *v *= 2)),
|
||||
);
|
||||
tree.iter_mut().for_each(black_box(|(_, v): (Vec<&usize>, &mut usize)| *v *= 2));
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -653,7 +653,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
impl FromSorted<((usize, usize), (usize, usize), (usize, usize), (usize, usize))> for Tree4 {
|
||||
fn from_sorted(
|
||||
t: ((usize, usize), (usize, usize), (usize, usize), (usize, usize)),
|
||||
|
@ -265,20 +265,20 @@ mod tests {
|
||||
|
||||
|
||||
// Default is false.
|
||||
assert_eq!(is_dragged.value(), false);
|
||||
assert!(!is_dragged.value());
|
||||
|
||||
// Mouse down over shape activates dragging.
|
||||
shape.mouse_over.emit(());
|
||||
mouse.down.emit(Button::from_code(0));
|
||||
assert_eq!(is_dragged.value(), true);
|
||||
assert!(is_dragged.value());
|
||||
|
||||
// Release mouse stops dragging.
|
||||
mouse.up.emit(Button::from_code(0));
|
||||
assert_eq!(is_dragged.value(), false);
|
||||
assert!(!is_dragged.value());
|
||||
|
||||
// Mouse down while not over shape does not activate dragging.
|
||||
shape.mouse_out.emit(());
|
||||
mouse.down.emit(Button::from_code(0));
|
||||
assert_eq!(is_dragged.value(), false);
|
||||
assert!(!is_dragged.value());
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ crate-type = ["rlib", "cdylib"]
|
||||
[dependencies]
|
||||
enso-frp = { path = "../../../frp" }
|
||||
enso-prelude = { path = "../../../prelude"}
|
||||
enso-shapely = { path = "../../../shapely/impl"}
|
||||
enso-shapely = { path = "../../../shapely"}
|
||||
enso-text = { path = "../../../text" }
|
||||
enso-types = { path = "../../../types" }
|
||||
ensogl-core = { path = "../../core" }
|
||||
|
@ -348,8 +348,8 @@ mod tests {
|
||||
const TEST_FONT_NAME: &str = "DejaVuSansMono-Bold";
|
||||
|
||||
fn create_test_font() -> Font {
|
||||
let mut embedded_fonts = EmbeddedFonts::create_and_fill();
|
||||
Font::try_from_embedded(&mut embedded_fonts, TEST_FONT_NAME).unwrap()
|
||||
let embedded_fonts = EmbeddedFonts::create_and_fill();
|
||||
Font::try_from_embedded(&embedded_fonts, TEST_FONT_NAME).unwrap()
|
||||
}
|
||||
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
@ -21,7 +21,7 @@ enso-generics = { path = "../../generics"}
|
||||
enso-logger = { path = "../../logger"}
|
||||
enso-optics = { path = "../../optics"}
|
||||
enso-prelude = { path = "../../prelude"}
|
||||
enso-shapely = { path = "../../shapely/impl"}
|
||||
enso-shapely = { path = "../../shapely"}
|
||||
enso-shortcuts = { path = "../../shortcuts" }
|
||||
enso-types = { path = "../../types" }
|
||||
enso-web = { path = "../../web" }
|
||||
|
@ -1505,20 +1505,20 @@ mod tests {
|
||||
node4.add_child(&node5);
|
||||
node5.add_child(&node6);
|
||||
|
||||
assert_eq!(node3.is_visible(), false);
|
||||
assert_eq!(node4.is_visible(), false);
|
||||
assert_eq!(node5.is_visible(), false);
|
||||
assert_eq!(node6.is_visible(), false);
|
||||
assert!(!node3.is_visible());
|
||||
assert!(!node4.is_visible());
|
||||
assert!(!node5.is_visible());
|
||||
assert!(!node6.is_visible());
|
||||
|
||||
|
||||
// === Init Update ===
|
||||
|
||||
world.update(&());
|
||||
|
||||
assert_eq!(node3.is_visible(), true);
|
||||
assert_eq!(node4.is_visible(), true);
|
||||
assert_eq!(node5.is_visible(), true);
|
||||
assert_eq!(node6.is_visible(), true);
|
||||
assert!(node3.is_visible());
|
||||
assert!(node4.is_visible());
|
||||
assert!(node5.is_visible());
|
||||
assert!(node6.is_visible());
|
||||
|
||||
assert_eq!(node1.global_position(), Vector3::new(0.0, 0.0, 0.0));
|
||||
assert_eq!(node2.global_position(), Vector3::new(0.0, 0.0, 0.0));
|
||||
@ -1551,10 +1551,10 @@ mod tests {
|
||||
node3.unset_parent();
|
||||
world.update(&());
|
||||
|
||||
assert_eq!(node3.is_visible(), false);
|
||||
assert_eq!(node4.is_visible(), false);
|
||||
assert_eq!(node5.is_visible(), false);
|
||||
assert_eq!(node6.is_visible(), false);
|
||||
assert!(!node3.is_visible());
|
||||
assert!(!node4.is_visible());
|
||||
assert!(!node5.is_visible());
|
||||
assert!(!node6.is_visible());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -26,7 +26,7 @@ ensogl-example-text-area = { path = "text-area" }
|
||||
#enso-frp = { path = "../../frp" }
|
||||
#enso-logger = { path = "../../logger"}
|
||||
#enso-prelude = { path = "../../prelude"}
|
||||
#enso-shapely = { path = "../../shapely/impl"}
|
||||
#enso-shapely = { path = "../../shapely"}
|
||||
#enso-text = { path = "../../text" }
|
||||
#ensogl-core = { path = "../core" }
|
||||
#ensogl-gui-component = { path = "../component/gui" }
|
||||
|
@ -161,7 +161,7 @@ mod test {
|
||||
|
||||
let mut bit_field = BitField32::default();
|
||||
for bit in tested_bits {
|
||||
assert_eq!(bit_field.get_bit(*bit), false);
|
||||
assert!(!bit_field.get_bit(*bit));
|
||||
}
|
||||
|
||||
// Set bits one by one
|
||||
@ -189,7 +189,7 @@ mod test {
|
||||
|
||||
let mut bit_field = BitField256::default();
|
||||
for bit in tested_bits {
|
||||
assert_eq!(bit_field.get_bit(*bit), false);
|
||||
assert!(!bit_field.get_bit(*bit));
|
||||
}
|
||||
|
||||
// Set bits one by one
|
||||
|
99
lib/rust/frp/src/future.rs
Normal file
99
lib/rust/frp/src/future.rs
Normal file
@ -0,0 +1,99 @@
|
||||
//! A module containing helpers for FRP networks in asynchronous environments.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::extend;
|
||||
use crate::node;
|
||||
use crate::stream::EventOutput;
|
||||
use crate::HasLabel;
|
||||
use crate::Label;
|
||||
use crate::Network;
|
||||
|
||||
use std::pin::Pin;
|
||||
use std::task::Context;
|
||||
use std::task::Poll;
|
||||
|
||||
|
||||
|
||||
// ===================
|
||||
// === FutureEvent ===
|
||||
// ===================
|
||||
|
||||
/// A structure returned from [`EventOutputExt::next_event`] method.
|
||||
///
|
||||
/// It's a future which is resolved once the given frp node emits an event. It also allows checking
|
||||
/// if the value is provided - a useful tool when testing components with FRP API.
|
||||
#[derive(Debug)]
|
||||
pub struct FutureEvent<Out> {
|
||||
_network: Network,
|
||||
label: Label,
|
||||
value: Rc<RefCell<Option<Out>>>,
|
||||
wakers: Rc<RefCell<SmallVec<[std::task::Waker; 1]>>>,
|
||||
}
|
||||
|
||||
impl<Out> FutureEvent<Out> {
|
||||
fn new<T>(node: &T) -> Self
|
||||
where
|
||||
T: EventOutput<Output = Out> + HasLabel,
|
||||
Out: node::Data, {
|
||||
let label = node.label();
|
||||
let network = Network::new(format!("{label}.future_event"));
|
||||
let value: Rc<RefCell<Option<Out>>> = default();
|
||||
let wakers: Rc<RefCell<SmallVec<[std::task::Waker; 1]>>> = default();
|
||||
extend! { network
|
||||
let node = node.clone_ref();
|
||||
eval node ([value,wakers](event) {
|
||||
value.set(event.clone());
|
||||
for waker in wakers.take() {
|
||||
waker.wake();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Self { _network: network, label, value, wakers }
|
||||
}
|
||||
|
||||
/// Returns the received event.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if no event was emitted by the node since this structure creation.
|
||||
pub fn expect(self) -> Out {
|
||||
self.value.take().unwrap_or_else(|| ipanic!("Expected {self.label} event"))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Out: node::Data> std::future::Future for FutureEvent<Out> {
|
||||
type Output = Out;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let value = self.value.take();
|
||||
match value {
|
||||
Some(val) => Poll::Ready(val),
|
||||
None => {
|
||||
self.wakers.borrow_mut().push(cx.waker().clone());
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ======================
|
||||
// === EventOutputExt ===
|
||||
// ======================
|
||||
|
||||
/// A trait implemented automatically for every FRP node with helpers related to asynchronous
|
||||
/// environment.
|
||||
pub trait EventOutputExt: EventOutput {
|
||||
/// Returns the future which is resolved once this node emits a next event. The events emitted
|
||||
/// before calling this method are not considered.
|
||||
fn next_event(&self) -> FutureEvent<Self::Output>;
|
||||
}
|
||||
|
||||
impl<T: EventOutput + HasLabel> EventOutputExt for T {
|
||||
fn next_event(&self) -> FutureEvent<Self::Output> {
|
||||
FutureEvent::new(self)
|
||||
}
|
||||
}
|
@ -160,6 +160,7 @@
|
||||
|
||||
pub mod data;
|
||||
pub mod debug;
|
||||
pub mod future;
|
||||
pub mod io;
|
||||
pub mod macros;
|
||||
pub mod network;
|
||||
@ -181,7 +182,6 @@ pub mod prelude {
|
||||
pub use enso_prelude::*;
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod network_mode_tests {
|
||||
use crate as frp;
|
||||
@ -267,7 +267,7 @@ mod dynamic_mode_tests {
|
||||
def toggle_src = source::<()>();
|
||||
def map_src = source::<()>();
|
||||
def toggle = toggle_src.toggle_true();
|
||||
def _map = map_src.map2(&toggle,|_,value| assert_eq!(*value,true));
|
||||
def _map = map_src.map2(&toggle,|_,value| assert!(*value));
|
||||
}
|
||||
map_src.emit(());
|
||||
}
|
||||
@ -278,7 +278,7 @@ mod dynamic_mode_tests {
|
||||
def toggle_src = source::<()>();
|
||||
def map_src = source::<()>();
|
||||
def toggle = toggle_src.toggle();
|
||||
def _map = map_src.map2(&toggle,|_,value| assert_eq!(*value,true));
|
||||
def _map = map_src.map2(&toggle,|_,value| assert!(*value));
|
||||
}
|
||||
toggle_src.emit(());
|
||||
map_src.emit(());
|
||||
@ -301,7 +301,7 @@ mod dynamic_mode_tests {
|
||||
behavior.emit(val);
|
||||
some_event.emit(());
|
||||
}
|
||||
let true_count = input.iter().filter(|&&val| val == true).count();
|
||||
let true_count = input.iter().filter(|&&val| val).count();
|
||||
assert_eq!(passed_events.get(), true_count);
|
||||
}
|
||||
|
||||
@ -310,9 +310,9 @@ mod dynamic_mode_tests {
|
||||
let passed_events = Rc::new(Cell::new(0));
|
||||
frp::new_network! { network
|
||||
source <- source::<bool>();
|
||||
filtered <- source.filter(|&value| value == true);
|
||||
filtered <- source.filter(|&value| value);
|
||||
eval filtered ([passed_events](&value) {
|
||||
assert_eq!(value,true);
|
||||
assert!(value);
|
||||
passed_events.set(passed_events.get() + 1);
|
||||
});
|
||||
};
|
||||
@ -321,7 +321,7 @@ mod dynamic_mode_tests {
|
||||
for val in input {
|
||||
source.emit(*val);
|
||||
}
|
||||
let true_count = input.iter().filter(|&&val| val == true).count();
|
||||
let true_count = input.iter().filter(|&&val| val).count();
|
||||
assert_eq!(passed_events.get(), true_count);
|
||||
}
|
||||
|
||||
@ -338,7 +338,7 @@ mod dynamic_mode_tests {
|
||||
for val in input {
|
||||
source.emit(*val);
|
||||
}
|
||||
let true_count = input.iter().filter(|&&val| val == true).count();
|
||||
let true_count = input.iter().filter(|&&val| val).count();
|
||||
assert_eq!(passed_events.get(), true_count);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ use enso_generics as generics;
|
||||
use enso_generics::traits::*;
|
||||
|
||||
|
||||
|
||||
// ========================
|
||||
// === Network Node API ===
|
||||
// ========================
|
||||
|
@ -650,6 +650,14 @@ where Def: InputBehaviors
|
||||
}
|
||||
}
|
||||
|
||||
impl<Def: HasOutputStatic> HasLabel for WeakNode<Def>
|
||||
where Def: InputBehaviors
|
||||
{
|
||||
fn label(&self) -> Label {
|
||||
self.upgrade().map(|node| node.stream.data.label).unwrap_or("<FRP node deleted>")
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME code quality below:
|
||||
impl<Def> HasOutputTypeLabel for Node<Def>
|
||||
where Def: HasOutputStatic + InputBehaviors
|
||||
|
@ -9,7 +9,7 @@ crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
enso-prelude = { path = "../prelude", features = ["futures"]}
|
||||
enso-shapely = { path = "../shapely/impl"}
|
||||
enso-shapely = { path = "../shapely"}
|
||||
enso-web = { path = "../web" }
|
||||
futures = { version = "0.3.1" }
|
||||
failure = { version = "0.1.6" }
|
||||
|
@ -322,14 +322,14 @@ mod tests {
|
||||
#[test]
|
||||
fn test_response_deserialization() {
|
||||
let response = r#"{"jsonrpc":"2.0","id":0,"result":{"exists":true}}"#;
|
||||
let msg = serde_json::from_str(&response).unwrap();
|
||||
let msg = serde_json::from_str(response).unwrap();
|
||||
if let IncomingMessage::Response(resp) = msg {
|
||||
assert_eq!(resp.id, Id(0));
|
||||
if let Result::Success(ret) = resp.result {
|
||||
let obj = ret.result.as_object().expect("expected object ret");
|
||||
assert_eq!(obj.len(), 1);
|
||||
let exists = obj.get("exists").unwrap().as_bool().unwrap();
|
||||
assert_eq!(exists, true)
|
||||
assert!(exists)
|
||||
} else {
|
||||
panic!("Expected a success result")
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ default = []
|
||||
|
||||
[dependencies]
|
||||
enso-prelude = { version = "^0.2.1", path = "../prelude" }
|
||||
enso-shapely = { version = "^0.2.0", path = "../shapely/impl" }
|
||||
enso-shapely = { version = "^0.2.0", path = "../shapely" }
|
||||
wasm-bindgen = { version = "=0.2.58", features = ["nightly"] }
|
||||
js-sys = { version = "0.3.28" }
|
||||
|
||||
|
@ -31,4 +31,4 @@ features = [
|
||||
]
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.2"
|
||||
wasm-bindgen-test = "0.3.8"
|
||||
|
@ -37,4 +37,4 @@ unicode-segmentation = "1.6.0"
|
||||
wasm-bindgen = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.2"
|
||||
wasm-bindgen-test = "0.3.8"
|
||||
|
@ -19,7 +19,7 @@ publish = true
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
enso-shapely = { version = "^0.2.0", path = "../shapely/impl" }
|
||||
enso-shapely = { version = "^0.2.0", path = "../shapely" }
|
||||
|
||||
anyhow = "1.0.37"
|
||||
backtrace = "0.3.53"
|
||||
@ -89,4 +89,4 @@ features = [
|
||||
]
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.2"
|
||||
wasm-bindgen-test = "0.3.8"
|
||||
|
@ -6,7 +6,7 @@ edition = "2021"
|
||||
|
||||
description = "Automated typeclass derivation."
|
||||
readme = "README.md"
|
||||
homepage = "https://github.com/enso-org/rust-lib/src/shapely/impl"
|
||||
homepage = "https://github.com/enso-org/rust-lib/src/shapely"
|
||||
repository = "https://github.com/enso-org/rust-lib"
|
||||
license-file = "../../../LICENSE"
|
||||
|
||||
@ -22,12 +22,12 @@ crate-type = ["cdylib", "rlib"]
|
||||
default = []
|
||||
|
||||
[dependencies]
|
||||
enso-shapely-macros = { version = "^0.2.1", path = "../macros" }
|
||||
paste = { version = "0.1" }
|
||||
derivative = { version = "2.2.0" }
|
||||
shrinkwraprs = { version = "0.3.0" }
|
||||
rustversion = { version = "1.0" }
|
||||
enso-shapely-macros = { version = "^0.2.1", path = "macros" }
|
||||
paste = { version = "0.1" }
|
||||
derivative = { version = "2.2.0" }
|
||||
shrinkwraprs = { version = "0.3.0" }
|
||||
rustversion = { version = "1.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
enso-prelude = { path = "../../prelude" }
|
||||
wasm-bindgen-test = "0.2"
|
||||
enso-prelude = { path = "../prelude" }
|
||||
wasm-bindgen-test = "0.3.8"
|
@ -36,4 +36,4 @@ features = [
|
||||
]
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.2"
|
||||
wasm-bindgen-test = "0.3.8"
|
||||
|
@ -945,8 +945,8 @@ mod benchmarks {
|
||||
use super::*;
|
||||
use test::Bencher;
|
||||
|
||||
const CONS_SIMPLE: &'static str = "ctrl";
|
||||
const CONS_COMPLEX: &'static str = "ctrl cmd alt shift";
|
||||
const CONS_SIMPLE: &str = "ctrl";
|
||||
const CONS_COMPLEX: &str = "ctrl cmd alt shift";
|
||||
|
||||
// === Construction ===
|
||||
|
||||
|
@ -104,6 +104,9 @@ mod tests {
|
||||
|
||||
|
||||
#[test]
|
||||
// Clippy complains about `-180.0.degrees()`, but the precedence is irrelevant, and code looks
|
||||
// cleaner without parentheses
|
||||
#[allow(clippy::precedence)]
|
||||
fn degree_radian_conversions() {
|
||||
fn assert_equivalence(deg: Degrees, rad: Radians) {
|
||||
let deg_from_rad = Degrees::from(rad);
|
||||
|
Loading…
Reference in New Issue
Block a user