From 80eb71ded52a97414a98d5b8405fa36fd11e02ea Mon Sep 17 00:00:00 2001 From: Dennis Date: Thu, 30 May 2024 14:35:52 +0200 Subject: [PATCH] Oxidizing Cucumber tests --- .gitignore | 1 + Cargo.lock | 1181 +++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 17 + src/main.rs | 3 + tests/end-to-end.rs | 384 ++++++++++++++ tests/osm.rs | 264 ++++++++++ 6 files changed, 1850 insertions(+) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs create mode 100644 tests/end-to-end.rs create mode 100644 tests/osm.rs diff --git a/.gitignore b/.gitignore index 9180d6fb5..a0168016a 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,7 @@ Thumbs.db /test/data/corech /test/data/mld /cmake/postinst +/target # Eclipse related files # ######################### diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..16f0ed864 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1181 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "bstr" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "bytecount" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" + +[[package]] +name = "cheap-ruler" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038d6b7abd3a709310d655cbf336f42fd0f0237c84ed0b37caf3e66e0cee5067" +dependencies = [ + "geo-types", + "num-traits", +] + +[[package]] +name = "chksum-core" +version = "0.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6db20071fdeca52ed6a7745519fb2d343fddcb93af81448373b851f072aaec5" +dependencies = [ + "chksum-hash-core", + "thiserror", +] + +[[package]] +name = "chksum-hash-core" +version = "0.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "221456234d441c788a2c51a27b91c4380f499de560670a67d3303e621d37b3bd" + +[[package]] +name = "chksum-hash-md5" +version = "0.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80c33d01c33c9e193fe33e719a29a7eb900c08583375dd1d3269991aacbe434a" +dependencies = [ + "chksum-hash-core", + "thiserror", +] + +[[package]] +name = "chksum-md5" +version = "0.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95dda0f76fbb6069e042c370a928457086e1b4eabc7e75f5f49fe1b913634351" +dependencies = [ + "chksum-core", + "chksum-hash-md5", +] + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", + "terminal_size", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "cucumber" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2940c675f8b0dd864bfedb4283d5fa07b8799eed59a4f7b09fb1257b18c88a1e" +dependencies = [ + "anyhow", + "clap", + "console", + "cucumber-codegen", + "cucumber-expressions", + "derive_more", + "drain_filter_polyfill", + "either", + "futures", + "gherkin", + "globwalk", + "humantime", + "inventory", + "itertools", + "lazy-regex", + "linked-hash-map", + "once_cell", + "pin-project", + "regex", + "sealed", + "smart-default", +] + +[[package]] +name = "cucumber-codegen" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5c9c7e0af8103f81ab300a21be3df1d57a003a151cf0bf41fdd343f85d14552" +dependencies = [ + "cucumber-expressions", + "inflections", + "itertools", + "proc-macro2", + "quote", + "regex", + "syn 2.0.66", + "synthez", +] + +[[package]] +name = "cucumber-expressions" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d794fed319eea24246fb5f57632f7ae38d61195817b7eb659455aa5bdd7c1810" +dependencies = [ + "derive_more", + "either", + "nom", + "nom_locate", + "regex", + "regex-syntax 0.7.5", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "drain_filter_polyfill" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408" + +[[package]] +name = "either" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "geo-types" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ff16065e5720f376fbced200a5ae0f47ace85fd70b7e54269790281353b6d61" +dependencies = [ + "approx", + "num-traits", + "serde", +] + +[[package]] +name = "gherkin" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20b79820c0df536d1f3a089a2fa958f61cb96ce9e0f3f8f507f5a31179567755" +dependencies = [ + "heck 0.4.1", + "peg", + "quote", + "serde", + "serde_json", + "syn 2.0.66", + "textwrap", + "thiserror", + "typed-builder", +] + +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax 0.8.3", +] + +[[package]] +name = "globwalk" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" +dependencies = [ + "bitflags", + "ignore", + "walkdir", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "ignore" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata", + "same-file", + "walkdir", + "winapi-util", +] + +[[package]] +name = "inflections" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" + +[[package]] +name = "inventory" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "lazy-regex" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d12be4595afdf58bd19e4a9f4e24187da2a66700786ff660a418e9059937a4c" +dependencies = [ + "lazy-regex-proc_macros", + "once_cell", + "regex", +] + +[[package]] +name = "lazy-regex-proc_macros" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44bcd58e6c97a7fcbaffcdc95728b393b8d98933bfadad49ed4097845b57ef0b" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 2.0.66", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nom_locate" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e3c83c053b0713da60c5b8de47fe8e494fe3ece5267b2f23090a07a053ba8f3" +dependencies = [ + "bytecount", + "memchr", + "nom", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "osrm-backend" +version = "0.1.0" +dependencies = [ + "cheap-ruler", + "chksum-md5", + "cucumber", + "futures", + "geo-types", + "walkdir", + "xml-builder", +] + +[[package]] +name = "peg" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f76678828272f177ac33b7e2ac2e3e73cc6c1cd1e3e387928aa69562fa51367" +dependencies = [ + "peg-macros", + "peg-runtime", +] + +[[package]] +name = "peg-macros" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "636d60acf97633e48d266d7415a9355d4389cea327a193f87df395d88cd2b14d" +dependencies = [ + "peg-runtime", + "proc-macro2", + "quote", +] + +[[package]] +name = "peg-runtime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555b1514d2d99d78150d3c799d4c357a3e2c2a8062cd108e93a06d9057629c5" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "proc-macro2" +version = "1.0.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "sealed" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a8caec23b7800fb97971a1c6ae365b6239aaeddfb934d6265f8505e795699d" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "serde" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smart-default" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synthez" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d2c2202510a1e186e63e596d9318c91a8cbe85cd1a56a7be0c333e5f59ec8d" +dependencies = [ + "syn 2.0.66", + "synthez-codegen", + "synthez-core", +] + +[[package]] +name = "synthez-codegen" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f724aa6d44b7162f3158a57bccd871a77b39a4aef737e01bcdff41f4772c7746" +dependencies = [ + "syn 2.0.66", + "synthez-core", +] + +[[package]] +name = "synthez-core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bfa6ec52465e2425fd43ce5bbbe0f0b623964f7c63feb6b10980e816c654ea" +dependencies = [ + "proc-macro2", + "quote", + "sealed", + "syn 2.0.66", +] + +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "typed-builder" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe83c85a85875e8c4cb9ce4a890f05b23d38cd0d47647db7895d3d2a79566d2" +dependencies = [ + "typed-builder-macro", +] + +[[package]] +name = "typed-builder-macro" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29a3151c41d0b13e3d011f98adc24434560ef06673a155a6c7f66b9879eecce2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-width" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "xml-builder" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efc4f1a86af7800dfc4056c7833648ea4515ae21502060b5c98114d828f5333b" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..78c508e81 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "osrm-backend" +version = "0.1.0" +edition = "2021" + +[dependencies] +cheap-ruler = "0.4.0" +chksum-md5 = "0.0.0" +cucumber = "0.21.0" +futures = "0.3.30" +geo-types = "0.7.13" +walkdir = "2.5.0" +xml-builder = "0.5.2" + +[[test]] +name = "end-to-end" +harness = false diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 000000000..e7a11a969 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/end-to-end.rs b/tests/end-to-end.rs new file mode 100644 index 000000000..771dfc368 --- /dev/null +++ b/tests/end-to-end.rs @@ -0,0 +1,384 @@ +mod osm; + +use core::panic; +use std::collections::{HashMap, HashSet, VecDeque}; +use std::fs::{create_dir_all, DirEntry, File}; +use std::io::{self, Read, Write}; +use std::path::PathBuf; +use std::{env, fs}; + +use cheap_ruler::CheapRuler; +use cucumber::{self, gherkin::Step, given, when, World}; +use futures::{future, FutureExt}; +use geo_types::{point, Point}; +use osm::{OSMDb, OSMNode, OSMWay}; +use walkdir::WalkDir; + +#[derive(Debug, Default, World)] +struct OSRMWorld { + feature_path: Option, + scenario_id: String, + feature_digest: String, + osrm_digest: String, + osm_id: u64, + profile: String, + + known_osm_nodes: HashSet, + known_locations: HashMap, + + osm_db: OSMDb, +} + +impl OSRMWorld { + fn set_scenario_specific_paths_and_digests(&mut self, path: Option) { + self.feature_path = path.clone(); + + let file = File::open(path.clone().unwrap()) + .expect(&format!("filesystem broken? can't open file {:?}", path)); + self.feature_digest = chksum_md5::chksum(file) + .expect("md5 could not be computed") + .to_hex_lowercase(); + } + + fn make_osm_id(&mut self) -> u64 { + // number implicitly starts a 1. This is in line with previous implementations + self.osm_id += 1; + self.osm_id + } + + fn add_osm_node(&mut self, name: char, location: Point, id: Option) { + if self.known_osm_nodes.contains(&name) { + panic!("duplicate node: {name}"); + } + let id = match id { + Some(id) => id, + None => self.make_osm_id(), + }; + let node = OSMNode { + id, + lat: location.y(), + lon: location.x(), + tags: HashMap::from([("name".to_string(), name.to_string())]), + }; + + self.known_osm_nodes.insert(name); + self.osm_db.add_node(node); + } + + fn add_location(&mut self, name: char, location: Point) { + if self.known_locations.contains_key(&name) { + panic!("duplicate location: {name}") + } + self.known_locations.insert(name, location); + } +} + +const DEFAULT_ORIGIN: [f64; 2] = [1., 1.]; // TODO: move to world? +const DEFAULT_GRID_SIZE: f64 = 100.; // TODO: move to world? + +fn offset_origin_by(dx: f64, dy: f64) -> geo_types::Point { + let ruler = CheapRuler::new(DEFAULT_ORIGIN[1], cheap_ruler::DistanceUnit::Meters); + ruler.offset( + &point!(DEFAULT_ORIGIN), + dx * DEFAULT_GRID_SIZE, + dy * DEFAULT_GRID_SIZE, + ) //TODO: needs to be world's gridSize, not the local one +} + +#[given(expr = "the profile \"{word}\"")] +fn set_profile(world: &mut OSRMWorld, profile: String) { + println!( + "using profile: {profile} on scenario: {}", + world.scenario_id + ); + world.profile = profile; +} +#[given(expr = "the node map")] +fn set_node_map(world: &mut OSRMWorld, step: &Step) { + if let Some(docstring) = step.docstring() { + // TODO: refactor into a function + docstring + .split('\n') + .enumerate() + .for_each(|(row_index, row)| { + row.chars() + .enumerate() + .filter(|(_column_index, charater)| *charater != ' ') + .for_each(|(column_index, name)| { + // This ports the logic from previous implementations. + let location = + offset_origin_by(column_index as f64 * 0.5, -(row_index as f64 - 1.)); + match name { + '0'...'9' => world.add_location(name, location), + 'a'...'z' => world.add_osm_node(name, location, None), + _ => unreachable!("node name not in [0..9][a..z]"), + } + }); + }); + } else { + panic!("node map not found"); + } +} + +#[given(regex = "the ways")] +fn set_ways(world: &mut OSRMWorld, step: &Step) { + // println!("using profile: {profile}"); + if let Some(table) = step.table.as_ref() { + if table.rows.is_empty() { + panic!("empty way table provided") + } + // store a reference to the headers for convenient lookup + let headers = table.rows.first().unwrap(); + + // iterate over the following rows and build ways one by one + table.rows.iter().skip(1).for_each(|row| { + let mut way = OSMWay { + id: world.make_osm_id(), + ..Default::default() + }; + way.tags.insert("highway".into(), "primary".into()); // default may get overwritten below + row.iter().enumerate().for_each(|(column_index, token)| { + let header = headers[column_index].as_str(); + if header == "nodes" { + assert!( + token.len() >= 2, + "ways must be defined by token of at least length two giving" + ); + way.tags.insert("name".into(), token.clone()); + token.chars().for_each(|name| { + if !world.known_osm_nodes.contains(&name) { + // TODO: this check is probably not necessary since it is also checked below + panic!("referenced unknown node {name} in way {token}"); + } + if let Some((_, node)) = world.osm_db.find_node(name) { + way.add_node(node.clone()); + } else { + panic!("node is known, but not found in osm_db"); + } + }) + } else if !token.is_empty() { + way.tags.insert(header.into(), token.clone()); + } + }); + world.osm_db.add_way(way); + }); + } else { + println!("no table found {step:#?}"); + } + + // println!("{}", world.osm_db.to_xml()) +} + +#[when("I request nearest I should get")] +fn request_nearest(world: &mut OSRMWorld, step: &Step) { + // if .osm file does not exist + // write osm file + // TODO: move to cache_file/path(.) function in OSRMWorld + let full_path = world.feature_path.clone().unwrap(); + let path = full_path + .ancestors() + .find(|p| p.ends_with("features")) + .expect(".feature files reside in a directory tree with the root name 'features'"); + + let suffix = full_path.strip_prefix(path).unwrap(); + let path = path.parent().unwrap(); + println!("suffix: {suffix:?}"); + let cache_path = path + .join("test") + .join("cache") + .join(suffix) + .join(&world.feature_digest); + + println!("{cache_path:?}"); + if !cache_path.exists() { + create_dir_all(&cache_path).expect("cache path could not be created"); + } else { + println!("not creating cache dir"); + } + + let osm_file = cache_path.join(world.scenario_id.clone() + ".osm"); + if !osm_file.exists() { + println!("writing to osm file: {osm_file:?}"); + let mut file = File::create(osm_file).expect("could not create OSM file"); + file.write_all(world.osm_db.to_xml().as_bytes()) + .expect("could not write OSM file"); + } else { + println!("not writing to OSM file {osm_file:?}"); + } + + // if extracted file does not exist + // extract osm file (partition, preprocess) + + // parse table from Step and build query list + // run queries (in parallel) and validate results + todo!("nearest {step:?}"); +} + +// TODO: move to different file +fn get_file_as_byte_vec(path: &PathBuf) -> Vec { + println!("opening {path:?}"); + let mut f = File::open(&path).expect("no file found"); + let metadata = fs::metadata(&path).expect("unable to read metadata"); + let mut buffer = vec![0; metadata.len() as usize]; + f.read(&mut buffer).expect("buffer overflow"); + + buffer +} + +// TODO: port into toolbox-rs +struct LexicographicFileWalker { + dirs: VecDeque, + files: VecDeque, +} + +impl LexicographicFileWalker { + pub fn new(path: &PathBuf) -> Self { + let mut dirs = VecDeque::new(); + + if path.is_dir() { + dirs.push_back(path.clone()); + } + + Self { + dirs, + files: VecDeque::new(), + } + } +} + +impl Iterator for LexicographicFileWalker { + type Item = PathBuf; + + fn next(&mut self) -> Option { + if self.dirs.is_empty() && self.files.is_empty() { + return None; + } + while self.files.is_empty() && !self.dirs.is_empty() { + assert!(!self.dirs.is_empty()); + let current_dir = self.dirs.pop_front().unwrap(); + let mut temp_dirs = Vec::new(); + + for entry in fs::read_dir(current_dir).unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + if path.is_dir() { + temp_dirs.push(path.clone()); + } else { + self.files.push_back(path.clone()); + } + } + self.files.make_contiguous().sort(); + temp_dirs.sort(); + self.dirs.extend(temp_dirs.into_iter()); + } + return self.files.pop_front(); + } +} + +fn main() { + // create OSRM digest before any tests are executed since cucumber-rs doesn't have @beforeAll + let exe_path = env::current_exe().expect("failed to get current exe path"); + let path = exe_path + .ancestors() + .find(|p| p.ends_with("target")) + .expect("compiled cucumber test executable resides in a directory tree with the root name 'target'") + .parent().unwrap(); // TODO: Remove after migration to Rust build dir + let build_path = path.join("build"); // TODO: Remove after migration to Rust build dir + let mut dependencies = Vec::new(); + + // FIXME: the following iterator gymnastics port the exact behavior of the JavaScript implementation + let names = [ + "osrm-extract", + "osrm-contract", + "osrm-customize", + "osrm-partition", + "osrm_extract", + "osrm_contract", + "osrm_customize", + "osrm_partition", + ]; + + let files: Vec = fs::read_dir(&build_path) + .unwrap() + .into_iter() + .filter_map(|e| e.ok()) + .map(|dir_entry| dir_entry.path()) + .collect(); + + let iter = names.iter().map(|name| { + files + .iter() + .find(|path_buf| { + path_buf + .file_stem() + .unwrap() + .to_str() + .unwrap() + .contains(name) + }) + .map(|e| e.clone()) + .expect("file exists and is usable") + }); + + dependencies.extend(iter); + + let profiles_path = path.join("profiles"); + println!("{profiles_path:?}"); + + dependencies.extend( + LexicographicFileWalker::new(&profiles_path) + .filter(|pb| !pb.to_str().unwrap().contains("examples")) + .filter(|pathbuf| match pathbuf.extension() { + Some(ext) => ext.to_str().unwrap() == "lua", + None => false, + }), + ); + let mut md5 = chksum_md5::new(); + println!("md5: {}", md5.digest().to_hex_lowercase()); + + for path_buf in dependencies { + let data = get_file_as_byte_vec(&path_buf); + if data.len() == 0 { + continue; + } + md5.update(data); + // println!("md5: {}", md5.digest().to_hex_lowercase()); + } + + futures::executor::block_on( + OSRMWorld::cucumber() + .before(move |_feature, _rule, scenario, world| { + // TODO: move to function call below + // ports the following logic: + // let name = scenario.getName().toLowerCase().replace(/[/\-'=,():*#]/g, '') + // .replace(/\s/g, '_').replace(/__/g, '_').replace(/\.\./g, '.') + // .substring(0, 64); + let mut s = scenario + .name + .to_ascii_lowercase() + .replace( + &['/', '\\', '-', '\'', '=', ',', '(', ')', ':', '*', '#'][..], + "", + ) + .chars() + .map(|x| match x { + ' ' => '_', + _ => x, + }) + .collect::() + .replace(r"\", "_") + .replace("__", "_") + .replace("..", "."); + s.truncate(64); + + world.scenario_id = format!("{}_{}", scenario.position.line, s); + world.set_scenario_specific_paths_and_digests(_feature.path.clone()); + world.osrm_digest = md5.digest().to_hex_lowercase(); + + // TODO: clean up cache if needed + + future::ready(()).boxed() + }) + .run_and_exit("features/nearest/pick.feature"), + ); +} diff --git a/tests/osm.rs b/tests/osm.rs new file mode 100644 index 000000000..f50549359 --- /dev/null +++ b/tests/osm.rs @@ -0,0 +1,264 @@ +// TODO: consider trait for OSM entities +// TODO: better error handling in XML creation +// FIXME: today nodes are stored twice +// TODO: move node lookup by name to here +use std::collections::HashMap; + +use xml_builder::{XMLBuilder, XMLElement, XMLVersion}; + +static OSM_USER: &str = "osrm"; +static OSM_TIMESTAMP :&str = "2000-01-01T00:00:00Z"; +static OSM_UID: &str = "1"; + +#[derive(Clone, Debug, Default)] +pub struct OSMNode { + pub id: u64, + pub lat: f64, + pub lon: f64, + pub tags: HashMap, +} + +impl OSMNode { + pub fn add_tag(&mut self, key: &str, value: &str) { + self.tags.insert(key.into(), value.into()); + } + + pub fn set_id_(&mut self, id: u64) { + self.id = id; + } + + pub fn set_tags(&mut self, tags: HashMap) { + self.tags = tags + } + + pub fn to_xml(&self) -> XMLElement { + let mut node = XMLElement::new("node"); + node.add_attribute("id", &self.id.to_string()); + node.add_attribute("version", "1"); + node.add_attribute("uid", &OSM_UID); + node.add_attribute("user", &OSM_USER); + node.add_attribute("timestamp", &OSM_TIMESTAMP); + node.add_attribute("lon", &format!("{:?}", self.lon)); + node.add_attribute("lat", &format!("{:?}", self.lat)); + + if !self.tags.is_empty() { + for (key, value) in &self.tags { + let mut tags = XMLElement::new("tag"); + tags.add_attribute("k", key); + tags.add_attribute("v", value); + node.add_child(tags).unwrap(); + } + } + + node + } +} + +#[derive(Clone, Debug, Default)] +pub struct OSMWay { + pub id: u64, + pub osm_user: String, + pub osm_time_stamp: String, + pub osm_uid: u64, + pub tags: HashMap, + pub nodes: Vec, + pub add_locations: bool, +} + +impl OSMWay { + pub fn add_node(&mut self, node: OSMNode) { + self.nodes.push(node); + } + + pub fn set_tags(&mut self, tags: HashMap) { + self.tags = tags; + } + + pub fn to_xml(&self) -> XMLElement { + let mut way = XMLElement::new("way"); + way.add_attribute("id", &self.id.to_string()); + way.add_attribute("version", "1"); + way.add_attribute("uid", &self.osm_uid.to_string()); + way.add_attribute("user", &self.osm_user); + way.add_attribute("timestamp", &self.osm_time_stamp); + + assert!(self.nodes.len() >= 2); + + for node in &self.nodes { + let mut nd = XMLElement::new("nd"); + nd.add_attribute("ref", &node.id.to_string()); + if self.add_locations { + nd.add_attribute("lon", &format!("{:?}", node.lon)); + nd.add_attribute("lat", &format!("{:?}", node.lat)); + } + way.add_child(nd).unwrap(); + } + + if !self.tags.is_empty() { + for (key, value) in &self.tags { + let mut tags = XMLElement::new("tag"); + tags.add_attribute("k", key); + tags.add_attribute("v", value); + way.add_child(tags).unwrap(); + } + } + + way + } +} + +#[derive(Clone, Debug)] +struct Member { + id: u64, + member_type: String, + member_role: String, +} + +#[derive(Clone, Debug)] +struct OSMRelation { + id: u64, + osm_user: String, + osm_time_stamp: String, + osm_uid: String, + members: Vec, + tags: HashMap, +} + +impl OSMRelation { + fn add_member(&mut self, member_type: String, id: u64, member_role: String) { + self.members.push(Member { + id, + member_type, + member_role, + }); + } + + pub fn add_tag(&mut self, key: &str, value: &str) { + self.tags.insert(key.into(), value.into()); + } +} + +#[derive(Debug, Default)] +pub struct OSMDb { + nodes: Vec<(char, OSMNode)>, + ways: Vec, + relations: Vec, +} + +impl OSMDb { + pub fn add_node(&mut self, node: OSMNode) { + let name = node.tags.get("name").unwrap(); + assert!(name.len() == 1, "name needs to be of length 1, but was \"{name}\""); + self.nodes.push((name.chars().next().unwrap() as char, node)); + } + + pub fn find_node(&self, search_name: char) -> Option<&(char, OSMNode)> { + // TODO: this is a linear search. + self.nodes.iter().find(|(name, _node)| { + search_name == *name + }) + } + + pub fn add_way(&mut self, way: OSMWay) { + self.ways.push(way); + } + + pub fn add_relation(&mut self, relation: OSMRelation) { + self.relations.push(relation); + } + + pub fn clear(&mut self) { + self.nodes.clear(); + self.ways.clear(); + self.relations.clear(); + } + + pub fn to_xml(&self) -> String { + let mut xml = XMLBuilder::new() + .version(XMLVersion::XML1_0) + .encoding("UTF-8".into()) + .build(); + + let mut osm = XMLElement::new("osm"); + osm.add_attribute("generator", "osrm-test"); + osm.add_attribute("version", "0.6"); + + for (_, node) in &self.nodes { + osm.add_child(node.to_xml()).unwrap(); + } + + for way in &self.ways { + osm.add_child(way.to_xml()).unwrap(); + } + + xml.set_root_element(osm); + + let mut writer: Vec = Vec::new(); + xml.generate(&mut writer).unwrap(); + String::from_utf8(writer).unwrap() + } + + pub fn node_len(&self) -> usize { + self.nodes.len() + } + pub fn way_len(&self) -> usize { + self.ways.len() + } + pub fn relation_len(&self) -> usize { + self.relations.len() + } +} + +#[cfg(test)] +mod test { + use super::{OSMNode, OSMWay}; + + #[test] + fn empty_db_by_default() { + let osm_db = crate::OSMDb::default(); + assert_eq!(0, osm_db.node_len()); + assert_eq!(0, osm_db.way_len()); + assert_eq!(0, osm_db.relation_len()); + } + + #[test] + fn osm_db_with_single_node() { + let mut osm_db = crate::OSMDb::default(); + + let mut node1 = OSMNode { + id: 123, + lat: 50.1234, + lon: 8.9876, + ..Default::default() + }; + + let mut node2 = OSMNode { + id: 321, + lat: 50.1234, + lon: 8.9876, + ..Default::default() + }; + node1.add_tag("name", "a"); + node2.add_tag("name", "b"); + osm_db.add_node(node1.clone()); + osm_db.add_node(node2.clone()); + + let mut way = OSMWay { + id: 890, + osm_user: "osrm".into(), + osm_time_stamp: "2000-01-01T00:00:00Z".into(), + osm_uid: 1, + ..Default::default() + }; + way.nodes.push(node1); + way.nodes.push(node2); + + osm_db.add_way(way); + + let actual = osm_db.to_xml(); + let expected = "\n\n\t\n\t\t\n\t\n\t\n\t\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n"; + + println!("{actual}"); + assert_eq!(actual, expected); + } +}