Integration Test Framework (#3257)

This commit is contained in:
Adam Obuchowicz 2022-02-11 13:19:02 +01:00 committed by GitHub
parent 1814d3c4f1
commit c68ac5c0d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
85 changed files with 751 additions and 687 deletions

395
Cargo.lock generated
View File

@ -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"

View File

@ -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

View File

@ -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" }

View File

@ -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);

View File

@ -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)
}
}

View File

@ -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();

View File

@ -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()
}

View File

@ -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");

View File

@ -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())
}

View File

@ -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)
);

View File

@ -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);

View File

@ -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"] }

View File

@ -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,
});

View File

@ -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))

View File

@ -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!({

View File

@ -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**

View File

@ -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" }

View File

@ -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("++"));
}
}

View File

@ -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]

View File

@ -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);

View File

@ -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");
}

View File

@ -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());

View File

@ -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);
};

View File

@ -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]

View File

@ -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] {

View File

@ -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 }
}

View File

@ -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());
}

View File

@ -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.

View File

@ -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(),

View File

@ -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;

View File

@ -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.
///

View File

@ -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(), &[

View File

@ -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>();

View File

@ -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(),

View File

@ -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 ===
// ============

View File

@ -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);

View File

@ -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()));

View File

@ -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));
});
}

View File

@ -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
}
}

View File

@ -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]

View File

@ -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()));

View File

@ -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);

View File

@ -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.

View File

@ -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![] };

View File

@ -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" }

View File

@ -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" }

View File

@ -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
}
}

View File

@ -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()
}

View File

@ -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'])
}

View File

@ -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);
}
}
}

View 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"

View 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();
}
}

View 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(), "");
}

View File

@ -0,0 +1,5 @@
{
"goog:chromeOptions": {
"args": ["--no-proxy-server", "--no-sandbox"]
}
}

View File

@ -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));
})
});
}

View File

@ -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)),

View File

@ -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());
}
}

View File

@ -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" }

View File

@ -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);

View File

@ -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" }

View File

@ -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]

View File

@ -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" }

View File

@ -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

View 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)
}
}

View File

@ -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);
}
}

View File

@ -22,7 +22,6 @@ use enso_generics as generics;
use enso_generics::traits::*;
// ========================
// === Network Node API ===
// ========================

View File

@ -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

View File

@ -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" }

View File

@ -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")
}

View File

@ -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" }

View File

@ -31,4 +31,4 @@ features = [
]
[dev-dependencies]
wasm-bindgen-test = "0.2"
wasm-bindgen-test = "0.3.8"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -36,4 +36,4 @@ features = [
]
[dev-dependencies]
wasm-bindgen-test = "0.2"
wasm-bindgen-test = "0.3.8"

View File

@ -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 ===

View File

@ -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);