diff options
Diffstat (limited to 'vendor/pretty_assertions-0.7.2')
17 files changed, 1490 insertions, 0 deletions
diff --git a/vendor/pretty_assertions-0.7.2/.cargo-checksum.json b/vendor/pretty_assertions-0.7.2/.cargo-checksum.json new file mode 100644 index 000000000..74431486b --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"b330969d16e38104c91ad0ff518af97b1b58137f40a6e834f6da3018d35ae988","Cargo.lock":"b154588bf85189f112a7c1506448f8813316772fe17550a847183db274e4a8b3","Cargo.toml":"35d70dee35b4d888e622d0f770231055a8780e95463b32473fda8023ff7ca047","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"8c9612877aacfa1b42f5e80b679e6c3c93a7ba2bb99dfaf6e87e200dca4b4e6c","README.md":"6988c526027f6920587923a870b6b5f6d816bb9114abbd9c41f251af986eb11e","examples/pretty_assertion.png":"a9a43d098b548cd222056e8f7391cc071ccd07372e9c44d10e254c0a683c7562","examples/pretty_assertion.rs":"41d0527d286baebe09149e33a9359c3e30c7fbfddd41995db4facdee291fcd2c","examples/pretty_assertion_v0_6_1.png":"c07a7a8cd56ebeb840ae8095c024957ddac8a1d011288acf7928f79d85b39e3a","examples/standard_assertion.png":"be6f676deb51d06bcb33f36d194c82228d5585d91f58af590d9040012e38a0a8","examples/standard_assertion.rs":"b520df96e468ab2a6f8b692d12a548a5a6dcbb8a7fb02a91aaad06ec7f1f3a60","scripts/check":"f323d7c808c8d2cfd8d57ff00b453a9b7c7c95dc0f1a7dfcf3c4d2ead3243c72","scripts/install":"311dd0a011d7e91f9e7df497b2d3b8d77ab2c77b136b7168ad104c82794c5d69","scripts/publish":"bae69134256065f3cd35478c67873ae99af680fc7d2ce4506bd391beed8e35ae","src/lib.rs":"b9fc488ea96d9aa3a902e0bb10d7ca0f83d817b06bb8735f901044126835506a","src/printer.rs":"10cb18c1451c6101e778f7d8e1a51a1ec0208c0ef06cf67dbe30d4805cf02a45"},"package":"1cab0e7c02cf376875e9335e0ba1da535775beb5450d21e1dffca068818ed98b"}
\ No newline at end of file diff --git a/vendor/pretty_assertions-0.7.2/CHANGELOG.md b/vendor/pretty_assertions-0.7.2/CHANGELOG.md new file mode 100644 index 000000000..a5c81b75b --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/CHANGELOG.md @@ -0,0 +1,38 @@ +# Unreleased + +# v0.7.2 + +- Fix macro hygiene for expansion in a `no_implicit_prelude` context ([#70](https://github.com/colin-kiegel/rust-pretty-assertions/issues/70), [@tommilligan](https://github.com/tommilligan)) + +# v0.7.1 + +- Fix a bug where multiline changes showed an unhelpful inline diff ([#66](https://github.com/colin-kiegel/rust-pretty-assertions/issues/66), [@tommilligan](https://github.com/tommilligan)) + +# v0.7.0 + +## Changed + +- Move from `difference` to `diff` for calculating diffs. The exact assertion messages generated may differ from previous versions. ([#52](https://github.com/colin-kiegel/rust-pretty-assertions/issues/52), [@tommilligan](https://github.com/tommilligan)) + +For example, the following assertion message from `v0.7.0`: + +![pretty assertion](https://raw.githubusercontent.com/colin-kiegel/rust-pretty-assertions/2d2357ff56d22c51a86b2f1cfe6efcee9f5a8081/examples/pretty_assertion.png) + +Was previously rendered like this in `v0.6.1`: + +![pretty assertion](https://raw.githubusercontent.com/colin-kiegel/rust-pretty-assertions/2d2357ff56d22c51a86b2f1cfe6efcee9f5a8081/examples/pretty_assertion_v0_6_1.png) + +## Added + +- Support for unsized values ([#42](https://github.com/colin-kiegel/rust-pretty-assertions/issues/42), [@stanislav-tkach](https://github.com/stanislav-tkach)) +- Document the `Comparison` struct, which was previously hidden. This can be used to generate a pretty diff of two values without panicking. ([#52](https://github.com/colin-kiegel/rust-pretty-assertions/issues/52), [@tommilligan](https://github.com/tommilligan)) + +## Fixed + +- Fix some unhygenic macro expansions ([#41](https://github.com/colin-kiegel/rust-pretty-assertions/issues/41), [@tommilligan](https://github.com/tommilligan)) + +## Internal + +- Test Windows targets in CI ([#46](https://github.com/colin-kiegel/rust-pretty-assertions/issues/46), [@tommilligan](https://github.com/tommilligan)) +- Bump `ansi_term` version to 0.12 ([#34](https://github.com/colin-kiegel/rust-pretty-assertions/issues/34), [@waywardmonkeys](https://github.com/waywardmonkeys)) +- Code health improvements ([#34](https://github.com/colin-kiegel/rust-pretty-assertions/issues/34), [@waywardmonkeys](https://github.com/waywardmonkeys)) diff --git a/vendor/pretty_assertions-0.7.2/Cargo.lock b/vendor/pretty_assertions-0.7.2/Cargo.lock new file mode 100644 index 000000000..8e433f023 --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/Cargo.lock @@ -0,0 +1,102 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "ctor" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8f45d9ad417bcef4817d614a501ab55cdd96a6fdb24f49aab89a54acfd66b19" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "diff" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" + +[[package]] +name = "output_vt100" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" +dependencies = [ + "winapi", +] + +[[package]] +name = "pretty_assertions" +version = "0.7.2" +dependencies = [ + "ansi_term", + "ctor", + "diff", + "output_vt100", +] + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd9bc7ccc2688b3344c2f48b9b546648b25ce0b20fc717ee7fa7981a8ca9717" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/vendor/pretty_assertions-0.7.2/Cargo.toml b/vendor/pretty_assertions-0.7.2/Cargo.toml new file mode 100644 index 000000000..3f4660d5a --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/Cargo.toml @@ -0,0 +1,36 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "pretty_assertions" +version = "0.7.2" +authors = ["Colin Kiegel <kiegel@gmx.de>", "Florent Fayolle <florent.fayolle69@gmail.com>", "Tom Milligan <code@tommilligan.net>"] +description = "Overwrite `assert_eq!` and `assert_ne!` with drop-in replacements, adding colorful diffs." +documentation = "https://docs.rs/pretty_assertions" +readme = "README.md" +keywords = ["assert", "diff", "pretty", "color"] +categories = ["development-tools"] +license = "MIT/Apache-2.0" +repository = "https://github.com/colin-kiegel/rust-pretty-assertions" +[dependencies.ansi_term] +version = "0.12.1" + +[dependencies.diff] +version = "0.1.12" +[target."cfg(windows)".dependencies.ctor] +version = "0.1.9" + +[target."cfg(windows)".dependencies.output_vt100] +version = "0.1.2" +[badges.travis-ci] +repository = "colin-kiegel/rust-pretty-assertions" diff --git a/vendor/pretty_assertions-0.7.2/LICENSE-APACHE b/vendor/pretty_assertions-0.7.2/LICENSE-APACHE new file mode 100644 index 000000000..8f71f43fe --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/LICENSE-APACHE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/vendor/pretty_assertions-0.7.2/LICENSE-MIT b/vendor/pretty_assertions-0.7.2/LICENSE-MIT new file mode 100644 index 000000000..48b7653f4 --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/LICENSE-MIT @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 rust-derive-builder contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/pretty_assertions-0.7.2/README.md b/vendor/pretty_assertions-0.7.2/README.md new file mode 100644 index 000000000..cc9a6ef74 --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/README.md @@ -0,0 +1,91 @@ +[![Build status](https://travis-ci.org/colin-kiegel/rust-pretty-assertions.svg?branch=master)](https://travis-ci.org/colin-kiegel/rust-pretty-assertions) +[![Latest version](https://img.shields.io/crates/v/pretty-assertions.svg)](https://crates.io/crates/pretty-assertions) +[![All downloads](https://img.shields.io/crates/d/pretty-assertions.svg)](https://crates.io/crates/pretty-assertions) +[![Downloads of latest version](https://img.shields.io/crates/dv/pretty-assertions.svg)](https://crates.io/crates/pretty-assertions) + +# Pretty Assertions + +When writing tests in Rust, you'll probably use `assert_eq!(a, b)` _a lot_. + +If such a test fails, it will present all the details of `a` and `b`. +But you have to spot the differences yourself, which is not always straightforward, +like here: + +![standard assertion](https://raw.githubusercontent.com/colin-kiegel/rust-pretty-assertions/2d2357ff56d22c51a86b2f1cfe6efcee9f5a8081/examples/standard_assertion.png) + +Wouldn't that task be _much_ easier with a colorful diff? + +![pretty assertion](https://raw.githubusercontent.com/colin-kiegel/rust-pretty-assertions/2d2357ff56d22c51a86b2f1cfe6efcee9f5a8081/examples/pretty_assertion.png) + +Yep — and you only need **one line of code** to make it happen: + +```rust,ignore +use pretty_assertions::{assert_eq, assert_ne}; +``` + +<details> +<summary>Show the example behind the screenshots above.</summary> + +```rust,ignore +// 1. add the `pretty_assertions` dependency to `Cargo.toml`. +// 2. insert this line at the top of each module, as needed +use pretty_assertions::{assert_eq, assert_ne}; + +fn main() { + #[derive(Debug, PartialEq)] + struct Foo { + lorem: &'static str, + ipsum: u32, + dolor: Result<String, String>, + } + + let x = Some(Foo { lorem: "Hello World!", ipsum: 42, dolor: Ok("hey".to_string())}); + let y = Some(Foo { lorem: "Hello Wrold!", ipsum: 42, dolor: Ok("hey ho!".to_string())}); + + assert_eq!(x, y); +} +``` + +</details> + +## Tip + +Specify it as [`[dev-dependencies]`](http://doc.crates.io/specifying-dependencies.html#development-dependencies) +and it will only be used for compiling tests, examples, and benchmarks. +This way the compile time of `cargo build` won't be affected! + +Also add `#[cfg(test)]` to your `use` statements, like this: + +```rust,ignore +#[cfg(test)] +use pretty_assertions::{assert_eq, assert_ne}; +``` + +## Note + +- Since `Rust 2018` edition, you need to declare + `use pretty_assertions::{assert_eq, assert_ne};` per module. + Before you would write `#[macro_use] extern crate pretty_assertions;`. +- The replacement is only effective in your own crate, not in other libraries + you include. +- `assert_ne` is also switched to multi-line presentation, but does _not_ show + a diff. +- Under Windows, the terminal state is modified to properly handle VT100 + escape sequences, which may break display for certain use cases. +- The minimum supported rust version (MSRV) is 1.35.0 + +## License + +Licensed under either of + +- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally +submitted for inclusion in the work by you, as defined in the Apache-2.0 +license, shall be dual licensed as above, without any additional terms or +conditions. diff --git a/vendor/pretty_assertions-0.7.2/examples/pretty_assertion.png b/vendor/pretty_assertions-0.7.2/examples/pretty_assertion.png Binary files differnew file mode 100644 index 000000000..1e5b645f0 --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/examples/pretty_assertion.png diff --git a/vendor/pretty_assertions-0.7.2/examples/pretty_assertion.rs b/vendor/pretty_assertions-0.7.2/examples/pretty_assertion.rs new file mode 100644 index 000000000..63246c6d7 --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/examples/pretty_assertion.rs @@ -0,0 +1,3 @@ +use pretty_assertions::assert_eq; + +include!("standard_assertion.rs"); diff --git a/vendor/pretty_assertions-0.7.2/examples/pretty_assertion_v0_6_1.png b/vendor/pretty_assertions-0.7.2/examples/pretty_assertion_v0_6_1.png Binary files differnew file mode 100644 index 000000000..dc192d081 --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/examples/pretty_assertion_v0_6_1.png diff --git a/vendor/pretty_assertions-0.7.2/examples/standard_assertion.png b/vendor/pretty_assertions-0.7.2/examples/standard_assertion.png Binary files differnew file mode 100644 index 000000000..03ea059b7 --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/examples/standard_assertion.png diff --git a/vendor/pretty_assertions-0.7.2/examples/standard_assertion.rs b/vendor/pretty_assertions-0.7.2/examples/standard_assertion.rs new file mode 100644 index 000000000..fddd512f4 --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/examples/standard_assertion.rs @@ -0,0 +1,21 @@ +fn main() { + #[derive(Debug, PartialEq)] + struct Foo { + lorem: &'static str, + ipsum: u32, + dolor: Result<String, String>, + } + + let x = Some(Foo { + lorem: "Hello World!", + ipsum: 42, + dolor: Ok("hey".to_string()), + }); + let y = Some(Foo { + lorem: "Hello Wrold!", + ipsum: 42, + dolor: Ok("hey ho!".to_string()), + }); + + assert_eq!(x, y); +} diff --git a/vendor/pretty_assertions-0.7.2/scripts/check b/vendor/pretty_assertions-0.7.2/scripts/check new file mode 100755 index 000000000..43fb3a9b3 --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/scripts/check @@ -0,0 +1,9 @@ +#!/bin/bash + +set -exuo pipefail + +cargo fmt -- --check +cargo audit --deny warnings +cargo clippy --all-targets -- -D warnings +cargo test +cargo doc --no-deps diff --git a/vendor/pretty_assertions-0.7.2/scripts/install b/vendor/pretty_assertions-0.7.2/scripts/install new file mode 100755 index 000000000..92577640c --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/scripts/install @@ -0,0 +1,6 @@ +#!/bin/bash + +set -exuo pipefail + +rustup component add rustfmt clippy +cargo install cargo-audit cargo-tarpaulin diff --git a/vendor/pretty_assertions-0.7.2/scripts/publish b/vendor/pretty_assertions-0.7.2/scripts/publish new file mode 100755 index 000000000..e904f03eb --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/scripts/publish @@ -0,0 +1,11 @@ +#!/bin/bash + +set -euxo pipefail + +# Don't log the cargo login token while authenticating +set +x +echo "cargo login ***********************************" +cargo login "${CARGO_LOGIN_TOKEN}" +set -x + +cargo publish diff --git a/vendor/pretty_assertions-0.7.2/src/lib.rs b/vendor/pretty_assertions-0.7.2/src/lib.rs new file mode 100644 index 000000000..5c1787533 --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/src/lib.rs @@ -0,0 +1,475 @@ +//! # Pretty Assertions +//! +//! When writing tests in Rust, you'll probably use `assert_eq!(a, b)` _a lot_. +//! +//! If such a test fails, it will present all the details of `a` and `b`. +//! But you have to spot the differences yourself, which is not always straightforward, +//! like here: +//! +//! ![standard assertion](https://raw.githubusercontent.com/colin-kiegel/rust-pretty-assertions/2d2357ff56d22c51a86b2f1cfe6efcee9f5a8081/examples/standard_assertion.png) +//! +//! Wouldn't that task be _much_ easier with a colorful diff? +//! +//! ![pretty assertion](https://raw.githubusercontent.com/colin-kiegel/rust-pretty-assertions/2d2357ff56d22c51a86b2f1cfe6efcee9f5a8081/examples/pretty_assertion.png) +//! +//! Yep — and you only need **one line of code** to make it happen: +//! +//! ```rust +//! use pretty_assertions::{assert_eq, assert_ne}; +//! ``` +//! +//! <details> +//! <summary>Show the example behind the screenshots above.</summary> +//! +//! ```rust,should_panic +//! // 1. add the `pretty_assertions` dependency to `Cargo.toml`. +//! // 2. insert this line at the top of each module, as needed +//! use pretty_assertions::{assert_eq, assert_ne}; +//! +//! #[derive(Debug, PartialEq)] +//! struct Foo { +//! lorem: &'static str, +//! ipsum: u32, +//! dolor: Result<String, String>, +//! } +//! +//! let x = Some(Foo { lorem: "Hello World!", ipsum: 42, dolor: Ok("hey".to_string())}); +//! let y = Some(Foo { lorem: "Hello Wrold!", ipsum: 42, dolor: Ok("hey ho!".to_string())}); +//! +//! assert_eq!(x, y); +//! ``` +//! </details> +//! +//! ## Tip +//! +//! Specify it as [`[dev-dependencies]`](http://doc.crates.io/specifying-dependencies.html#development-dependencies) +//! and it will only be used for compiling tests, examples, and benchmarks. +//! This way the compile time of `cargo build` won't be affected! +//! +//! Also add `#[cfg(test)]` to your `use` statements, like this: +//! +//! ```rust +//! #[cfg(test)] +//! use pretty_assertions::{assert_eq, assert_ne}; +//! ``` +//! +//! ## Note +//! +//! * Since `Rust 2018` edition, you need to declare +//! `use pretty_assertions::{assert_eq, assert_ne};` per module. +//! Before you would write `#[macro_use] extern crate pretty_assertions;`. +//! * The replacement is only effective in your own crate, not in other libraries +//! you include. +//! * `assert_ne` is also switched to multi-line presentation, but does _not_ show +//! a diff. + +#![deny(clippy::all, missing_docs, unsafe_code)] + +pub use ansi_term::Style; +use std::fmt::{self, Debug, Display}; + +mod printer; + +#[cfg(windows)] +use ctor::*; +#[cfg(windows)] +#[ctor] +fn init() { + output_vt100::try_init().ok(); // Do not panic on fail +} + +/// A comparison of two values. +/// +/// Where both values implement `Debug`, the comparison can be displayed as a pretty diff. +/// +/// ``` +/// use pretty_assertions::Comparison; +/// +/// print!("{}", Comparison::new(&123, &134)); +/// ``` +/// +/// The values may have different types, although in practice they are usually the same. +pub struct Comparison<'a, TLeft, TRight> +where + TLeft: ?Sized, + TRight: ?Sized, +{ + left: &'a TLeft, + right: &'a TRight, +} + +impl<'a, TLeft, TRight> Comparison<'a, TLeft, TRight> +where + TLeft: ?Sized, + TRight: ?Sized, +{ + /// Store two values to be compared in future. + /// + /// Expensive diffing is deferred until calling `Debug::fmt`. + pub fn new(left: &'a TLeft, right: &'a TRight) -> Comparison<'a, TLeft, TRight> { + Comparison { left, right } + } +} + +impl<'a, TLeft, TRight> Display for Comparison<'a, TLeft, TRight> +where + TLeft: Debug + ?Sized, + TRight: Debug + ?Sized, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // To diff arbitary types, render them as debug strings + let left_debug = format!("{:#?}", self.left); + let right_debug = format!("{:#?}", self.right); + // And then diff the debug output + printer::write_header(f)?; + printer::write_lines(f, &left_debug, &right_debug) + } +} + +/// Asserts that two expressions are equal to each other (using [`PartialEq`]). +/// +/// On panic, this macro will print a diff derived from [`Debug`] representation of +/// each value. +/// +/// This is a drop in replacement for [`std::assert_eq!`]. +/// You can provide a custom panic message if desired. +/// +/// # Examples +/// +/// ``` +/// use pretty_assertions::assert_eq; +/// +/// let a = 3; +/// let b = 1 + 2; +/// assert_eq!(a, b); +/// +/// assert_eq!(a, b, "we are testing addition with {} and {}", a, b); +/// ``` +#[macro_export] +macro_rules! assert_eq { + ($left:expr , $right:expr,) => ({ + $crate::assert_eq!($left, $right) + }); + ($left:expr , $right:expr) => ({ + match (&($left), &($right)) { + (left_val, right_val) => { + if !(*left_val == *right_val) { + ::std::panic!("assertion failed: `(left == right)`\ + \n\ + \n{}\ + \n", + $crate::Comparison::new(left_val, right_val)) + } + } + } + }); + ($left:expr , $right:expr, $($arg:tt)*) => ({ + match (&($left), &($right)) { + (left_val, right_val) => { + if !(*left_val == *right_val) { + ::std::panic!("assertion failed: `(left == right)`: {}\ + \n\ + \n{}\ + \n", + format_args!($($arg)*), + $crate::Comparison::new(left_val, right_val)) + } + } + } + }); +} + +/// Asserts that two expressions are not equal to each other (using [`PartialEq`]). +/// +/// On panic, this macro will print the values of the expressions with their +/// [`Debug`] representations. +/// +/// This is a drop in replacement for [`std::assert_ne!`]. +/// You can provide a custom panic message if desired. +/// +/// # Examples +/// +/// ``` +/// use pretty_assertions::assert_ne; +/// +/// let a = 3; +/// let b = 2; +/// assert_ne!(a, b); +/// +/// assert_ne!(a, b, "we are testing that the values are not equal"); +/// ``` +#[macro_export] +macro_rules! assert_ne { + ($left:expr, $right:expr) => ({ + $crate::assert_ne!(@ $left, $right, "", ""); + }); + ($left:expr, $right:expr,) => ({ + $crate::assert_ne!(@ $left, $right, "", ""); + }); + ($left:expr, $right:expr, $($arg:tt)+) => ({ + $crate::assert_ne!(@ $left, $right, ": ", $($arg)+); + }); + (@ $left:expr, $right:expr, $maybe_semicolon:expr, $($arg:tt)+) => ({ + match (&($left), &($right)) { + (left_val, right_val) => { + if *left_val == *right_val { + let left_dbg = ::std::format!("{:?}", &*left_val); + let right_dbg = ::std::format!("{:?}", &*right_val); + if left_dbg != right_dbg { + + ::std::panic!("assertion failed: `(left != right)`{}{}\ + \n\ + \n{}\ + \n{}: According to the `PartialEq` implementation, both of the values \ + are partially equivalent, even if the `Debug` outputs differ.\ + \n\ + \n", + $maybe_semicolon, + format_args!($($arg)+), + $crate::Comparison::new(left_val, right_val), + $crate::Style::new() + .bold() + .underline() + .paint("Note")) + } + + ::std::panic!("assertion failed: `(left != right)`{}{}\ + \n\ + \n{}:\ + \n{:#?}\ + \n\ + \n", + $maybe_semicolon, + format_args!($($arg)+), + $crate::Style::new().bold().paint("Both sides"), + left_val) + } + } + } + }); +} + +#[cfg(test)] +#[allow(clippy::eq_op)] +#[no_implicit_prelude] +mod test { + mod assert_eq { + use ::std::string::{String, ToString}; + + #[test] + fn passes() { + let a = "some value"; + crate::assert_eq!(a, a); + } + + #[test] + fn passes_unsized() { + let a: &[u8] = b"e"; + crate::assert_eq!(*a, *a); + } + + #[test] + fn passes_comparable_types() { + let s0: &'static str = "foo"; + let s1: String = "foo".to_string(); + crate::assert_eq!(s0, s1); + } + + #[test] + #[should_panic(expected = r#"assertion failed: `(left == right)` + +[1mDiff[0m [31m< left[0m / [32mright >[0m : +[31m<[0m[1;48;5;52;31m666[0m +[32m>[0m[1;48;5;22;32m999[0m + +"#)] + fn fails() { + crate::assert_eq!(666, 999); + } + + #[test] + #[should_panic(expected = r#"assertion failed: `(left == right)` + +[1mDiff[0m [31m< left[0m / [32mright >[0m : +[31m<[0m[1;48;5;52;31m666[0m +[32m>[0m[1;48;5;22;32m999[0m + +"#)] + fn fails_trailing_comma() { + crate::assert_eq!(666, 999,); + } + + #[test] + #[should_panic(expected = r#"assertion failed: `(left == right)` + +[1mDiff[0m [31m< left[0m / [32mright >[0m : + [ + 101, +[32m> 101,[0m + ] + +"#)] + fn fails_unsized() { + let a: &[u8] = b"e"; + let b: &[u8] = b"ee"; + crate::assert_eq!(*a, *b); + } + + #[test] + #[should_panic( + expected = r#"assertion failed: `(left == right)`: custom panic message + +[1mDiff[0m [31m< left[0m / [32mright >[0m : +[31m<[0m[1;48;5;52;31m666[0m +[32m>[0m[1;48;5;22;32m999[0m + +"# + )] + fn fails_custom() { + crate::assert_eq!(666, 999, "custom panic message"); + } + + #[test] + #[should_panic( + expected = r#"assertion failed: `(left == right)`: custom panic message + +[1mDiff[0m [31m< left[0m / [32mright >[0m : +[31m<[0m[1;48;5;52;31m666[0m +[32m>[0m[1;48;5;22;32m999[0m + +"# + )] + fn fails_custom_trailing_comma() { + crate::assert_eq!(666, 999, "custom panic message",); + } + } + + mod assert_ne { + use ::std::string::{String, ToString}; + + #[test] + fn passes() { + let a = "a"; + let b = "b"; + crate::assert_ne!(a, b); + } + + #[test] + fn passes_unsized() { + let a: &[u8] = b"e"; + let b: &[u8] = b"ee"; + crate::assert_ne!(*a, *b); + } + + #[test] + fn passes_comparable_types() { + let s0: &'static str = "foo"; + let s1: String = "bar".to_string(); + crate::assert_ne!(s0, s1); + } + + #[test] + #[should_panic(expected = r#"assertion failed: `(left != right)` + +[1mBoth sides[0m: +666 +"#)] + fn fails() { + crate::assert_ne!(666, 666); + } + + #[test] + #[should_panic(expected = r#"assertion failed: `(left != right)` + +[1mBoth sides[0m: +666 +"#)] + fn fails_trailing_comma() { + crate::assert_ne!(666, 666,); + } + + #[test] + #[should_panic(expected = r#"assertion failed: `(left != right)` + +[1mBoth sides[0m: +[ + 101, +] + +"#)] + fn fails_unsized() { + let a: &[u8] = b"e"; + crate::assert_ne!(*a, *a); + } + + #[test] + #[should_panic( + expected = r#"assertion failed: `(left != right)`: custom panic message + +[1mBoth sides[0m: +666 +"# + )] + fn fails_custom() { + crate::assert_ne!(666, 666, "custom panic message"); + } + + #[test] + #[should_panic( + expected = r#"assertion failed: `(left != right)`: custom panic message + +[1mBoth sides[0m: +666 +"# + )] + fn fails_custom_trailing_comma() { + crate::assert_ne!(666, 666, "custom panic message",); + } + + // If the values are equal but their debug outputs are not + // show a specific warning + + #[test] + #[should_panic(expected = r#"assertion failed: `(left != right)` + +[1mDiff[0m [31m< left[0m / [32mright >[0m : +[31m<[0m[1;48;5;52;31m-[0m[31m0.0[0m +[32m>0.0[0m + +[1;4mNote[0m: According to the `PartialEq` implementation, both of the values are partially equivalent, even if the `Debug` outputs differ. + +"#)] + fn assert_ne_partial() { + // Workaround for https://github.com/rust-lang/rust/issues/47619 + // can be removed, when we require rust 1.25 or higher + struct Foo(f32); + + use ::std::fmt; + impl fmt::Debug for Foo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + ::std::write!(f, "{:.1?}", self.0) + } + } + + impl ::std::cmp::PartialEq for Foo { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } + } + + crate::assert_ne!(Foo(-0.0), Foo(0.0)); + } + + // Regression tests + + #[test] + #[should_panic] + fn assert_ne_non_empty_return() { + fn not_zero(x: u32) -> u32 { + crate::assert_ne!(x, 0); + x + } + not_zero(0); + } + } +} diff --git a/vendor/pretty_assertions-0.7.2/src/printer.rs b/vendor/pretty_assertions-0.7.2/src/printer.rs new file mode 100644 index 000000000..172b1ed6c --- /dev/null +++ b/vendor/pretty_assertions-0.7.2/src/printer.rs @@ -0,0 +1,474 @@ +use ansi_term::{ + Colour::{Fixed, Green, Red}, + Style, +}; +use std::fmt; + +macro_rules! paint { + ($f:expr, $colour:expr, $fmt:expr, $($args:tt)*) => ( + write!($f, "{}", $colour.paint(format!($fmt, $($args)*))) + ) +} + +const SIGN_RIGHT: char = '>'; // + > → +const SIGN_LEFT: char = '<'; // - < ← + +/// Present the diff output for two mutliline strings in a pretty, colorised manner. +pub(crate) fn write_header(f: &mut fmt::Formatter) -> fmt::Result { + writeln!( + f, + "{} {} / {} :", + Style::new().bold().paint("Diff"), + Red.paint(format!("{} left", SIGN_LEFT)), + Green.paint(format!("right {}", SIGN_RIGHT)) + ) +} + +/// Delay formatting this deleted chunk until later. +/// +/// It can be formatted as a whole chunk by calling `flush`, or the inner value +/// obtained with `take` for further processing. +#[derive(Default)] +struct LatentDeletion<'a> { + // The most recent deleted line we've seen + value: Option<&'a str>, + // The number of deleted lines we've seen, including the current value + count: usize, +} + +impl<'a> LatentDeletion<'a> { + /// Set the chunk value. + fn set(&mut self, value: &'a str) { + self.value = Some(value); + self.count += 1; + } + + /// Take the underlying chunk value, if it's suitable for inline diffing. + /// + /// If there is no value of we've seen more than one line, return `None`. + fn take(&mut self) -> Option<&'a str> { + if self.count == 1 { + self.value.take() + } else { + None + } + } + + /// If a value is set, print it as a whole chunk, using the given formatter. + /// + /// If a value is not set, reset the count to zero (as we've called `flush` twice, + /// without seeing another deletion. Therefore the line in the middle was something else). + fn flush<TWrite: fmt::Write>(&mut self, f: &mut TWrite) -> fmt::Result { + if let Some(value) = self.value { + paint!(f, Red, "{}{}", SIGN_LEFT, value)?; + writeln!(f)?; + self.value = None; + } else { + self.count = 0; + } + + Ok(()) + } +} + +// Adapted from: +// https://github.com/johannhof/difference.rs/blob/c5749ad7d82aa3d480c15cb61af9f6baa08f116f/examples/github-style.rs +// Credits johannhof (MIT License) + +/// Present the diff output for two mutliline strings in a pretty, colorised manner. +pub(crate) fn write_lines<TWrite: fmt::Write>( + f: &mut TWrite, + left: &str, + right: &str, +) -> fmt::Result { + let diff = ::diff::lines(left, right); + + let mut changes = diff.into_iter().peekable(); + let mut previous_deletion = LatentDeletion::default(); + + while let Some(change) = changes.next() { + match (change, changes.peek()) { + // If the text is unchanged, just print it plain + (::diff::Result::Both(value, _), _) => { + previous_deletion.flush(f)?; + writeln!(f, " {}", value)?; + } + // Defer any deletions to next loop + (::diff::Result::Left(deleted), _) => { + previous_deletion.flush(f)?; + previous_deletion.set(deleted); + } + // Underlying diff library should never return this sequence + (::diff::Result::Right(_), Some(::diff::Result::Left(_))) => { + panic!("insertion followed by deletion"); + } + // If we're being followed by more insertions, don't inline diff + (::diff::Result::Right(inserted), Some(::diff::Result::Right(_))) => { + previous_deletion.flush(f)?; + paint!(f, Green, "{}{}", SIGN_RIGHT, inserted)?; + writeln!(f)?; + } + // Otherwise, check if we need to inline diff with the previous line (if it was a deletion) + (::diff::Result::Right(inserted), _) => { + if let Some(deleted) = previous_deletion.take() { + write_inline_diff(f, deleted, inserted)?; + } else { + previous_deletion.flush(f)?; + paint!(f, Green, "{}{}", SIGN_RIGHT, inserted)?; + writeln!(f)?; + } + } + }; + } + + previous_deletion.flush(f)?; + Ok(()) +} + +/// Group character styling for an inline diff, to prevent wrapping each single +/// character in terminal styling codes. +/// +/// Styles are applied automatically each time a new style is given in `write_with_style`. +struct InlineWriter<'a, Writer> { + f: &'a mut Writer, + style: Style, +} + +impl<'a, Writer> InlineWriter<'a, Writer> +where + Writer: fmt::Write, +{ + fn new(f: &'a mut Writer) -> Self { + InlineWriter { + f, + style: Style::new(), + } + } + + /// Push a new character into the buffer, specifying the style it should be written in. + fn write_with_style(&mut self, c: &char, style: Style) -> fmt::Result { + // If the style is the same as previously, just write character + if style == self.style { + write!(self.f, "{}", c)?; + } else { + // Close out previous style + write!(self.f, "{}", self.style.suffix())?; + + // Store new style and start writing it + write!(self.f, "{}{}", style.prefix(), c)?; + self.style = style; + } + Ok(()) + } + + /// Finish any existing style and reset to default state. + fn finish(&mut self) -> fmt::Result { + // Close out previous style + writeln!(self.f, "{}", self.style.suffix())?; + self.style = Default::default(); + Ok(()) + } +} + +/// Format a single line to show an inline diff of the two strings given. +/// +/// The given strings should not have a trailing newline. +/// +/// The output of this function will be two lines, each with a trailing newline. +fn write_inline_diff<TWrite: fmt::Write>(f: &mut TWrite, left: &str, right: &str) -> fmt::Result { + let diff = ::diff::chars(left, right); + let mut writer = InlineWriter::new(f); + + // Print the left string on one line, with differences highlighted + let light = Red.into(); + let heavy = Red.on(Fixed(52)).bold(); + writer.write_with_style(&SIGN_LEFT, light)?; + for change in diff.iter() { + match change { + ::diff::Result::Both(value, _) => writer.write_with_style(value, light)?, + ::diff::Result::Left(value) => writer.write_with_style(value, heavy)?, + _ => (), + } + } + writer.finish()?; + + // Print the right string on one line, with differences highlighted + let light = Green.into(); + let heavy = Green.on(Fixed(22)).bold(); + writer.write_with_style(&SIGN_RIGHT, light)?; + for change in diff.iter() { + match change { + ::diff::Result::Both(value, _) => writer.write_with_style(value, light)?, + ::diff::Result::Right(value) => writer.write_with_style(value, heavy)?, + _ => (), + } + } + writer.finish() +} + +#[cfg(test)] +mod test { + use super::*; + + // ANSI terminal codes used in our outputs. + // + // Interpolate these into test strings to make expected values easier to read. + const RED_LIGHT: &str = "\u{1b}[31m"; + const GREEN_LIGHT: &str = "\u{1b}[32m"; + const RED_HEAVY: &str = "\u{1b}[1;48;5;52;31m"; + const GREEN_HEAVY: &str = "\u{1b}[1;48;5;22;32m"; + const RESET: &str = "\u{1b}[0m"; + + /// Given that both of our diff printing functions have the same + /// type signature, we can reuse the same test code for them. + /// + /// This could probably be nicer with traits! + fn check_printer<TPrint>(printer: TPrint, left: &str, right: &str, expected: &str) + where + TPrint: Fn(&mut String, &str, &str) -> fmt::Result, + { + let mut actual = String::new(); + printer(&mut actual, left, right).expect("printer function failed"); + + println!( + "## left ##\n\ + {}\n\ + ## right ##\n\ + {}\n\ + ## actual diff ##\n\ + {}\n\ + ## expected diff ##\n\ + {}", + left, right, actual, expected + ); + assert_eq!(actual, expected); + } + + #[test] + fn write_inline_diff_empty() { + let left = ""; + let right = ""; + let expected = format!( + "{red_light}<{reset}\n\ + {green_light}>{reset}\n", + red_light = RED_LIGHT, + green_light = GREEN_LIGHT, + reset = RESET, + ); + + check_printer(write_inline_diff, left, right, &expected); + } + + #[test] + fn write_inline_diff_added() { + let left = ""; + let right = "polymerase"; + let expected = format!( + "{red_light}<{reset}\n\ + {green_light}>{reset}{green_heavy}polymerase{reset}\n", + red_light = RED_LIGHT, + green_light = GREEN_LIGHT, + green_heavy = GREEN_HEAVY, + reset = RESET, + ); + + check_printer(write_inline_diff, left, right, &expected); + } + + #[test] + fn write_inline_diff_removed() { + let left = "polyacrylamide"; + let right = ""; + let expected = format!( + "{red_light}<{reset}{red_heavy}polyacrylamide{reset}\n\ + {green_light}>{reset}\n", + red_light = RED_LIGHT, + green_light = GREEN_LIGHT, + red_heavy = RED_HEAVY, + reset = RESET, + ); + + check_printer(write_inline_diff, left, right, &expected); + } + + #[test] + fn write_inline_diff_changed() { + let left = "polymerase"; + let right = "polyacrylamide"; + let expected = format!( + "{red_light}<poly{reset}{red_heavy}me{reset}{red_light}ra{reset}{red_heavy}s{reset}{red_light}e{reset}\n\ + {green_light}>poly{reset}{green_heavy}ac{reset}{green_light}r{reset}{green_heavy}yl{reset}{green_light}a{reset}{green_heavy}mid{reset}{green_light}e{reset}\n", + red_light = RED_LIGHT, + green_light = GREEN_LIGHT, + red_heavy = RED_HEAVY, + green_heavy = GREEN_HEAVY, + reset = RESET, + ); + + check_printer(write_inline_diff, left, right, &expected); + } + + /// If one of our strings is empty, it should not be shown at all in the output. + #[test] + fn write_lines_empty_string() { + let left = ""; + let right = "content"; + let expected = format!( + "{green_light}>content{reset}\n", + green_light = GREEN_LIGHT, + reset = RESET, + ); + + check_printer(write_lines, left, right, &expected); + } + + /// Realistic multiline struct diffing case. + #[test] + fn write_lines_struct() { + let left = r#"Some( + Foo { + lorem: "Hello World!", + ipsum: 42, + dolor: Ok( + "hey", + ), + }, +)"#; + let right = r#"Some( + Foo { + lorem: "Hello Wrold!", + ipsum: 42, + dolor: Ok( + "hey ho!", + ), + }, +)"#; + let expected = format!( + r#" Some( + Foo {{ +{red_light}< lorem: "Hello W{reset}{red_heavy}o{reset}{red_light}rld!",{reset} +{green_light}> lorem: "Hello Wr{reset}{green_heavy}o{reset}{green_light}ld!",{reset} + ipsum: 42, + dolor: Ok( +{red_light}< "hey",{reset} +{green_light}> "hey{reset}{green_heavy} ho!{reset}{green_light}",{reset} + ), + }}, + ) +"#, + red_light = RED_LIGHT, + red_heavy = RED_HEAVY, + green_light = GREEN_LIGHT, + green_heavy = GREEN_HEAVY, + reset = RESET, + ); + + check_printer(write_lines, left, right, &expected); + } + + /// Relistic multiple line chunks + /// + /// We can't support realistic line diffing in large blocks + /// (also, it's unclear how usefult this is) + /// + /// So if we have more than one line in a single removal chunk, disable inline diffing. + #[test] + fn write_lines_multiline_block() { + let left = r#"Proboscis +Cabbage"#; + let right = r#"Probed +Caravaggio"#; + let expected = format!( + r#"{red_light}<Proboscis{reset} +{red_light}<Cabbage{reset} +{green_light}>Probed{reset} +{green_light}>Caravaggio{reset} +"#, + red_light = RED_LIGHT, + green_light = GREEN_LIGHT, + reset = RESET, + ); + + check_printer(write_lines, left, right, &expected); + } + + /// Single deletion line, multiple insertions - no inline diffing. + #[test] + fn write_lines_multiline_insert() { + let left = r#"Cabbage"#; + let right = r#"Probed +Caravaggio"#; + let expected = format!( + r#"{red_light}<Cabbage{reset} +{green_light}>Probed{reset} +{green_light}>Caravaggio{reset} +"#, + red_light = RED_LIGHT, + green_light = GREEN_LIGHT, + reset = RESET, + ); + + check_printer(write_lines, left, right, &expected); + } + + /// Multiple deletion, single insertion - no inline diffing. + #[test] + fn write_lines_multiline_delete() { + let left = r#"Proboscis +Cabbage"#; + let right = r#"Probed"#; + let expected = format!( + r#"{red_light}<Proboscis{reset} +{red_light}<Cabbage{reset} +{green_light}>Probed{reset} +"#, + red_light = RED_LIGHT, + green_light = GREEN_LIGHT, + reset = RESET, + ); + + check_printer(write_lines, left, right, &expected); + } + + /// Regression test for multiline highlighting issue + #[test] + fn write_lines_issue12() { + let left = r#"[ + 0, + 0, + 0, + 128, + 10, + 191, + 5, + 64, +]"#; + let right = r#"[ + 84, + 248, + 45, + 64, +]"#; + let expected = format!( + r#" [ +{red_light}< 0,{reset} +{red_light}< 0,{reset} +{red_light}< 0,{reset} +{red_light}< 128,{reset} +{red_light}< 10,{reset} +{red_light}< 191,{reset} +{red_light}< 5,{reset} +{green_light}> 84,{reset} +{green_light}> 248,{reset} +{green_light}> 45,{reset} + 64, + ] +"#, + red_light = RED_LIGHT, + green_light = GREEN_LIGHT, + reset = RESET, + ); + + check_printer(write_lines, left, right, &expected); + } +} |