* [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10
@ 2024-03-17 15:59 Aaron Covrig via Guix-patches via
2024-03-19 10:45 ` Efraim Flashner
0 siblings, 1 reply; 4+ messages in thread
From: Aaron Covrig via Guix-patches via @ 2024-03-17 15:59 UTC (permalink / raw)
To: 69859; +Cc: Aaron Covrig, efraim
* gnu/packages/crates-io.scm (rust-pcap-1): New variable
* gnu/packages/crates-io.scm (rust-pcap-0.11): New variable
* gnu/packages/crates-io.scm (rust-pcap-0.10): New variable
* gnu/packages/crates-io.scm (rust-gat-std-0.1): New variable
* gnu/packages/crates-io.scm (rust-gat-std-proc-0.1): New variable
* gnu/packages/crates-io.scm (rust-etherparse-0.14): New variable
* gnu/packages/crates-io.scm (rust-etherparse-0.9): New variable
* gnu/packages/crates-io.scm (rust-eui48-1): New variable
* gnu/packages/crates-io.scm (rust-tun-tap-0.1): New variable
* gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch:
New file (provides tests and examples rust-mockall)
* gnu/packages/crates-io.scm (rust-mockall-0.12): New variable
* gnu/packages/crates-io.scm (rust-mockall-derive-0.12): New variable
* gnu/packages/crates-io.scm (rust-mockall-0.11): Bumps to 0.11.4
* gnu/packages/crates-io.scm (rust-mockall-derive-0.11): Bumps to 0.11.4
* gnu/packages/crates-io.scm (rust-mockall-double-0.3): Bumps to 0.3.1
* gnu/packages/crates-io.scm (rust-fragile-2): New variable
* gnu/packages/crates-io.scm (rust-fragile-1): Bumps to 1.2.2
* gnu/packages/crates-io.scm (rust-slab-0.4): Bumps to 0.4.9
---
gnu/packages/crates-io.scm | 453 +-
...t-mockall-restore-examples-and-tests.patch | 7611 +++++++++++++++++
2 files changed, 7976 insertions(+), 88 deletions(-)
create mode 100644 gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch
diff --git a/gnu/packages/crates-io.scm b/gnu/packages/crates-io.scm
index e99f0f991b..34916d251e 100644
--- a/gnu/packages/crates-io.scm
+++ b/gnu/packages/crates-io.scm
@@ -24519,25 +24519,41 @@ (define-public rust-form-urlencoded-1
syntax, as used by HTML forms.")
(license (list license:expat license:asl2.0))))
-(define-public rust-fragile-1
+(define-public rust-fragile-2
(package
(name "rust-fragile")
- (version "1.0.0")
+ (version "2.0.0")
(source
(origin
(method url-fetch)
(uri (crate-uri "fragile" version))
(file-name (string-append name "-" version ".tar.gz"))
(sha256
- (base32 "1wlihmkjyhvl5rckal32p010piy1l15s6l81h7z31jcd971kk839"))))
+ (base32 "1ajfdnwdn921bhjlzyvsqvdgci8ab40ln6w9ly422lf8svb428bc"))))
(build-system cargo-build-system)
- (arguments `(#:skip-build? #t))
- (home-page "https://github.com/mitsuhiko/rust-fragile")
+ (arguments
+ `(#:cargo-inputs (("rust-slab" ,rust-slab-0.4))))
+ (home-page "https://github.com/mitsuhiko/fragile")
(synopsis "Wrapper types for sending non-send values to other threads")
(description "This package provides wrapper types for sending non-send
values to other threads.")
(license license:asl2.0)))
+(define-public rust-fragile-1
+ (package
+ (inherit rust-fragile-2)
+ (name "rust-fragile")
+ (version "1.2.2")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "fragile" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "1s2rz4cmmba5zi0gf2h6hprrcrf0wm83c1y45sdls09z99f4qimp"))))
+ (arguments
+ `(#:cargo-inputs (("rust-fragile" ,rust-fragile-2))))))
+
(define-public rust-freetype-0.7
(package
(name "rust-freetype")
@@ -25974,6 +25990,48 @@ (define-public rust-galil-seiferas-0.1
time, for nonorderable alphabets.")
(license (list license:expat license:asl2.0))))
+(define-public rust-gat-std-0.1
+ (package
+ (name "rust-gat-std")
+ (version "0.1.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "gat-std" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "14v4ldnzi8y8zkcj2qq7rj4af5ygk0s9iklflssxpcdgqzsfp3p0"))))
+ (build-system cargo-build-system)
+ (arguments
+ `(#:cargo-inputs (("rust-gat-std-proc" ,rust-gat-std-proc-0.1))))
+ (home-page "https://github.com/CraftSpider/gat-std")
+ (synopsis "Variants of Rust std traits that use GATs")
+ (description
+ "A variant of Rust std traits that use GATs, as well as a macro to allow
+rewriting code to use these traits instead of the std equivalents.")
+ (license (list license:expat license:asl2.0))))
+
+(define-public rust-gat-std-proc-0.1
+ (package
+ (name "rust-gat-std-proc")
+ (version "0.1.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "gat-std-proc" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "0br6d92fg4g7s81lsms6q3ayss1bl19fanqxc7v1csnic2vaw84c"))))
+ (build-system cargo-build-system)
+ (arguments
+ `(#:cargo-inputs (("rust-proc-macro2" ,rust-proc-macro2-1)
+ ("rust-quote" ,rust-quote-1)
+ ("rust-syn" ,rust-syn-1))))
+ (home-page "https://github.com/CraftSpider/gat-std")
+ (synopsis "Proc macros for gat-std")
+ (description "Proc macros for gat-std.")
+ (license (list license:expat license:asl2.0))))
+
(define-public rust-gcc-0.3
(package
(name "rust-gcc")
@@ -38529,85 +38587,136 @@ (define-public rust-mock-instant-0.2
"This package provides a simple way to mock an std::time::Instant in rust.")
(license license:bsd-0)))
-(define-public rust-mockall-0.11
+(define-public rust-mockall-0.12
(package
(name "rust-mockall")
- (version "0.11.1")
- (source (origin
- (method url-fetch)
- (uri (crate-uri "mockall" version))
- (file-name (string-append name "-" version ".tar.gz"))
- (sha256
- (base32
- "0k3g3xxf195vsnzmwza047dv89zlg6h5yj5774wjlndgpdvf8han"))))
+ (version "0.12.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "mockall" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "0j0a1wx6sb8yimjgg3q1svrn8jsnaiz9zqgz93ihvc83a8mnqxj3"))
+ (patches (search-patches
+ "rust-mockall-restore-examples-and-tests.patch"))))
(build-system cargo-build-system)
+ ;; Tests depend on additional includes, only running examples
(arguments
- `(#:tests? #f ; Not all files included.
- #:cargo-inputs
- (("rust-cfg-if" ,rust-cfg-if-1)
- ("rust-downcast" ,rust-downcast-0.11)
- ("rust-fragile" ,rust-fragile-1)
- ("rust-lazy-static" ,rust-lazy-static-1)
- ("rust-mockall-derive" ,rust-mockall-derive-0.11)
- ("rust-predicates" ,rust-predicates-2)
- ("rust-predicates-tree" ,rust-predicates-tree-1))
- #:cargo-development-inputs
- (("rust-async-trait" ,rust-async-trait-0.1)
- ("rust-futures" ,rust-futures-0.3)
- ("rust-mockall-double" ,rust-mockall-double-0.3)
- ("rust-serde" ,rust-serde-1)
- ("rust-serde-derive" ,rust-serde-derive-1)
- ("rust-serde-json" ,rust-serde-json-1)
- ("rust-tracing" ,rust-tracing-0.1))))
+ `(#:cargo-test-flags '("--release" "--examples" "--lib")
+ #:cargo-inputs (("rust-cfg-if" ,rust-cfg-if-1)
+ ("rust-downcast" ,rust-downcast-0.11)
+ ("rust-fragile" ,rust-fragile-2)
+ ("rust-lazy-static" ,rust-lazy-static-1)
+ ("rust-mockall-derive" ,rust-mockall-derive-0.12)
+ ("rust-predicates" ,rust-predicates-3)
+ ("rust-predicates-tree" ,rust-predicates-tree-1))
+ #:cargo-development-inputs (("rust-async-trait" ,rust-async-trait-0.1)
+ ("rust-futures" ,rust-futures-0.3)
+ ("rust-mockall-double" ,rust-mockall-double-0.3)
+ ("rust-serde" ,rust-serde-1)
+ ("rust-serde-derive" ,rust-serde-derive-1)
+ ("rust-serde-json" ,rust-serde-json-1)
+ ("rust-tracing" ,rust-tracing-0.1))))
(home-page "https://github.com/asomers/mockall")
(synopsis "Mock object library for Rust")
(description
"Mockall is a rich mocking library with a terse and ergonomic interface.")
(license (list license:expat license:asl2.0))))
-(define-public rust-mockall-derive-0.11
+(define-public rust-mockall-0.11
+ (package
+ (inherit rust-mockall-0.12)
+ (name "rust-mockall")
+ (version "0.11.4")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "mockall" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "15kww0a3wv300wkksc6zj0kz1jwk0hyly48daxs2vvpj300lk12c"))
+ (patches (search-patches
+ "rust-mockall-restore-examples-and-tests.patch"))))
+ (build-system cargo-build-system)
+ ;; Tests depend on additional includes, only running examples
+ (arguments
+ `(#:cargo-test-flags '("--release" "--examples" "--lib")
+ #:cargo-inputs (("rust-cfg-if" ,rust-cfg-if-1)
+ ("rust-downcast" ,rust-downcast-0.11)
+ ("rust-fragile" ,rust-fragile-2)
+ ("rust-lazy-static" ,rust-lazy-static-1)
+ ("rust-mockall-derive" ,rust-mockall-derive-0.11)
+ ("rust-predicates" ,rust-predicates-2)
+ ("rust-predicates-tree" ,rust-predicates-tree-1))
+ #:cargo-development-inputs (("rust-async-trait" ,rust-async-trait-0.1)
+ ("rust-futures" ,rust-futures-0.3)
+ ("rust-mockall-double" ,rust-mockall-double-0.3)
+ ("rust-serde" ,rust-serde-1)
+ ("rust-serde-derive" ,rust-serde-derive-1)
+ ("rust-serde-json" ,rust-serde-json-1)
+ ("rust-tracing" ,rust-tracing-0.1))))))
+
+(define-public rust-mockall-derive-0.12
(package
(name "rust-mockall-derive")
- (version "0.11.1")
- (source (origin
- (method url-fetch)
- (uri (crate-uri "mockall_derive" version))
- (file-name (string-append name "-" version ".tar.gz"))
- (sha256
- (base32
- "1ixhmsrg5ky4b2jlvbxhlpr3mbv7frd6wr8msm005vijb5rmcb96"))))
+ (version "0.12.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "mockall_derive" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "1qhal0m997vy5vv8admrrbcibsq1cjkr1ajbypaa31f3kvkvqz5g"))))
(build-system cargo-build-system)
(arguments
- `(#:cargo-inputs
- (("rust-cfg-if" ,rust-cfg-if-1)
- ("rust-proc-macro2" ,rust-proc-macro2-1)
- ("rust-quote" ,rust-quote-1)
- ("rust-syn" ,rust-syn-1))
- #:cargo-development-inputs
- (("rust-pretty-assertions" ,rust-pretty-assertions-0.7))))
+ `(#:cargo-inputs (("rust-cfg-if" ,rust-cfg-if-1)
+ ("rust-proc-macro2" ,rust-proc-macro2-1)
+ ("rust-quote" ,rust-quote-1)
+ ("rust-syn" ,rust-syn-2))
+ #:cargo-development-inputs (("rust-pretty-assertions" ,rust-pretty-assertions-1))))
(home-page "https://github.com/asomers/mockall")
(synopsis "Procedural macros for the Mockall crate")
(description
"This package procides procedural macros for the Mockall crate.")
(license (list license:expat license:asl2.0))))
+(define-public rust-mockall-derive-0.11
+ (package
+ (inherit rust-mockall-derive-0.12)
+ (name "rust-mockall-derive")
+ (version "0.11.4")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "mockall_derive" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "1fvc9kwjcc9ia6ng7z9z02b4qkl9dvsx9m4z51xz9i0mj1k7bki2"))))
+ (arguments
+ `(#:cargo-inputs (("rust-cfg-if" ,rust-cfg-if-1)
+ ("rust-proc-macro2" ,rust-proc-macro2-1)
+ ("rust-quote" ,rust-quote-1)
+ ("rust-syn" ,rust-syn-1))
+ #:cargo-development-inputs (("rust-pretty-assertions" ,rust-pretty-assertions-1))))))
+
(define-public rust-mockall-double-0.3
(package
(name "rust-mockall-double")
- (version "0.3.0")
- (source (origin
- (method url-fetch)
- (uri (crate-uri "mockall_double" version))
- (file-name (string-append name "-" version ".tar.gz"))
- (sha256
- (base32
- "1xk6hjr7m73zly4hg3zmma437vqvrwnjxy2wfxy1hxbk52xwfwdf"))))
+ (version "0.3.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "mockall_double" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "1s0k85929bf8afvdgq8m2vs8haqpkg9ysdimw7inl99mmkjrdjpi"))))
(build-system cargo-build-system)
(arguments
`(#:cargo-inputs (("rust-cfg-if" ,rust-cfg-if-1)
("rust-proc-macro2" ,rust-proc-macro2-1)
("rust-quote" ,rust-quote-1)
- ("rust-syn" ,rust-syn-1))))
+ ("rust-syn" ,rust-syn-2))))
(home-page "https://github.com/asomers/mockall")
(synopsis "Double test adapter that works well with Mockall")
(description
@@ -46217,8 +46326,91 @@ (define-public rust-pathdiff-0.2
path.")
(license (list license:asl2.0 license:expat))))
+(define-public rust-pcap-1
+ (package
+ (name "rust-pcap")
+ (version "1.3.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "pcap" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "0ygzsi7v2x9ld5cb61dfg8jgifs2rln6qlknypzqjjnmfgy3bscr"))))
+ (build-system cargo-build-system)
+ (arguments
+ `(#:cargo-inputs (("rust-bitflags" ,rust-bitflags-1)
+ ("rust-errno" ,rust-errno-0.2)
+ ("rust-etherparse" ,rust-etherparse-0.13)
+ ("rust-gat-std" ,rust-gat-std-0.1)
+ ("rust-futures" ,rust-futures-0.3)
+ ("rust-libc" ,rust-libc-0.2)
+ ("rust-tokio" ,rust-tokio-1)
+ ("rust-tun-tap" ,rust-tun-tap-0.1)
+ ("rust-windows-sys" ,rust-windows-sys-0.36))
+ #:cargo-development-inputs (("rust-eui48" ,rust-eui48-1)
+ ("rust-mockall" ,rust-mockall-0.11)
+ ("rust-once-cell" ,rust-once-cell-1)
+ ("rust-tempdir" ,rust-tempdir-0.3))))
+ (inputs (list libpcap))
+ (home-page "https://github.com/rust-pcap/pcap")
+ (synopsis "Rust packet capture API around pcap/wpcap")
+ (description "This is a Rust language crate for accessing the packet
+sniffing capabilities of libpcap (or Npcap on Windows).")
+ (license (list license:asl2.0 license:expat))))
+
+(define-public rust-pcap-0.11
+ (package
+ (inherit rust-pcap-1)
+ (name "rust-pcap")
+ (version "0.11.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "pcap" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "0sk9d0ygqgpwn6rpdclx8lqxcz8gm470pyfspbdjcgjvyr5jvncq"))))
+ (arguments
+ `(#:cargo-inputs (("rust-bitflags" ,rust-bitflags-1)
+ ("rust-errno" ,rust-errno-0.2)
+ ("rust-futures" ,rust-futures-0.3)
+ ("rust-libc" ,rust-libc-0.2)
+ ("rust-windows-sys" ,rust-windows-sys-0.36)
+ ("rust-tokio" ,rust-tokio-1))
+ #:cargo-development-inputs (("rust-libloading" ,rust-libloading-0.6)
+ ("rust-pkg-config" ,rust-pkg-config-0.3)
+ ("rust-regex" ,rust-regex-1)
+ ("rust-eui48" ,rust-eui48-1)
+ ("rust-tempdir" ,rust-tempdir-0.3))))))
+
+(define-public rust-pcap-0.10
+ (package
+ (inherit rust-pcap-1)
+ (name "rust-pcap")
+ (version "0.10.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "pcap" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "0yp1akb8y53faf993xv7l7va957waiv9qmjl8m3mpijw2744999d"))))
+ (arguments
+ `(#:cargo-inputs (("rust-bitflags" ,rust-bitflags-1)
+ ("rust-errno" ,rust-errno-0.2)
+ ("rust-futures" ,rust-futures-0.3)
+ ("rust-libc" ,rust-libc-0.2)
+ ("rust-windows-sys" ,rust-windows-sys-0.36)
+ ("rust-tokio" ,rust-tokio-1))
+ #:cargo-development-inputs (("rust-eui48" ,rust-eui48-1)
+ ("rust-libloading" ,rust-libloading-0.6)
+ ("rust-regex" ,rust-regex-1)
+ ("rust-tempdir" ,rust-tempdir-0.3))))))
+
(define-public rust-pcap-0.7
(package
+ (inherit rust-pcap-0.10)
(name "rust-pcap")
(version "0.7.0")
(source
@@ -46228,8 +46420,6 @@ (define-public rust-pcap-0.7
(file-name (string-append name "-" version ".tar.gz"))
(sha256
(base32 "14blflnbj87z3ajlj1hszsl6k7rwa338y4aw2yjm2j0xdpjvj4pr"))))
- (native-inputs (list libpcap))
- (build-system cargo-build-system)
(arguments
`(#:tests? #f ; can't find crate for `futures`
#:cargo-inputs
@@ -46239,11 +46429,7 @@ (define-public rust-pcap-0.7
("rust-mio" ,rust-mio-0.6)
("rust-tokio-core" ,rust-tokio-core-0.1))
#:cargo-development-inputs
- (("rust-tempdir" ,rust-tempdir-0.3))))
- (home-page "https://github.com/rust-pcap/pcap")
- (synopsis "Packet capture API around pcap/wpcap")
- (description "This package provides a packet capture API around pcap/wpcap.")
- (license (list license:expat license:asl2.0))))
+ (("rust-tempdir" ,rust-tempdir-0.3))))))
(define-public rust-pcap-sys-0.1
(package
@@ -57118,29 +57304,91 @@ (define-public rust-ethtool-0.2
(description "Linux Ethtool Communication Library.")
(license license:expat)))
-(define-public rust-etherparse-0.13
+
+(define-public rust-etherparse-0.14
(package
(name "rust-etherparse")
- (version "0.13.0")
+ (version "0.14.2")
(source
(origin
(method url-fetch)
(uri (crate-uri "etherparse" version))
(file-name (string-append name "-" version ".tar.gz"))
(sha256
- (base32 "146rcbnhlpcbl6c6csfhvz0227wbiwhk13md6acq8211b7m94wl2"))))
+ (base32 "1cf9qf089c8a5xlr7az2wcrr0i0l2zi1q9h2ixwalhsbxc1hd294"))))
(build-system cargo-build-system)
(arguments
`(#:cargo-inputs (("rust-arrayvec" ,rust-arrayvec-0.7))
- #:cargo-development-inputs (("rust-assert-matches" ,rust-assert-matches-1)
- ("rust-proptest" ,rust-proptest-1))))
+ #:cargo-development-inputs (("rust-proptest" ,rust-proptest-1))))
(home-page "https://github.com/JulianSchmid/etherparse")
- (synopsis "Library for parsing & writing a bunch of packet based protocols")
+ (synopsis
+ "Library for parsing & writing a bunch of packet based protocols")
(description
- "This package provides a library for parsing & writing a bunch of packet
-based protocols (@code{EthernetII}, IPv4, IPv6, UDP, TCP ...).")
+ "A zero allocation library for parsing & writing a bunch of
+packet based protocols (EthernetII, IPv4, IPv6, UDP, TCP ...).")
(license (list license:expat license:asl2.0))))
+(define-public rust-etherparse-0.13
+ (package
+ (inherit rust-etherparse-0.14)
+ (name "rust-etherparse")
+ (version "0.13.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "etherparse" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "146rcbnhlpcbl6c6csfhvz0227wbiwhk13md6acq8211b7m94wl2"))))
+ (arguments
+ `(#:cargo-inputs (("rust-arrayvec" ,rust-arrayvec-0.7))
+ #:cargo-development-inputs (("rust-assert-matches" ,rust-assert-matches-1)
+ ("rust-proptest" ,rust-proptest-1))))))
+
+(define-public rust-etherparse-0.9
+ (package
+ (inherit rust-etherparse-0.13)
+ (name "rust-etherparse")
+ (version "0.9.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "etherparse" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "01s86nj0k663mgxpj3r7y5wr50l5c3aq0pm4rpzyb7hz50i0k8ig"))))
+ (arguments
+ `(#:cargo-inputs (("rust-byteorder" ,rust-byteorder-1))
+ #:cargo-development-inputs (("rust-assert-matches" ,rust-assert-matches-1)
+ ("rust-proptest" ,rust-proptest-0.9))))))
+
+(define-public rust-eui48-1
+ (package
+ (name "rust-eui48")
+ (version "1.1.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "eui48" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "00cpf25kc3mxhqnahm0bw9xl19gr2pzc5g84dvkc4mwdbsn1hx48"))))
+ (build-system cargo-build-system)
+ (arguments
+ `(#:cargo-inputs (("rust-regex" ,rust-regex-1)
+ ("rust-rustc-serialize" ,rust-rustc-serialize-0.3)
+ ("rust-serde" ,rust-serde-1)
+ ("rust-serde-json" ,rust-serde-json-1))
+ #:cargo-development-inputs (("rust-bincode" ,rust-bincode-1))))
+ (home-page "https://github.com/abaumhauer/eui48")
+ (synopsis "Rust implementation of IEEE EUI-48 (MAC-48) datatype")
+ (description
+ "A library to generate and parse IEEE EUI-48 and EUI-64, also
+known as MAC-48 media access control addresses. The IEEE claims trademarks on
+the names EUI-48 and EUI-64, in which EUI is an abbreviation for Extended Unique
+Identifier.")
+ (license (list license:asl2.0 license:expat))))
+
(define-public rust-rust-hawktracer-0.7
(package
(name "rust-rust-hawktracer")
@@ -62931,26 +63179,23 @@ (define-public rust-skim-0.7
(define-public rust-slab-0.4
(package
(name "rust-slab")
- (version "0.4.8")
+ (version "0.4.9")
(source
- (origin
- (method url-fetch)
- (uri (crate-uri "slab" version))
- (file-name (string-append name "-" version ".tar.gz"))
- (sha256
- (base32
- "0bgwxig8gkqp6gz8rvrpdj6qwa10karnsxwx7wsj5ay8kcf3aa35"))))
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "slab" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "0rxvsgir0qw5lkycrqgb1cxsvxzjv9bmx73bk5y42svnzfba94lg"))))
(build-system cargo-build-system)
(arguments
- `(#:cargo-development-inputs
- (("rust-rustversion" ,rust-rustversion-1)
- ("rust-serde" ,rust-serde-1)
- ("rust-serde-test" ,rust-serde-test-1))
- #:cargo-inputs (("rust-autocfg" ,rust-autocfg-1)
- ("rust-serde" ,rust-serde-1))))
- (native-inputs
- (list rust-autocfg-1))
- (home-page "https://github.com/carllerche/slab")
+ `(#:cargo-development-inputs (("rust-rustversion" ,rust-rustversion-1)
+ ("rust-serde" ,rust-serde-1)
+ ("rust-serde-test" ,rust-serde-test-1)
+ ("rust-autocfg" ,rust-autocfg-1))
+ #:cargo-inputs (("rust-serde" ,rust-serde-1)
+ ("rust-autocfg" ,rust-autocfg-1))))
+ (home-page "https://github.com/tokio-rs/slab")
(synopsis "Pre-allocated storage for a uniform data type")
(description "This create provides a pre-allocated storage for a uniform
data type.")
@@ -74935,6 +75180,38 @@ (define-public rust-tuikit-0.2
#:cargo-development-inputs
(("rust-env-logger" ,rust-env-logger-0.6))))))
+(define-public rust-tun-tap-0.1
+ (package
+ (name "rust-tun-tap")
+ (version "0.1.4")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (crate-uri "tun-tap" version))
+ (file-name (string-append name "-" version ".tar.gz"))
+ (sha256
+ (base32 "0l5yp9xs5kyhzrkqfhnqjwj97ylzr5xd0g6jfp42miv7jd77liws"))))
+ (build-system cargo-build-system)
+ (arguments
+ `(#:cargo-test-flags '("--"
+ ;; Network access not allowed in build environment
+ "--skip=it_receives_packets"
+ "--skip=it_sents_packets")
+ #:cargo-inputs (("rust-futures" ,rust-futures-0.1)
+ ("rust-libc" ,rust-libc-0.2)
+ ("rust-mio" ,rust-mio-0.6)
+ ("rust-tokio-core" ,rust-tokio-core-0.1))
+ #:cargo-development-inputs (("rust-cc" ,rust-cc-1)
+ ("rust-etherparse" ,rust-etherparse-0.9)
+ ("rust-serial-test" ,rust-serial-test-0.4)
+ ("rust-version-sync" ,rust-version-sync-0.9))))
+ (home-page "https://github.com/vorner/tuntap")
+ (synopsis "TUN/TAP interface wrapper")
+ (description
+ "Rust TUN/TAP wrapper allowing the implementation of virtual network adaptors in
+userspace.")
+ (license (list license:expat license:asl2.0))))
+
(define-public rust-twoway-0.2
(package
(name "rust-twoway")
diff --git a/gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch b/gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch
new file mode 100644
index 0000000000..1c1f77eb0d
--- /dev/null
+++ b/gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch
@@ -0,0 +1,7611 @@
+This patch restores the tests and examples that were removed from
+mockall when it was bundled for distribution. They are required
+to enable testing of the built packages.
+
+---
+diff --git a/examples/ffi.rs b/examples/ffi.rs
+new file mode 100644
+index 0000000..6b7c9d0
+--- /dev/null
++++ b/examples/ffi.rs
+@@ -0,0 +1,34 @@
++// vim: tw=80
++//! An example of unit testing involving mocked FFI functions
++
++#[cfg(test)]
++use mockall::automock;
++use mockall_double::double;
++
++#[cfg_attr(test, automock)]
++pub mod mockable_ffi {
++ extern "C" {
++ pub fn abs(i: i32) -> i32;
++ }
++}
++
++#[double]
++use mockable_ffi as ffi;
++
++fn abs(i: i32) -> i32 {
++ unsafe { ffi::abs(i) }
++}
++
++fn main() {
++ let i: i32 = -42;
++ println!("abs({}) = {}", i, abs(i) );
++}
++
++
++#[test]
++fn time_test() {
++ let ctx = ffi::abs_context();
++ ctx.expect()
++ .return_const(42);
++ assert_eq!(42, abs(-42))
++}
+diff --git a/examples/serde.rs b/examples/serde.rs
+new file mode 100644
+index 0000000..4498449
+--- /dev/null
++++ b/examples/serde.rs
+@@ -0,0 +1,102 @@
++// vim: tw=80
++//! Mock a struct that implements Serde traits
++//!
++//! Serde defines to popular traits that look like this:
++//! ```ignore
++//! trait Serialize {
++//! fn serialize<S: Serializer>(&self, serializer: S) -> Result<String, anyhow::Error>;
++//! }
++//! trait Deserialize {
++//! fn deserialize<D: Deserializer>(deserializer: D) -> Result<Self, anyhow::Error>;
++//! }
++//! ```
++//!
++//! Mockall can usually implement traits with generic methods. However,
++//! `serde::Serializer` isn't `'static`, and the definition of
++//! `Serialize::serialize` doesn't require `S` to be static. That's a problem,
++//! because Mockall requires that all generic methods' generic types be
++//! `'static` so that they can implement `std::any::Any`.
++//!
++//! There's no getting around that requirement. But there's still hope! You
++//! can mock a struct that implements Serde traits by manually implementing
++//! `Serialize` and `Deserialize` in terms of non-generic methods, using a
++//! surrogate object for the expectations.
++#![deny(warnings)]
++
++use mockall::*;
++use serde::{Deserialize, Deserializer};
++use serde_derive::*;
++
++/// A serializable surrogate for `Thing`. It should serialize and deserialize
++/// in exactly the same way as `Thing`. In fact, it may even be `Thing`.
++#[derive(Deserialize, Serialize)]
++pub struct SurrogateThing {
++ x: u32
++}
++
++mock! {
++ pub Thing {
++ // MockThing's private deserialize method. The name is not important,
++ // but you probably don't want to call it `deserialize` because then
++ // you'll have to call the real deserialize method using
++ // `<x as Deserialize>::deserialize` syntax.
++ //
++ // This method must always succeed (or panic), because `Deserialize`'s
++ // error type is neither `'static` nor `Default`.
++ fn private_deserialize(deserializable: Result<SurrogateThing, ()>) -> Self;
++ // MockThing's private serialize method. The name is not important,
++ // but you probably don't want to call it `serialize` because then
++ // you'll have to call the real serialize method using
++ // `<x as Serialize>::serialize` syntax.
++ //
++ // This method must always succeed (or panic), because `Serialize`'s
++ // error type is neither `'static` nor `Default`.
++ fn private_serialize(&self) -> SurrogateThing;
++ }
++}
++
++// Manually implement Serialize for MockThing
++impl serde::Serialize for MockThing {
++ fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
++ self.private_serialize().serialize(s)
++ }
++}
++
++// Manually implement Deserialize for MockThing
++impl<'de> Deserialize<'de> for MockThing {
++ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
++ where
++ D: Deserializer<'de>,
++ {
++ let serializable = SurrogateThing::deserialize(deserializer)
++ .map_err(|_| ());
++ Ok(MockThing::private_deserialize(serializable))
++ }
++}
++
++// In your tests, set an expectation for `private_serialize` and return a
++// suitable `SurrogateThing`
++#[test]
++fn serialize() {
++ let mut mock = MockThing::default();
++ mock.expect_private_serialize()
++ .returning(|| SurrogateThing{x: 42} );
++
++ let json = serde_json::to_string(&mock).unwrap();
++ assert_eq!("{\"x\":42}", json);
++}
++
++// In your tests, set an expectation for `private_deserialize`, which will
++// receive an already-deserialized `SurrogateThing` object.
++#[test]
++fn deserialize() {
++ let ctx = MockThing::private_deserialize_context();
++ ctx.expect()
++ .withf(|st: &Result<SurrogateThing, ()>|
++ st.as_ref().unwrap().x == 42
++ ).once()
++ .returning(|_| MockThing::default());
++
++ let json = "{\"x\":42}";
++ let _thing: MockThing = serde_json::from_str(json).unwrap();
++}
+diff --git a/examples/synchronization.rs b/examples/synchronization.rs
+new file mode 100644
+index 0000000..a943b88
+--- /dev/null
++++ b/examples/synchronization.rs
+@@ -0,0 +1,64 @@
++// vim: tw=80
++//! Add synchronization to multiple tests that are accessing the same mock
++//!
++//! When mockall mocks a function or static method, it does so globally. This
++//! can cause hard to debug and non-deterministic failures when one test
++//! overwrites the mock that another test is depending on. The solution to this
++//! is to add some form of synchronization so that tests that depend on a
++//! specific mock will not run in parallel. This is easily achieved using a
++//! Mutex.
++#![deny(warnings)]
++
++use mockall_double::double;
++
++pub mod my_mock {
++ #[cfg(test)]
++ use mockall::automock;
++
++ pub struct Thing;
++ #[cfg_attr(test, automock)]
++ impl Thing {
++ pub fn one() -> u32 {
++ 1
++ }
++ }
++}
++
++#[double]
++use my_mock::Thing;
++
++fn main() {
++ println!("1 == {}", Thing::one());
++}
++
++#[cfg(test)]
++mod test {
++ use crate::my_mock::MockThing;
++ use std::sync::Mutex;
++
++ static MTX: Mutex<()> = Mutex::new(());
++
++ #[test]
++ fn test_1() {
++ // The mutex might be poisoned if another test fails. But we don't
++ // care, because it doesn't hold any data. So don't unwrap the Result
++ // object; whether it's poisoned or not, we'll still hold the
++ // MutexGuard.
++ let _m = MTX.lock();
++
++ let ctx = MockThing::one_context();
++ ctx.expect().returning(|| 1);
++ let expected = 1;
++ assert_eq!(expected, MockThing::one())
++ }
++
++ #[test]
++ fn test_2() {
++ let _m = MTX.lock();
++
++ let ctx = MockThing::one_context();
++ ctx.expect().returning(|| 2);
++ let expected = 2;
++ assert_eq!(expected, MockThing::one())
++ }
++}
+diff --git a/tests/anyhow.rs b/tests/anyhow.rs
+new file mode 100644
+index 0000000..f4f0fd4
+--- /dev/null
++++ b/tests/anyhow.rs
+@@ -0,0 +1,86 @@
++// vim: tw=80
++//! Mockall should be compatible with crates like Anyhow that redefine `Ok`.
++#![deny(warnings)]
++
++use mockall::*;
++
++// Define Error, Result, and Ok similarly to how anyhow defines them
++pub struct Error();
++impl Error {
++ pub fn new<E: std::error::Error>(_e: E) -> Self {
++ Self()
++ }
++}
++#[allow(non_snake_case)]
++pub fn Ok<T>(t: T) -> Result<T> {
++ Result::Ok(t)
++}
++pub type Result<T, E = Error> = std::result::Result<T, E>;
++
++#[automock]
++pub trait Foo {
++ fn foo(&self) -> Result<(), Error>;
++ fn reffoo(&self) -> &Result<(), Error>;
++ fn refmutfoo(&mut self) -> &mut Result<(), Error>;
++ fn staticfoo() -> Result<(), Error>;
++}
++
++mod static_method {
++ use super::*;
++
++ #[test]
++ fn ok() {
++ let mut foo = MockFoo::new();
++ foo.expect_foo()
++ .returning(|| Ok(()));
++ assert!(foo.foo().is_ok());
++ }
++
++ #[test]
++ fn err() {
++ let mut foo = MockFoo::new();
++ foo.expect_foo()
++ .returning(|| Err(Error::new(std::io::Error::last_os_error())));
++ assert!(foo.foo().is_err());
++ }
++}
++
++mod ref_method {
++ use super::*;
++
++ #[test]
++ fn ok() {
++ let mut foo = MockFoo::new();
++ foo.expect_reffoo()
++ .return_const(Ok(()));
++ assert!(foo.reffoo().is_ok());
++ }
++
++ #[test]
++ fn err() {
++ let mut foo = MockFoo::new();
++ foo.expect_reffoo()
++ .return_const(Err(Error::new(std::io::Error::last_os_error())));
++ assert!(foo.reffoo().is_err());
++ }
++}
++
++mod refmut_method {
++ use super::*;
++
++ #[test]
++ fn ok() {
++ let mut foo = MockFoo::new();
++ foo.expect_refmutfoo()
++ .return_var(Ok(()));
++ assert!(foo.refmutfoo().is_ok());
++ }
++
++ #[test]
++ fn err() {
++ let mut foo = MockFoo::new();
++ foo.expect_refmutfoo()
++ .return_var(Err(Error::new(std::io::Error::last_os_error())));
++ assert!(foo.refmutfoo().is_err());
++ }
++}
+diff --git a/tests/automock_associated_const.rs b/tests/automock_associated_const.rs
+new file mode 100644
+index 0000000..b7c14cf
+--- /dev/null
++++ b/tests/automock_associated_const.rs
+@@ -0,0 +1,56 @@
++// vim: tw=80
++//! A trait with an associated constant
++//!
++//! It's not possible to automock the trait, like:
++//! ```
++//! #[automock]
++//! trait Foo {
++//! const X: i32;
++//! }
++//! ```
++//! because there's no way to set the value of X on MockFoo.
++//!
++//! But it _is_ possible to automock the trait implementation, like this:
++//! ```
++//! struct Bar {}
++//! #[automock]
++//! impl Foo for Bar {
++//! const X: i32;
++//! }
++//! ```
++//!
++//! https://github.com/asomers/mockall/issues/97
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++ const X: i32;
++
++ fn x_plus_one(&self) -> i32 {
++ Self::X + 1
++ }
++}
++
++pub struct Bar {}
++
++#[automock]
++impl Foo for Bar {
++ const X: i32 = 42;
++}
++
++pub struct Baz {}
++#[automock]
++impl Baz {
++ pub const Y: i32 = 69;
++}
++
++#[test]
++fn default_method() {
++ assert_eq!(MockBar::new().x_plus_one(), 43);
++}
++
++#[test]
++fn on_a_struct() {
++ assert_eq!(MockBaz::Y, 69);
++}
+diff --git a/tests/automock_associated_type_constructor.rs b/tests/automock_associated_type_constructor.rs
+new file mode 100644
+index 0000000..c9a5a1a
+--- /dev/null
++++ b/tests/automock_associated_type_constructor.rs
+@@ -0,0 +1,36 @@
++// vim: tw=80
++//! A constructor that returns Self as an associated type of some other trait.
++//! This is very useful when working with Futures.
++#![deny(warnings)]
++
++use mockall::*;
++
++pub trait MyIterator {
++ type Item;
++}
++
++pub struct Foo{}
++
++#[automock]
++impl Foo {
++ pub fn open() -> impl MyIterator<Item=Self> {
++ struct Bar {}
++ impl MyIterator for Bar {
++ type Item=Foo;
++ }
++ Bar{}
++ }
++}
++
++#[test]
++fn returning() {
++ let ctx = MockFoo::open_context();
++ ctx.expect().returning(|| {
++ struct Baz {}
++ impl MyIterator for Baz {
++ type Item = MockFoo;
++ }
++ Box::new(Baz{})
++ });
++ let _a = MockFoo::open();
++}
+diff --git a/tests/automock_associated_types.rs b/tests/automock_associated_types.rs
+new file mode 100644
+index 0000000..82ffa78
+--- /dev/null
++++ b/tests/automock_associated_types.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++//! automatic-style mocking with associated types
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock(type T=u32;)]
++trait A {
++ type T: Clone;
++ fn foo(&self, x: Self::T) -> Self::T;
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockA::new();
++ mock.expect_foo()
++ .returning(|x| x);
++ assert_eq!(4, mock.foo(4));
++}
+diff --git a/tests/automock_associated_types_with_qself.rs b/tests/automock_associated_types_with_qself.rs
+new file mode 100644
+index 0000000..937e5b4
+--- /dev/null
++++ b/tests/automock_associated_types_with_qself.rs
+@@ -0,0 +1,23 @@
++// vim: tw=80
++//! automatic-style mocking with associated types, with QSelf
++#![deny(warnings)]
++
++use mockall::*;
++
++trait SomeTrait<Q>{}
++struct Foo {}
++impl SomeTrait<u32> for Foo {}
++
++#[automock(type T=u32;)]
++trait A {
++ type T: Clone;
++ fn baz(&self) -> Box<dyn SomeTrait<<Self as A>::T>>;
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockA::new();
++ mock.expect_baz()
++ .returning(|| Box::new(Foo{}));
++ mock.baz();
++}
+diff --git a/tests/automock_async_trait.rs b/tests/automock_async_trait.rs
+new file mode 100644
+index 0000000..4e642b5
+--- /dev/null
++++ b/tests/automock_async_trait.rs
+@@ -0,0 +1,31 @@
++// vim: tw=80
++//! An async trait, for use with Futures
++#![deny(warnings)]
++
++use async_trait::async_trait;
++use futures::executor::block_on;
++use mockall::*;
++
++#[automock]
++#[async_trait]
++pub trait Foo {
++ async fn foo(&self) -> u32;
++ async fn bar() -> u32;
++}
++
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .return_const(42u32);
++ assert_eq!(block_on(mock.foo()), 42);
++}
++
++#[test]
++fn static_method() {
++ let ctx = MockFoo::bar_context();
++ ctx.expect()
++ .return_const(42u32);
++ assert_eq!(block_on(MockFoo::bar()), 42);
++}
+diff --git a/tests/automock_attrs.rs b/tests/automock_attrs.rs
+new file mode 100644
+index 0000000..bbae260
+--- /dev/null
++++ b/tests/automock_attrs.rs
+@@ -0,0 +1,57 @@
++// vim: tw=80
++//! Attributes are applied to the mock object, too.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub mod m {
++ #[cfg(target_os = "multics")]
++ pub fn bloob(x: DoesNotExist) -> i64 {unimplemented!()}
++ #[cfg(not(target_os = "multics"))]
++ pub fn blarg(_x: i32) -> i64 {unimplemented!()}
++}
++
++#[test]
++fn returning() {
++ let ctx = mock_m::blarg_context();
++ ctx.expect()
++ .returning(|x| i64::from(x) + 1);
++ assert_eq!(5, mock_m::blarg(4));
++}
++
++pub struct A{}
++#[automock]
++impl A {
++ // Neither A::foo nor MockA::foo should be defined
++ #[cfg(target_os = "multics")] pub fn foo(&self, x: DoesNotExist) {}
++ // Both A::bar and MockA::bar should be defined
++ #[cfg(not(target_os = "multics"))] pub fn bar(&self, _x: i32) -> i32 {0}
++}
++
++#[automock]
++pub mod ffi {
++ extern "C" {
++ // mock_ffi::baz should not be defined
++ #[cfg(target_os = "multics")]
++ pub fn baz(x: DoesNotExist) -> i64;
++ // mock_ffi::bean should be defined
++ #[cfg(not(target_os = "multics"))]
++ pub fn bean(x: u32) -> i64;
++ }
++}
++
++#[test]
++fn method() {
++ let mut mock = MockA::new();
++ mock.expect_bar()
++ .returning(|x| x);
++ assert_eq!(4, mock.bar(4));
++}
++
++#[test]
++fn foreign() {
++ let ctx = mock_ffi::bean_context();
++ ctx.expect().returning(i64::from);
++ assert_eq!(42, unsafe{mock_ffi::bean(42)});
++}
+diff --git a/tests/automock_boxed_constructor.rs b/tests/automock_boxed_constructor.rs
+new file mode 100644
+index 0000000..f0d13c9
+--- /dev/null
++++ b/tests/automock_boxed_constructor.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++//! A trait with a constructor method that returns Box<Self>
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub trait A {
++ fn new() -> Box<Self>;
++}
++
++#[test]
++fn returning() {
++ let ctx = MockA::new_context();
++ ctx.expect().returning(Box::default);
++ let _a: Box<MockA> = <MockA as A>::new();
++}
+diff --git a/tests/automock_concretize.rs b/tests/automock_concretize.rs
+new file mode 100644
+index 0000000..f169a20
+--- /dev/null
++++ b/tests/automock_concretize.rs
+@@ -0,0 +1,50 @@
++// vim: tw=80
++//! #[concretize] works with #[automock], too.
++#![deny(warnings)]
++
++use mockall::*;
++use std::path::{Path, PathBuf};
++
++#[automock]
++trait Foo {
++ #[concretize]
++ fn foo<P: AsRef<std::path::Path>>(&self, x: P);
++}
++
++#[automock]
++pub mod mymod {
++ #[mockall::concretize]
++ pub fn bang<P: AsRef<std::path::Path>>(_x: P) { unimplemented!() }
++}
++
++mod generic_arg {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let mut foo = MockFoo::new();
++ foo.expect_foo()
++ .withf(|p| p.as_ref() == Path::new("/tmp"))
++ .times(3)
++ .return_const(());
++ foo.foo(Path::new("/tmp"));
++ foo.foo(PathBuf::from(Path::new("/tmp")));
++ foo.foo("/tmp");
++ }
++}
++
++mod module {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let ctx = mock_mymod::bang_context();
++ ctx.expect()
++ .withf(|p| p.as_ref() == Path::new("/tmp"))
++ .times(3)
++ .return_const(());
++ mock_mymod::bang(Path::new("/tmp"));
++ mock_mymod::bang(PathBuf::from(Path::new("/tmp")));
++ mock_mymod::bang("/tmp");
++ }
++}
+diff --git a/tests/automock_constructor_impl_trait.rs b/tests/automock_constructor_impl_trait.rs
+new file mode 100644
+index 0000000..7384e11
+--- /dev/null
++++ b/tests/automock_constructor_impl_trait.rs
+@@ -0,0 +1,30 @@
++// vim: tw=80
++//! A trait with a constructor method that returns impl Trait
++#![deny(warnings)]
++
++use mockall::*;
++
++pub trait Foo {}
++
++pub struct A{}
++
++struct Bar {}
++impl Foo for Bar {}
++
++#[automock]
++impl A {
++ pub fn build() -> impl Foo {
++ Bar{}
++ }
++}
++
++#[test]
++fn returning() {
++ let ctx = MockA::build_context();
++ ctx.expect().returning(|| {
++ struct Baz {}
++ impl Foo for Baz {}
++ Box::new(Baz{})
++ });
++ let _a = MockA::build();
++}
+diff --git a/tests/automock_constructor_in_generic_trait.rs b/tests/automock_constructor_in_generic_trait.rs
+new file mode 100644
+index 0000000..550fcb3
+--- /dev/null
++++ b/tests/automock_constructor_in_generic_trait.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! A generic trait with a non-generic constructor method.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo<T: 'static> {
++ fn new(t: T) -> Self;
++}
++
++#[test]
++fn return_once() {
++ let mock = MockFoo::<u32>::default();
++
++ let ctx = MockFoo::<u32>::new_context();
++ ctx.expect()
++ .return_once(move |_| mock);
++
++ let _mock = MockFoo::new(5u32);
++}
+diff --git a/tests/automock_constructor_in_struct.rs b/tests/automock_constructor_in_struct.rs
+new file mode 100644
+index 0000000..1c3a895
+--- /dev/null
++++ b/tests/automock_constructor_in_struct.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! A struct with a constructor method
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct A {}
++
++#[automock]
++#[allow(clippy::new_without_default)]
++impl A {
++ pub fn new() -> Self {
++ unimplemented!()
++ }
++}
++
++#[test]
++fn returning() {
++ let ctx = MockA::new_context();
++ ctx.expect().returning(MockA::default);
++ let _a: MockA = MockA::new();
++}
+diff --git a/tests/automock_constructor_in_trait.rs b/tests/automock_constructor_in_trait.rs
+new file mode 100644
+index 0000000..1bd0189
+--- /dev/null
++++ b/tests/automock_constructor_in_trait.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++//! A trait with a constructor method
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub trait A {
++ fn new() -> Self;
++}
++
++#[test]
++fn returning() {
++ let ctx = MockA::new_context();
++ ctx.expect().returning(MockA::default);
++ let _a: MockA = <MockA as A>::new();
++}
+diff --git a/tests/automock_constructor_in_trait_with_args.rs b/tests/automock_constructor_in_trait_with_args.rs
+new file mode 100644
+index 0000000..f7373ba
+--- /dev/null
++++ b/tests/automock_constructor_in_trait_with_args.rs
+@@ -0,0 +1,23 @@
++// vim: tw=80
++//! A struct with a constructor method named "new" that has arguments.
++//! mockall should mock the provided method, and not autogenerate a 0-argument
++//! "new" method.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo {
++ fn new(x: u32) -> Self;
++}
++
++#[test]
++fn return_once() {
++ let mock = MockFoo::default();
++ let ctx = MockFoo::new_context();
++
++ ctx.expect()
++ .return_once(|_| mock);
++
++ let _mock = MockFoo::new(5);
++}
+diff --git a/tests/automock_constructor_with_args.rs b/tests/automock_constructor_with_args.rs
+new file mode 100644
+index 0000000..5a6f563
+--- /dev/null
++++ b/tests/automock_constructor_with_args.rs
+@@ -0,0 +1,25 @@
++// vim: tw=80
++//! A struct with a constructor method named "new" that has arguments.
++//! mockall should mock the provided method, and not autogenerate a 0-argument
++//! "new" method.
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct Foo{}
++
++#[automock]
++impl Foo {
++ pub fn new(_x: u32) -> Self {unimplemented!()}
++}
++
++#[test]
++fn return_once() {
++ let mock = MockFoo::default();
++ let ctx = MockFoo::new_context();
++
++ ctx.expect()
++ .return_once(|_| mock);
++
++ let _mock = MockFoo::new(5);
++}
+diff --git a/tests/automock_consume_arguments.rs b/tests/automock_consume_arguments.rs
+new file mode 100644
+index 0000000..eb47fe8
+--- /dev/null
++++ b/tests/automock_consume_arguments.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++struct NonCopy{}
++
++#[automock]
++trait T {
++ fn foo(&self, x: NonCopy);
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockT::new();
++ mock.expect_foo()
++ .returning(|_x: NonCopy| ());
++ mock.foo(NonCopy{});
++}
+diff --git a/tests/automock_custom_result.rs b/tests/automock_custom_result.rs
+new file mode 100644
+index 0000000..89f7591
+--- /dev/null
++++ b/tests/automock_custom_result.rs
+@@ -0,0 +1,42 @@
++// vim: tw=80
++//! It should be possible to use a custom Result type in the signature of a
++//! mocked method. Regression test for
++//! https://github.com/asomers/mockall/issues/73
++#![deny(warnings)]
++
++use mockall::*;
++
++pub type Result<T> = std::result::Result<T, String>;
++
++pub struct MyStruct {}
++
++#[automock]
++impl MyStruct {
++ pub fn ret_static(&self) -> Result<i32> { unimplemented!() }
++ pub fn ret_ref(&self) -> &Result<i32> { unimplemented!() }
++ pub fn ret_refmut(&mut self) -> &mut Result<i32> { unimplemented!() }
++}
++
++#[test]
++fn ret_ref() {
++ let mut s = MockMyStruct::new();
++ s.expect_ret_ref()
++ .return_const(Ok(42));
++ assert_eq!(Ok(42), *s.ret_ref());
++}
++
++#[test]
++fn ret_ref_mut() {
++ let mut s = MockMyStruct::new();
++ s.expect_ret_refmut()
++ .return_var(Ok(42));
++ assert_eq!(Ok(42), *s.ret_refmut());
++}
++
++#[test]
++fn ret_static() {
++ let mut s = MockMyStruct::new();
++ s.expect_ret_static()
++ .return_const(Ok(42));
++ assert_eq!(Ok(42), s.ret_static());
++}
+diff --git a/tests/automock_debug.rs b/tests/automock_debug.rs
+new file mode 100644
+index 0000000..6341c75
+--- /dev/null
++++ b/tests/automock_debug.rs
+@@ -0,0 +1,35 @@
++// vim: tw=80
++//! A mocked struct should implement Debug
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub trait Foo {}
++
++pub trait Bar {}
++pub struct Baz {}
++#[automock]
++impl Bar for Baz{}
++
++pub struct Bean {}
++#[automock]
++impl Bean{}
++
++#[test]
++fn automock_trait() {
++ let foo = MockFoo::new();
++ assert_eq!("MockFoo", format!("{foo:?}"));
++}
++
++#[test]
++fn automock_struct_impl() {
++ let bean = MockBean::new();
++ assert_eq!("MockBean", format!("{bean:?}"));
++}
++
++#[test]
++fn automock_trait_impl() {
++ let baz = MockBaz::new();
++ assert_eq!("MockBaz", format!("{baz:?}"));
++}
+diff --git a/tests/automock_deref.rs b/tests/automock_deref.rs
+new file mode 100644
+index 0000000..61c55b3
+--- /dev/null
++++ b/tests/automock_deref.rs
+@@ -0,0 +1,74 @@
++// vim: tw=80
++//! A method that returns a type which is a common target for std::ops::Deref
++#![deny(warnings)]
++
++use mockall::*;
++use std::{
++ ffi::{CStr, CString, OsStr, OsString},
++ path::{Path, PathBuf},
++};
++
++#[automock]
++trait Foo {
++ fn name(&self) -> &CStr;
++ fn alias(&self) -> &str;
++ fn desc(&self) -> &OsStr;
++ fn path(&self) -> &Path;
++ fn text(&self) -> &'static str;
++ fn slice(&self) -> &[i32];
++}
++
++mod return_const {
++ use super::*;
++
++ #[test]
++ fn cstr() {
++ let mut mock = MockFoo::new();
++ let name = CString::new("abcd").unwrap();
++ mock.expect_name().return_const(name.clone());
++ assert_eq!(name.as_c_str(), mock.name());
++ }
++
++ #[test]
++ fn osstr() {
++ let mut mock = MockFoo::new();
++ let desc = OsString::from("abcd");
++ mock.expect_desc().return_const(desc.clone());
++ assert_eq!(desc.as_os_str(), mock.desc());
++ }
++
++ #[test]
++ fn path() {
++ let mut mock = MockFoo::new();
++ let mut pb = PathBuf::new();
++ pb.push("foo");
++ pb.push("bar");
++ pb.push("baz");
++ mock.expect_path().return_const(pb.clone());
++ assert_eq!(pb.as_path(), mock.path());
++ }
++
++ #[test]
++ fn str() {
++ let mut mock = MockFoo::new();
++ mock.expect_alias().return_const("abcd".to_owned());
++ assert_eq!("abcd", mock.alias());
++ }
++
++ #[allow(clippy::redundant_static_lifetimes)]
++ #[test]
++ fn static_str() {
++ const TEXT: &'static str = "abcd";
++ let mut mock = MockFoo::new();
++ mock.expect_text().return_const(TEXT);
++ assert_eq!("abcd", mock.text());
++ }
++
++ #[test]
++ fn slice() {
++ let r = vec![1, 2, 3];
++ let mut mock = MockFoo::new();
++ mock.expect_slice().return_const(r);
++ assert_eq!(&[1, 2, 3], mock.slice());
++ }
++}
+diff --git a/tests/automock_extern_std.rs b/tests/automock_extern_std.rs
+new file mode 100644
+index 0000000..3b67c68
+--- /dev/null
++++ b/tests/automock_extern_std.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++//! automocking a trait when std is only an extern crate (eg., as a testing
++//! support mod for a no_std library). This setup requires some extra "use"s
++//! to make, eg., Box, available.
++
++#![no_std]
++extern crate std;
++
++use mockall::*;
++
++#[automock]
++pub trait SimpleTrait {
++ fn foo(&self, x: u32) -> u32;
++}
++
++#[test]
++fn creating() {
++ let _ = MockSimpleTrait::new();
++}
+diff --git a/tests/automock_foreign_c.rs b/tests/automock_foreign_c.rs
+new file mode 100644
+index 0000000..07eb47d
+--- /dev/null
++++ b/tests/automock_foreign_c.rs
+@@ -0,0 +1,52 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++use std::sync::Mutex;
++
++#[automock]
++mod ffi {
++ extern "C" {
++ pub(super) fn foo(x: u32) -> i64;
++ }
++}
++
++static FOO_MTX: Mutex<()> = Mutex::new(());
++
++// Ensure we can still use the original mocked function
++pub fn normal_usage() {
++ let _m = FOO_MTX.lock();
++ unsafe {
++ ffi::foo(42);
++ }
++}
++
++#[test]
++#[should_panic(expected = "mock_ffi::foo(5): No matching expectation found")]
++fn with_no_matches() {
++ let _m = FOO_MTX.lock();
++ let ctx = mock_ffi::foo_context();
++ ctx.expect()
++ .with(predicate::eq(4))
++ .returning(i64::from);
++ unsafe{ mock_ffi::foo(5) };
++}
++
++#[test]
++fn returning() {
++ let _m = FOO_MTX.lock();
++ let ctx = mock_ffi::foo_context();
++ ctx.expect().returning(i64::from);
++ assert_eq!(42, unsafe{mock_ffi::foo(42)});
++}
++
++/// Ensure that the mock function can be called from C by casting it to a C
++/// function pointer.
++#[test]
++fn c_abi() {
++ let _m = FOO_MTX.lock();
++ let ctx = mock_ffi::foo_context();
++ ctx.expect().returning(i64::from);
++ let p: unsafe extern "C" fn(u32) -> i64 = mock_ffi::foo;
++ assert_eq!(42, unsafe{p(42)});
++}
+diff --git a/tests/automock_foreign_c_variadic.rs b/tests/automock_foreign_c_variadic.rs
+new file mode 100644
+index 0000000..71a62ed
+--- /dev/null
++++ b/tests/automock_foreign_c_variadic.rs
+@@ -0,0 +1,23 @@
++// vim: tw=80
++#![cfg_attr(feature = "nightly", feature(c_variadic))]
++#![deny(warnings)]
++
++#[cfg(feature = "nightly")]
++use mockall::*;
++
++#[automock]
++#[cfg(feature = "nightly")]
++pub mod ffi {
++ extern "C" {
++ pub fn foo(x: i32, y: i32, ...) -> i32;
++ }
++}
++
++#[test]
++#[cfg(feature = "nightly")]
++#[cfg_attr(miri, ignore)]
++fn mocked_c_variadic() {
++ let ctx = mock_ffi::foo_context();
++ ctx.expect().returning(|x, y| x * y);
++ assert_eq!(6, unsafe{mock_ffi::foo(2, 3, 1, 4, 1)});
++}
+diff --git a/tests/automock_foreign_rust.rs b/tests/automock_foreign_rust.rs
+new file mode 100644
+index 0000000..ccc7ee5
+--- /dev/null
++++ b/tests/automock_foreign_rust.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub mod ffi {
++ extern "Rust" {
++ pub fn foo(_x: u32) -> i64;
++ }
++}
++
++#[test]
++fn returning() {
++ let ctx = mock_ffi::foo_context();
++ ctx.expect().returning(i64::from);
++ assert_eq!(42, unsafe{mock_ffi::foo(42)});
++}
+diff --git a/tests/automock_gat.rs b/tests/automock_gat.rs
+new file mode 100644
+index 0000000..4fd4938
+--- /dev/null
++++ b/tests/automock_gat.rs
+@@ -0,0 +1,35 @@
++#! vim: tw=80
++//! automock a trait with Generic Associated Types
++#![deny(warnings)]
++
++use cfg_if::cfg_if;
++
++cfg_if! {
++ if #[cfg(feature = "nightly")] {
++ use mockall::*;
++
++ // The lifetime must have the same name as in the next() method.
++ #[automock(type Item=&'a u32;)]
++ trait LendingIterator {
++ type Item<'a> where Self: 'a;
++
++ // Clippy doesn't know that Mockall will need the lifetime when it
++ // expands the macro.
++ #[allow(clippy::needless_lifetimes)]
++ fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>;
++ }
++
++ // It isn't possible to safely set an expectation for a non-'static
++ // return value (because the mock object doesn't have any lifetime
++ // parameters itself), but unsafely setting such an expectation is a
++ // common use case.
++ #[test]
++ fn return_const() {
++ let mut mock = MockLendingIterator::new();
++ let x = 42u32;
++ let xstatic: &'static u32 = unsafe{ std::mem::transmute(&x) };
++ mock.expect_next().return_const(Some(xstatic));
++ assert_eq!(42u32, *mock.next().unwrap());
++ }
++ }
++}
+diff --git a/tests/automock_generic_arguments.rs b/tests/automock_generic_arguments.rs
+new file mode 100644
+index 0000000..5b8a9e6
+--- /dev/null
++++ b/tests/automock_generic_arguments.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! generic methods with generic arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++ fn foo<T: 'static>(&self, t: T);
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockA::new();
++ mock.expect_foo::<u32>()
++ .returning(|_x: u32| ());
++ mock.expect_foo::<i16>()
++ .returning(|_x: i16| ());
++ mock.foo(5u32);
++ mock.foo(-1i16);
++}
+diff --git a/tests/automock_generic_arguments_returning_references.rs b/tests/automock_generic_arguments_returning_references.rs
+new file mode 100644
+index 0000000..de1f5c1
+--- /dev/null
++++ b/tests/automock_generic_arguments_returning_references.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++//! generic methods with generic arguments returning immutable references
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++ fn foo<T: 'static>(&self, t: T) -> &u32;
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockA::new();
++ mock.expect_foo::<u32>().return_const(5);
++ assert_eq!(5, *mock.foo(42u32));
++}
+diff --git a/tests/automock_generic_arguments_with_where_clause.rs b/tests/automock_generic_arguments_with_where_clause.rs
+new file mode 100644
+index 0000000..2d619d9
+--- /dev/null
++++ b/tests/automock_generic_arguments_with_where_clause.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! A method with generic arguments bounded by a where clause
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++ fn foo<T>(&self, t: T) where T: Clone + 'static;
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockA::new();
++ mock.expect_foo::<u32>()
++ .returning(|_x: u32| ());
++ mock.expect_foo::<i16>()
++ .returning(|_x: i16| ());
++ mock.foo(5u32);
++ mock.foo(-1i16);
++}
+diff --git a/tests/automock_generic_constructor.rs b/tests/automock_generic_constructor.rs
+new file mode 100644
+index 0000000..d9f7286
+--- /dev/null
++++ b/tests/automock_generic_constructor.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++//! A non-generic struct can have a generic constructor method
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo {
++ fn build<T: 'static>(t: T) -> Self;
++}
++
++#[test]
++fn returning_once() {
++ let ctx = MockFoo::build_context();
++ ctx.expect::<i16>()
++ .return_once(|_| MockFoo::default());
++
++ let _mock: MockFoo = MockFoo::build::<i16>(-1);
++}
+diff --git a/tests/automock_generic_future.rs b/tests/automock_generic_future.rs
+new file mode 100644
+index 0000000..de26d92
+--- /dev/null
++++ b/tests/automock_generic_future.rs
+@@ -0,0 +1,36 @@
++// vim: tw=80
++//! A generic mock object that implements Future
++//!
++//! This is tricky because the Context object has a lifetime parameter, yet the
++//! poll method must not be treated as a generic method.
++#![deny(warnings)]
++
++use futures::executor::block_on;
++use mockall::*;
++use std::{
++ future::Future,
++ pin::Pin,
++ task::{Context, Poll},
++};
++
++struct Foo<T>(T);
++
++#[automock]
++impl<T> Future for Foo<T> {
++ type Output = ();
++
++ fn poll<'a>(self: Pin<&mut Self>, _cx: &mut Context<'a>)
++ -> Poll<Self::Output>
++ {
++ unimplemented!()
++ }
++}
++
++#[test]
++fn ready() {
++ let mut mock = MockFoo::<u32>::new();
++ mock.expect_poll()
++ .once()
++ .return_const(Poll::Ready(()));
++ block_on(mock);
++}
+diff --git a/tests/automock_generic_future_with_where_clause.rs b/tests/automock_generic_future_with_where_clause.rs
+new file mode 100644
+index 0000000..45e80d8
+--- /dev/null
++++ b/tests/automock_generic_future_with_where_clause.rs
+@@ -0,0 +1,36 @@
++// vim: tw=80
++//! A generic mock object with a method that has only lifetime generic
++//! parameters, and a where clause that bounds a generic type not used by the
++//! method.
++//!
++//! Mockall must not emit the where clause for the method's Expectation.
++#![deny(warnings)]
++#![allow(clippy::needless_lifetimes)]
++
++use mockall::*;
++
++struct Foo<T, V>((T, V));
++trait MyTrait {
++ type Item;
++
++ fn myfunc(&self, cx: &NonStatic) -> Self::Item;
++}
++#[allow(dead_code)]
++pub struct NonStatic<'ns>(&'ns i32);
++
++#[automock]
++impl<T, V> MyTrait for Foo<T, V> where T: Clone {
++ type Item = V;
++
++ fn myfunc<'a>(&self, _cx: &NonStatic<'a>) -> V { unimplemented!() }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::<u32, u32>::new();
++ let x = 5i32;
++ let ns = NonStatic(&x);
++ mock.expect_myfunc()
++ .return_const(42u32);
++ assert_eq!(42u32, mock.myfunc(&ns));
++}
+diff --git a/tests/automock_generic_method_with_bounds.rs b/tests/automock_generic_method_with_bounds.rs
+new file mode 100644
+index 0000000..6bc68b1
+--- /dev/null
++++ b/tests/automock_generic_method_with_bounds.rs
+@@ -0,0 +1,23 @@
++// vim: tw=80
++//! generic methods with bounds on their generic parameters
++#![deny(warnings)]
++
++use mockall::*;
++use std::fmt::Debug;
++
++struct X<T: Debug>(T);
++
++#[automock]
++trait Foo {
++ fn foo<T: Debug + 'static>(&self, x: X<T>);
++}
++
++#[test]
++fn withf() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<u32>()
++ .withf(|x| x.0 == 42u32)
++ .return_const(());
++
++ mock.foo(X(42u32));
++}
+diff --git a/tests/automock_generic_method_with_lifetime_parameter.rs b/tests/automock_generic_method_with_lifetime_parameter.rs
+new file mode 100644
+index 0000000..0c1b65d
+--- /dev/null
++++ b/tests/automock_generic_method_with_lifetime_parameter.rs
+@@ -0,0 +1,48 @@
++// vim: tw=80
++//! A generic method whose only generic parameter is a lifetime parameter is,
++//! from Mockall's perspective, pretty much the same as a non-generic method.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[derive(Debug, Eq)]
++struct X<'a>(&'a u32);
++
++impl<'a> PartialEq for X<'a> {
++ fn eq(&self, other: &X<'a>) -> bool {
++ self.0 == other.0
++ }
++}
++
++#[automock]
++trait Foo {
++ fn foo<'a>(&self, x: &'a X<'a>) -> u32;
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .return_const(42u32);
++ let x = X(&5);
++ assert_eq!(42, mock.foo(&x));
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|f| *f.0);
++ let x = X(&5);
++ assert_eq!(5, mock.foo(&x));
++}
++
++#[test]
++fn withf() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .withf(|f| *f.0 == 5)
++ .return_const(42u32);
++ let x = X(&5);
++ assert_eq!(42, mock.foo(&x));
++}
+diff --git a/tests/automock_generic_method_with_unknown_size_bounds.rs b/tests/automock_generic_method_with_unknown_size_bounds.rs
+new file mode 100644
+index 0000000..4182b2e
+--- /dev/null
++++ b/tests/automock_generic_method_with_unknown_size_bounds.rs
+@@ -0,0 +1,34 @@
++// vim: tw=80
++//! generic methods with unknown size bounds on their generic parameters
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo {
++ fn foo<T: 'static + ?Sized>(&self, input: Box<T>);
++}
++
++trait Bar {
++ fn get(&self) -> u32;
++}
++
++struct Foobar {
++ value: u32,
++}
++
++impl Bar for Foobar {
++ fn get(&self) -> u32 {
++ self.value
++ }
++}
++
++#[test]
++fn withf() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<dyn Bar>()
++ .withf(|x| x.get() == 42)
++ .return_const(());
++
++ mock.foo::<dyn Bar>(Box::new(Foobar { value: 42 }));
++}
+diff --git a/tests/automock_generic_method_without_generic_args_or_return.rs b/tests/automock_generic_method_without_generic_args_or_return.rs
+new file mode 100644
+index 0000000..63b297b
+--- /dev/null
++++ b/tests/automock_generic_method_without_generic_args_or_return.rs
+@@ -0,0 +1,44 @@
++// vim: tw=80
++//! generic methods whose generic parameters appear in neither inputs nor return
++//! types should still be mockable, and it should be possible to set
++//! simultaneous expectations for different generic types on the same object.
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct Foo{}
++
++#[automock]
++impl Foo {
++ #[allow(clippy::extra_unused_type_parameters)]
++ pub fn foo<T: 'static>(&self) -> i32 {
++ unimplemented!()
++ }
++ /// A static method
++ #[allow(clippy::extra_unused_type_parameters)]
++ pub fn bar<T: 'static>() -> i32 {
++ unimplemented!()
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<f32>()
++ .return_const(42);
++ mock.expect_foo::<f64>()
++ .return_const(69);
++ assert_eq!(42, mock.foo::<f32>());
++ assert_eq!(69, mock.foo::<f64>());
++}
++
++#[test]
++fn static_method() {
++ let ctx = MockFoo::bar_context();
++ ctx.expect::<f32>()
++ .return_const(42);
++ ctx.expect::<f64>()
++ .return_const(69);
++ assert_eq!(42, MockFoo::bar::<f32>());
++ assert_eq!(69, MockFoo::bar::<f64>());
++}
+diff --git a/tests/automock_generic_return.rs b/tests/automock_generic_return.rs
+new file mode 100644
+index 0000000..9ea8944
+--- /dev/null
++++ b/tests/automock_generic_return.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! generic methods with generic return values
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++ fn foo<T: 'static>(&self, t: T) -> T;
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockA::new();
++ mock.expect_foo::<u32>()
++ .returning(|_x: u32| 42u32);
++ mock.expect_foo::<i16>()
++ .returning(|_x: i16| 42i16);
++ assert_eq!(42u32, mock.foo(5u32));
++ assert_eq!(42i16, mock.foo(-1i16));
++}
+diff --git a/tests/automock_generic_static_method.rs b/tests/automock_generic_static_method.rs
+new file mode 100644
+index 0000000..3afc95e
+--- /dev/null
++++ b/tests/automock_generic_static_method.rs
+@@ -0,0 +1,33 @@
++// vim: tw=80
++//! generic static methods with generic arguments
++#![deny(warnings)]
++
++use mockall::*;
++use std::sync::Mutex;
++
++static A_MTX: Mutex<()> = Mutex::new(());
++
++#[automock]
++trait A {
++ fn bar<T: 'static>(t: T) -> u32;
++}
++
++#[test]
++fn returning() {
++ let _m = A_MTX.lock().unwrap();
++
++ let ctx = MockA::bar_context();
++ ctx.expect::<i16>()
++ .returning(|_| 42);
++ assert_eq!(42, MockA::bar(-1i16));
++}
++
++#[test]
++fn return_const() {
++ let _m = A_MTX.lock().unwrap();
++
++ let ctx = MockA::bar_context();
++ ctx.expect::<i16>()
++ .return_const(42u32);
++ assert_eq!(42, MockA::bar(-1i16));
++}
+diff --git a/tests/automock_generic_struct.rs b/tests/automock_generic_struct.rs
+new file mode 100644
+index 0000000..2efaba3
+--- /dev/null
++++ b/tests/automock_generic_struct.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++//! generic structs
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct GenericStruct<T, V> {
++ _t: T,
++ _v: V
++}
++#[automock]
++impl<T, V> GenericStruct<T, V> {
++ pub fn foo(&self, _x: u32) -> i64 {
++ 42
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockGenericStruct::<u8, i8>::new();
++ mock.expect_foo()
++ .returning(|x| i64::from(x) + 1);
++ assert_eq!(5, mock.foo(4));
++}
+diff --git a/tests/automock_generic_struct_with_bounds.rs b/tests/automock_generic_struct_with_bounds.rs
+new file mode 100644
+index 0000000..b7ba3b4
+--- /dev/null
++++ b/tests/automock_generic_struct_with_bounds.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++//! generic structs with bounds on their generic parameters
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct GenericStruct<T: Copy, V: Clone> {
++ _t: T,
++ _v: V
++}
++#[automock]
++impl<T: Copy + Copy, V: Clone + Copy> GenericStruct<T, V> {
++ pub fn foo(&self, _x: u32) -> i64 {
++ 42
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockGenericStruct::<u8, i8>::new();
++ mock.expect_foo()
++ .returning(|x| i64::from(x) + 1);
++ assert_eq!(5, mock.foo(4));
++}
+diff --git a/tests/automock_generic_struct_with_static_method.rs b/tests/automock_generic_struct_with_static_method.rs
+new file mode 100644
+index 0000000..1410113
+--- /dev/null
++++ b/tests/automock_generic_struct_with_static_method.rs
+@@ -0,0 +1,20 @@
++// vim: tw=80
++//! static non-generic methods of generic structs shouldn't require any special
++//! treatment when mocking. Prior to version 0.3.0, the struct's generic
++//! parameters had to be duplicated as generic parameters of the method.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo<T: 'static> {
++ fn foo(t: T);
++}
++
++#[test]
++fn returning() {
++ let ctx = MockFoo::<u32>::foo_context();
++ ctx.expect()
++ .returning(|_| ());
++ MockFoo::foo(42u32);
++}
+diff --git a/tests/automock_generic_struct_with_where_clause.rs b/tests/automock_generic_struct_with_where_clause.rs
+new file mode 100644
+index 0000000..f62996f
+--- /dev/null
++++ b/tests/automock_generic_struct_with_where_clause.rs
+@@ -0,0 +1,26 @@
++// vim: tw=80
++//! A struct with generic parameters bounded by a where clause
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct GenericStruct<T> {
++ _t: T,
++}
++#[automock]
++impl<T> GenericStruct<T>
++ where T: Clone + Default
++{
++ #[allow(clippy::redundant_clone)]
++ pub fn foo(&self, x: T) -> T {
++ x.clone()
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockGenericStruct::<u8>::default();
++ mock.expect_foo()
++ .returning(|x| x);
++ assert_eq!(4, mock.foo(4u8));
++}
+diff --git a/tests/automock_generic_trait.rs b/tests/automock_generic_trait.rs
+new file mode 100644
+index 0000000..499ef08
+--- /dev/null
++++ b/tests/automock_generic_trait.rs
+@@ -0,0 +1,30 @@
++// vim: tw=80
++//! generic traits
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A<T> {
++ fn foo(&self, t: T);
++ fn bar(&self) -> T;
++}
++
++#[test]
++fn generic_arguments() {
++ let mut mock = MockA::<u32>::new();
++ mock.expect_foo()
++ .with(mockall::predicate::eq(16u32))
++ .once()
++ .returning(|_| ());
++ mock.foo(16u32);
++}
++
++#[test]
++fn generic_return() {
++ let mut mock = MockA::<u32>::new();
++ mock.expect_bar()
++ .returning(|| 42u32);
++ assert_eq!(42u32, mock.bar());
++}
++
+diff --git a/tests/automock_generic_trait_with_bounds.rs b/tests/automock_generic_trait_with_bounds.rs
+new file mode 100644
+index 0000000..a99e824
+--- /dev/null
++++ b/tests/automock_generic_trait_with_bounds.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++//! generic traits with bounds on the generic parameters
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A<T: Copy> {
++ fn foo(&self);
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockA::<u32>::new();
++ mock.expect_foo()
++ .returning(|| ());
++ mock.foo();
++}
+diff --git a/tests/automock_generic_trait_with_where_clause.rs b/tests/automock_generic_trait_with_where_clause.rs
+new file mode 100644
+index 0000000..e12be15
+--- /dev/null
++++ b/tests/automock_generic_trait_with_where_clause.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++//! A trait with generic parameters bounded by a where clause
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo<T> where T: Clone + Copy {
++ fn foo(&self);
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::<u8>::default();
++ mock.expect_foo()
++ .returning(|| ());
++ mock.foo();
++}
+diff --git a/tests/automock_impl_future.rs b/tests/automock_impl_future.rs
+new file mode 100644
+index 0000000..26086af
+--- /dev/null
++++ b/tests/automock_impl_future.rs
+@@ -0,0 +1,50 @@
++// vim: tw=80
++//! A trait with a constructor method that returns impl Future<...>.
++//!
++//! This needs special handling, because Box<dyn Future<...>> is pretty useless.
++//! You need Pin<Box<dyn Future<...>>> instead.
++#![deny(warnings)]
++
++use futures::{Future, FutureExt, Stream, StreamExt, future, stream};
++use mockall::*;
++
++pub struct Foo{}
++
++#[automock]
++impl Foo {
++ pub fn foo(&self) -> impl Future<Output=u32>
++ {
++ future::ready(42)
++ }
++
++ pub fn bar(&self) -> impl Stream<Item=u32>
++ {
++ stream::empty()
++ }
++}
++
++#[test]
++fn returning_future() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|| {
++ Box::pin(future::ready(42))
++ });
++ mock.foo()
++ .now_or_never()
++ .unwrap();
++}
++
++#[test]
++fn returning_stream() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .returning(|| {
++ Box::pin(stream::iter(vec![42]))
++ });
++ let all = mock.bar()
++ .collect::<Vec<u32>>()
++ .now_or_never()
++ .unwrap();
++ assert_eq!(&all[..], &[42][..]);
++}
+diff --git a/tests/automock_impl_generic_trait_for.rs b/tests/automock_impl_generic_trait_for.rs
+new file mode 100644
+index 0000000..6bd218a
+--- /dev/null
++++ b/tests/automock_impl_generic_trait_for.rs
+@@ -0,0 +1,28 @@
++// vim: tw=80
++//! A generic struct that implements a generic trait
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo<T> {
++ fn foo(&self, t: T) -> T;
++}
++
++pub struct SomeStruct<T> {
++ _t: std::marker::PhantomData<T>
++}
++
++#[automock]
++impl<T> Foo<T> for SomeStruct<T> {
++ fn foo(&self, t: T) -> T {
++ t
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockSomeStruct::<u32>::new();
++ mock.expect_foo()
++ .returning(|t| t);
++ assert_eq!(4, <MockSomeStruct<u32> as Foo<u32>>::foo(&mock, 4));
++}
+diff --git a/tests/automock_impl_trait.rs b/tests/automock_impl_trait.rs
+new file mode 100644
+index 0000000..eb14a13
+--- /dev/null
++++ b/tests/automock_impl_trait.rs
+@@ -0,0 +1,20 @@
++// vim: tw=80
++//! A method that returns "impl Trait"
++#![deny(warnings)]
++
++use mockall::*;
++use std::fmt::Debug;
++
++pub struct Foo {}
++
++#[automock]
++impl Foo {
++ pub fn foo(&self) -> impl Debug + Send { unimplemented!()}
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo().returning(|| Box::new(4));
++ format!("{:?}", mock.foo());
++}
+diff --git a/tests/automock_impl_trait_for.rs b/tests/automock_impl_trait_for.rs
+new file mode 100644
+index 0000000..6dc153a
+--- /dev/null
++++ b/tests/automock_impl_trait_for.rs
+@@ -0,0 +1,26 @@
++// vim: tw=80
++//! A struct that implements a trait
++#![deny(warnings)]
++
++use mockall::*;
++
++pub trait Foo {
++ fn foo(&self, x: u32) -> i64;
++}
++
++pub struct SomeStruct {}
++
++#[automock]
++impl Foo for SomeStruct {
++ fn foo(&self, _x: u32) -> i64 {
++ 42
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockSomeStruct::new();
++ mock.expect_foo()
++ .returning(|x| i64::from(x) + 1);
++ assert_eq!(5, <MockSomeStruct as Foo>::foo(&mock, 4));
++}
+diff --git a/tests/automock_impl_trait_for_generic.rs b/tests/automock_impl_trait_for_generic.rs
+new file mode 100644
+index 0000000..7d50ef4
+--- /dev/null
++++ b/tests/automock_impl_trait_for_generic.rs
+@@ -0,0 +1,28 @@
++// vim: tw=80
++//! A generic struct that implements a trait
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++ fn foo(&self, x: u32) -> i64;
++}
++
++pub struct SomeStruct<T> {
++ _t: std::marker::PhantomData<T>
++}
++
++#[automock]
++impl<T> Foo for SomeStruct<T> {
++ fn foo(&self, _x: u32) -> i64 {
++ 42
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockSomeStruct::<u32>::new();
++ mock.expect_foo()
++ .returning(|x| i64::from(x) + 1);
++ assert_eq!(5, mock.foo(4));
++}
+diff --git a/tests/automock_impl_trait_with_associated_types_for.rs b/tests/automock_impl_trait_with_associated_types_for.rs
+new file mode 100644
+index 0000000..17bcca7
+--- /dev/null
++++ b/tests/automock_impl_trait_with_associated_types_for.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! A struct implements a trait with associated types
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct Foo {}
++#[automock]
++impl Iterator for Foo {
++ type Item = u32;
++
++ fn next(&mut self) -> Option<Self::Item> {
++ unimplemented!()
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::new();
++ mock.expect_next().returning(|| None);
++ assert!(mock.next().is_none());
++}
+diff --git a/tests/automock_inline.rs b/tests/automock_inline.rs
+new file mode 100644
+index 0000000..6ba2991
+--- /dev/null
++++ b/tests/automock_inline.rs
+@@ -0,0 +1,52 @@
++// vim: tw=80
++//! Mockall should ignore and not emit attributes like "inline" that affect
++//! code generation.
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct Foo {}
++
++#[automock]
++impl Foo {
++ #[inline]
++ pub fn foo(&self) -> i32 {unimplemented!()}
++ #[inline]
++ pub fn bar() -> i32 {unimplemented!()}
++ #[cold]
++ pub fn baz(&self) -> i32 {unimplemented!()}
++ #[cold]
++ pub fn bean() -> i32 {unimplemented!()}
++}
++
++#[test]
++fn inline_method() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .return_const(42i32);
++ assert_eq!(mock.foo(), 42);
++}
++
++#[test]
++fn inline_static_method() {
++ let ctx = MockFoo::bar_context();
++ ctx.expect()
++ .return_const(42i32);
++ assert_eq!(MockFoo::bar(), 42);
++}
++
++#[test]
++fn cold_method() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .return_const(42i32);
++ assert_eq!(mock.baz(), 42);
++}
++
++#[test]
++fn cold_static_method() {
++ let ctx = MockFoo::bean_context();
++ ctx.expect()
++ .return_const(42i32);
++ assert_eq!(MockFoo::bean(), 42);
++}
+diff --git a/tests/automock_instrument.rs b/tests/automock_instrument.rs
+new file mode 100644
+index 0000000..4f210ff
+--- /dev/null
++++ b/tests/automock_instrument.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! A trait that uses tracing::instrument should be automockable. The mock
++//! method won't be instrumented, though.
++#![deny(warnings)]
++
++use mockall::*;
++use tracing::instrument;
++
++#[derive(Debug)]
++pub struct Foo {}
++
++#[automock]
++impl Foo {
++ #[instrument]
++ fn foo(&self) {}
++ #[instrument]
++ fn bar() {}
++ #[tracing::instrument]
++ fn fooz(&self) {}
++ #[tracing::instrument]
++ fn barz() {}
++}
+diff --git a/tests/automock_many_args.rs b/tests/automock_many_args.rs
+new file mode 100644
+index 0000000..8393130
+--- /dev/null
++++ b/tests/automock_many_args.rs
+@@ -0,0 +1,81 @@
++// vim: tw=80
++//! mockall should be able to mock methods with at least 16 arguments
++#![allow(clippy::too_many_arguments)] // Good job, Clippy!
++#![allow(clippy::type_complexity)]
++#![deny(warnings)]
++
++use mockall::{automock, predicate::*};
++
++#[automock]
++trait ManyArgs {
++ fn foo(&self, _a0: u8, _a1: u8, _a2: u8, _a3: u8, _a4: u8, _a5: u8,
++ _a6: u8, _a7: u8, _a8: u8, _a9: u8, _a10: u8, _a11: u8,
++ _a12: u8, _a13: u8, _a14: u8, _a15: u8);
++ fn bar(&self, _a0: u8, _a1: u8, _a2: u8, _a3: u8, _a4: u8, _a5: u8,
++ _a6: u8, _a7: u8, _a8: u8, _a9: u8, _a10: u8, _a11: u8,
++ _a12: u8, _a13: u8, _a14: u8, _a15: u8) -> &u32;
++ fn baz(&mut self, _a0: u8, _a1: u8, _a2: u8, _a3: u8, _a4: u8, _a5: u8,
++ _a6: u8, _a7: u8, _a8: u8, _a9: u8, _a10: u8, _a11: u8,
++ _a12: u8, _a13: u8, _a14: u8, _a15: u8) -> &mut u32;
++ fn bean(_a0: u8, _a1: u8, _a2: u8, _a3: u8, _a4: u8, _a5: u8,
++ _a6: u8, _a7: u8, _a8: u8, _a9: u8, _a10: u8, _a11: u8,
++ _a12: u8, _a13: u8, _a14: u8, _a15: u8);
++}
++
++#[test]
++#[should_panic(
++ expected = "MockManyArgs::foo: Expectation(true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true) called 0 time(s) which is fewer than expected 1"
++)]
++fn not_yet_satisfied() {
++ let mut mock = MockManyArgs::new();
++ mock.expect_foo()
++ .with(always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), )
++ .times(1)
++ .returning(|_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _| ());
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockManyArgs::new();
++ mock.expect_foo()
++ .returning(|_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _| ());
++ mock.foo(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockManyArgs::new();
++ mock.expect_bar()
++ .return_const(42);
++ mock.bar(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
++}
++
++#[test]
++fn return_var() {
++ let mut mock = MockManyArgs::new();
++ mock.expect_baz()
++ .return_var(42);
++ mock.baz(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
++}
++
++#[test]
++fn static_method_returning() {
++ let ctx = MockManyArgs::bean_context();
++ ctx.expect()
++ .returning(|_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _| ());
++ MockManyArgs::bean(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
++}
++
++#[test]
++#[should_panic(
++ expected = "MockManyArgs::foo: Expectation(true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true) called 2 times which is more than the expected 1"
++)]
++fn too_many() {
++ let mut mock = MockManyArgs::new();
++ mock.expect_foo()
++ .with(always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), )
++ .times(1)
++ .returning(|_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _| ());
++ mock.foo(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
++ mock.foo(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
++}
+diff --git a/tests/automock_module.rs b/tests/automock_module.rs
+new file mode 100644
+index 0000000..ddfe53e
+--- /dev/null
++++ b/tests/automock_module.rs
+@@ -0,0 +1,50 @@
++// vim: tw=80
++//! Mocking an entire module of functions
++#![deny(warnings)]
++
++
++pub mod m {
++ use std::sync::Mutex;
++ use mockall::*;
++ type T = u32;
++
++ static BAR_MTX: Mutex<()> = Mutex::new(());
++
++ #[automock]
++ pub mod foo {
++ use super::T;
++ pub fn bar(_x: T) -> i64 {unimplemented!()}
++ // Module functions should be able to use impl Trait, too
++ pub fn baz() -> impl std::fmt::Debug + Send { unimplemented!()}
++ // Module functions can use mutable arguments
++ pub fn bean(mut _x: u32) { unimplemented!() }
++ }
++
++ #[test]
++ #[should_panic(expected = "mock_foo::bar(5): No matching expectation found")]
++ fn with_no_matches() {
++ let _m = BAR_MTX.lock();
++ let ctx = mock_foo::bar_context();
++ ctx.expect()
++ .with(predicate::eq(4))
++ .return_const(0);
++ mock_foo::bar(5);
++ }
++
++ #[test]
++ fn returning() {
++ let _m = BAR_MTX.lock();
++ let ctx = mock_foo::bar_context();
++ ctx.expect()
++ .returning(|x| i64::from(x) + 1);
++ assert_eq!(5, mock_foo::bar(4));
++ }
++
++ #[test]
++ fn impl_trait() {
++ let ctx = mock_foo::baz_context();
++ ctx.expect()
++ .returning(|| Box::new(4));
++ format!("{:?}", mock_foo::baz());
++ }
++}
+diff --git a/tests/automock_module_nonpub.rs b/tests/automock_module_nonpub.rs
+new file mode 100644
+index 0000000..d131197
+--- /dev/null
++++ b/tests/automock_module_nonpub.rs
+@@ -0,0 +1,45 @@
++// vim: tw=80
++//! bare functions can use non-public types, as long as the object's visibility is compatible.
++#![deny(warnings)]
++#![allow(dead_code)]
++
++mod outer {
++ struct SuperT();
++
++ mod inner {
++ use mockall::automock;
++
++ pub(crate) struct PubCrateT();
++ struct PrivT();
++
++ #[automock]
++ mod m {
++ use super::*;
++
++ pub(crate) fn foo(_x: PubCrateT) -> PubCrateT {
++ unimplemented!()
++ }
++ pub(super) fn bar(_x: PrivT) -> PrivT {
++ unimplemented!()
++ }
++ pub(in super::super) fn baz(_x: super::super::SuperT)
++ -> super::super::SuperT
++ {
++ unimplemented!()
++ }
++ pub(in crate::outer) fn bang(_x: crate::outer::SuperT)
++ -> crate::outer::SuperT
++ {
++ unimplemented!()
++ }
++ }
++
++ #[test]
++ fn returning() {
++ let ctx = mock_m::foo_context();
++ ctx.expect()
++ .returning(|x| x);
++ mock_m::foo(PubCrateT());
++ }
++ }
++}
+diff --git a/tests/automock_module_unused_import.rs b/tests/automock_module_unused_import.rs
+new file mode 100644
+index 0000000..7f09b43
+--- /dev/null
++++ b/tests/automock_module_unused_import.rs
+@@ -0,0 +1,26 @@
++// vim: tw=80
++//! Mocking modules should not generated "unused_imports" warnings for imports
++//! used by the bodies of the mocked functions.
++//! https://github.com/asomers/mockall/issues/343
++#![deny(warnings)]
++
++use mockall::automock;
++
++#[automock]
++pub mod foo {
++ use std::convert::TryInto;
++
++ pub fn bar() {
++ let x = 42i32;
++ let _y: u32 = x.try_into().unwrap_or(0);
++ }
++}
++
++#[test]
++fn return_const() {
++ let ctx = mock_foo::bar_context();
++ ctx.expect()
++ .once()
++ .return_const(());
++ mock_foo::bar();
++}
+diff --git a/tests/automock_multiple_lifetime_parameters.rs b/tests/automock_multiple_lifetime_parameters.rs
+new file mode 100644
+index 0000000..8bdae38
+--- /dev/null
++++ b/tests/automock_multiple_lifetime_parameters.rs
+@@ -0,0 +1,15 @@
++// vim: tw=80
++//! Methods with multiple generic lifetime parameters should produce their
++//! generated code deterministically.
++//!
++//! This test is designed to work with "--cfg reprocheck"
++
++#![deny(warnings)]
++#![allow(clippy::needless_lifetimes)]
++
++use mockall::*;
++
++#[automock]
++pub trait Foo {
++ fn foo<'a, 'b, 'c, 'd, 'e, 'f>(&self, x: &'a &'b &'c &'d &'e &'f i32);
++}
+diff --git a/tests/automock_must_use.rs b/tests/automock_must_use.rs
+new file mode 100644
+index 0000000..d661fd4
+--- /dev/null
++++ b/tests/automock_must_use.rs
+@@ -0,0 +1,60 @@
++// vim: tw=80
++//! Mockall should be able to mock #[must_use] methods. The generated code
++//! should contain #[must_use] on the mock method, but not the expect method.
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct Foo {}
++
++#[automock]
++impl Foo {
++ #[must_use]
++ pub fn bloob(&self) -> i32 {unimplemented!()}
++ #[must_use]
++ pub fn blarg() -> i32 {unimplemented!()}
++}
++
++// test that basic code generation works with must_use structs and traits. The
++// exact output will be verified by the unit tests.
++#[must_use]
++pub struct MustUseStruct {}
++#[automock]
++impl MustUseStruct {}
++#[automock]
++#[must_use]
++pub trait MustUseTrait {}
++
++#[test]
++fn must_use_method() {
++ let mut mock = MockFoo::new();
++ mock.expect_bloob()
++ .return_const(42i32);
++ assert_eq!(42, mock.bloob());
++}
++
++#[cfg(feature = "nightly")]
++#[test]
++fn may_not_use_expectation() {
++ let mut mock = MockFoo::new();
++ // This should not produce a "must_use" warning.
++ mock.expect_bloob();
++}
++
++#[test]
++fn must_use_static_method() {
++ let ctx = MockFoo::blarg_context();
++ ctx.expect()
++ .return_const(42i32);
++ assert_eq!(MockFoo::blarg(), 42);
++}
++
++#[cfg(feature = "nightly")]
++#[test]
++fn may_not_use_static_expectation() {
++ let ctx = MockFoo::blarg_context();
++ // This should not produce a "must_use" warning.
++ ctx.expect();
++}
++
++
+diff --git a/tests/automock_mutable_args.rs b/tests/automock_mutable_args.rs
+new file mode 100644
+index 0000000..6bdb5f4
+--- /dev/null
++++ b/tests/automock_mutable_args.rs
+@@ -0,0 +1,34 @@
++// vim: tw=80
++//! A method with mutable arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct Foo {}
++
++#[automock]
++impl Foo {
++ pub fn foo(&self, mut _x: u32) {}
++ pub fn bar(&mut self, _x: i32) -> i32 {0}
++}
++
++#[test]
++fn mutable_self() {
++ let mut mock = MockFoo::new();
++ let mut count = 0;
++ mock.expect_bar()
++ .returning(move |x| {
++ count += x;
++ count
++ });
++ assert_eq!(5, mock.bar(5));
++ assert_eq!(10, mock.bar(5));
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|_| ());
++ mock.foo(42);
++}
+diff --git a/tests/automock_nondebug.rs b/tests/automock_nondebug.rs
+new file mode 100644
+index 0000000..d6e2690
+--- /dev/null
++++ b/tests/automock_nondebug.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! A method may have non-Debug arguments and/or return values.
++#![deny(warnings)]
++
++use mockall::*;
++
++// Don't derive Debug
++pub struct NonDebug{}
++
++#[automock]
++pub trait Foo {
++ fn foo(&self, x: NonDebug);
++}
++
++#[test]
++#[should_panic(expected = "MockFoo::foo(?): No matching expectation found")]
++fn with_no_matches() {
++ let mock = MockFoo::new();
++ mock.foo(NonDebug{});
++}
++
++
+diff --git a/tests/automock_nonpub_methods.rs b/tests/automock_nonpub_methods.rs
+new file mode 100644
+index 0000000..c534858
+--- /dev/null
++++ b/tests/automock_nonpub_methods.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! Using automock on a struct with private methods should not result in any
++//! "dead_code" warnings. Such methods are often private helpers used only by
++//! other public methods.
++#[deny(dead_code)]
++
++pub mod mymod {
++ use mockall::automock;
++
++ pub struct Foo{}
++
++ #[automock]
++ impl Foo {
++ fn private_helper(&self) {}
++ fn static_private_helper() {}
++
++ pub fn pubfunc(&self) {
++ Self::static_private_helper();
++ self.private_helper()
++ }
++ }
++}
+diff --git a/tests/automock_nonsend.rs b/tests/automock_nonsend.rs
+new file mode 100644
+index 0000000..059879f
+--- /dev/null
++++ b/tests/automock_nonsend.rs
+@@ -0,0 +1,146 @@
++// vim: tw=80
++//! A method may have non-Send arguments and/or return values.
++#![deny(warnings)]
++
++use mockall::*;
++// Rc is not Send
++use std::rc::Rc;
++
++// Neither Send nor Clone
++pub struct NonSend(Rc<u32>);
++
++mod normal_method {
++ use super::*;
++
++ #[automock]
++ trait Foo {
++ fn foo(&self, x: Rc<u32>);
++ fn bar(&self) -> Rc<u32>;
++ fn baz(&self) -> NonSend;
++ }
++
++ #[test]
++ fn return_once_st() {
++ let mut mock = MockFoo::new();
++ let r = NonSend(Rc::new(42u32));
++ mock.expect_baz()
++ .return_once_st(move || r);
++ assert_eq!(42, *mock.baz().0);
++ }
++
++ #[test]
++ fn return_const_st() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .return_const_st(Rc::new(43u32));
++ assert_eq!(43, *mock.bar());
++ }
++
++ #[test]
++ fn returning_st() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .returning_st(|| Rc::new(43u32));
++ assert_eq!(43, *mock.bar());
++ }
++
++ #[test]
++ fn withf_st() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .withf_st(|x| **x == 42)
++ .return_const(());
++ mock.foo(Rc::new(42));
++ }
++}
++
++mod ref_method {
++ // ref methods don't have return_once_st because they don't return owned
++ // values, and they don't have returning_st because they don't have
++ // returning. Instead, they only have return_const, which does not require
++ // Send.
++ // fn foo(&self) -> &Rc<u32>;
++}
++
++mod refmut_method {
++ use super::*;
++
++ #[automock]
++ trait Foo {
++ fn foo(&mut self, x: Rc<u32>);
++ fn bar(&mut self) -> &mut Rc<u32>;
++ }
++
++ // refmut methods don't have return_once_st because they don't return owned
++ // values.
++ #[test]
++ fn returning_st() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .returning_st(|| Rc::new(43u32));
++ assert_eq!(43, **mock.bar());
++ }
++
++ #[test]
++ fn withf_st() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .withf_st(|x| **x == 42)
++ .return_const(());
++ mock.foo(Rc::new(42));
++ }
++}
++
++pub mod static_method {
++ use super::*;
++ use std::sync::Mutex;
++
++ static FOO_MTX: Mutex<()> = Mutex::new(());
++ static BAR_MTX: Mutex<()> = Mutex::new(());
++ static BAZ_MTX: Mutex<()> = Mutex::new(());
++
++ #[automock]
++ trait Foo {
++ fn foo(x: Rc<u32>);
++ fn bar() -> Rc<u32>;
++ fn baz() -> NonSend;
++ }
++
++ #[test]
++ fn return_once_st() {
++ let _guard = BAZ_MTX.lock().unwrap();
++ let ctx = MockFoo::baz_context();
++ let r = NonSend(Rc::new(42u32));
++ ctx.expect()
++ .return_once_st(move || r);
++ assert_eq!(42, *MockFoo::baz().0);
++ }
++
++ #[test]
++ fn returning_st() {
++ let _guard = BAR_MTX.lock().unwrap();
++ let ctx = MockFoo::bar_context();
++ ctx.expect()
++ .returning_st(|| Rc::new(42));
++ assert_eq!(42, *MockFoo::bar());
++ }
++
++ #[test]
++ fn return_const_st() {
++ let _guard = BAR_MTX.lock().unwrap();
++ let ctx = MockFoo::bar_context();
++ ctx.expect()
++ .return_const_st(Rc::new(42));
++ assert_eq!(42, *MockFoo::bar());
++ }
++
++ #[test]
++ fn withf_st() {
++ let _guard = FOO_MTX.lock().unwrap();
++ let ctx = MockFoo::foo_context();
++ ctx.expect()
++ .withf_st(|x| **x == 42)
++ .return_const(());
++ MockFoo::foo(Rc::new(42));
++ }
++}
+diff --git a/tests/automock_nonstatic_struct.rs b/tests/automock_nonstatic_struct.rs
+new file mode 100644
+index 0000000..ecb3399
+--- /dev/null
++++ b/tests/automock_nonstatic_struct.rs
+@@ -0,0 +1,53 @@
++// vim: tw=80
++//! Mock a struct with a lifetime parameter
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct NonStaticStruct<'nss> {
++ _x: &'nss i32
++}
++
++#[automock]
++impl<'nss> NonStaticStruct<'nss> {
++ pub fn foo(&self) -> i64 {
++ 42
++ }
++ pub fn bar() -> i64{
++ 42
++ }
++ // XXX Constructors aren't yet supported for non-static Structs
++ //pub fn new(x: &'nss i32) -> Self {
++ //NonStaticStruct{x}
++ //}
++}
++
++#[test]
++fn normal_method() {
++ // This function serves to define a named lifetime
++ #[allow(clippy::trivially_copy_pass_by_ref)]
++ fn has_lt<'a>(_x: &'a i8) {
++ let mut mock = MockNonStaticStruct::<'a>::default();
++ mock.expect_foo()
++ .returning(|| 5);
++ assert_eq!(5, mock.foo());
++ }
++
++ let x = 42i8;
++ has_lt(&x);
++}
++
++#[test]
++fn static_method() {
++ // This function serves to define a named lifetime
++ #[allow(clippy::trivially_copy_pass_by_ref)]
++ fn has_lt<'a>(_x: &'a i8) {
++ let ctx = MockNonStaticStruct::<'a>::bar_context();
++ ctx.expect()
++ .returning(|| 5);
++ assert_eq!(5, MockNonStaticStruct::bar());
++ }
++
++ let x = 42i8;
++ has_lt(&x);
++}
+diff --git a/tests/automock_partial_eq.rs b/tests/automock_partial_eq.rs
+new file mode 100644
+index 0000000..2618b4e
+--- /dev/null
++++ b/tests/automock_partial_eq.rs
+@@ -0,0 +1,39 @@
++// vim: tw=80
++//! Mockall should deselfify `Self` types, even if they aren't named `self`.
++use mockall::*;
++
++mock! {
++ #[derive(Debug)]
++ pub Foo {
++ fn compare(&self, other: &Self) -> bool;
++ }
++ impl PartialEq for Foo {
++ fn eq(&self, other: &Self) -> bool;
++ }
++}
++
++#[test]
++fn inherent_method() {
++ let mut x = MockFoo::default();
++ let mut y = MockFoo::default();
++ x.expect_compare()
++ .return_const(true);
++ y.expect_compare()
++ .return_const(false);
++
++ assert!(x.compare(&y));
++ assert!(!y.compare(&x));
++}
++
++#[test]
++fn trait_method() {
++ let mut x = MockFoo::default();
++ let mut y = MockFoo::default();
++ x.expect_eq()
++ .return_const(true);
++ y.expect_eq()
++ .return_const(false);
++
++ assert_eq!(x, y);
++ assert!(y != x);
++}
+diff --git a/tests/automock_qself.rs b/tests/automock_qself.rs
+new file mode 100644
+index 0000000..2b10034
+--- /dev/null
++++ b/tests/automock_qself.rs
+@@ -0,0 +1,54 @@
++// vim: tw=80
++//! Using QSelf in an argument, a where clause, or a return type
++#![deny(warnings)]
++
++use mockall::*;
++
++pub trait Foo {
++ type Output;
++}
++
++pub struct SendFoo {}
++impl Foo for SendFoo {
++ type Output = u32;
++}
++
++pub struct A{}
++#[automock]
++impl A {
++ pub fn foo<T: Foo + 'static>(&self, _q: <T as Foo>::Output) {
++ }
++ pub fn bar<T: Foo + 'static>(&self, _t: T) -> <T as Foo>::Output {
++ unimplemented!()
++ }
++ pub fn bean<T>(&self, _t: T)
++ where T: Foo + 'static,
++ <T as Foo>::Output: Send
++ {
++ }
++}
++
++#[test]
++fn arguments() {
++ let mut mock = MockA::new();
++ mock.expect_foo::<SendFoo>()
++ .with(predicate::eq(42u32))
++ .return_const(());
++ mock.foo::<SendFoo>(42u32);
++}
++
++#[test]
++fn where_clause() {
++ let mut mock = MockA::new();
++ mock.expect_bean::<SendFoo>()
++ .return_const(());
++ mock.bean(SendFoo{});
++}
++
++#[test]
++fn return_value() {
++ let mut mock = MockA::new();
++ mock.expect_bar::<SendFoo>()
++ .return_const(42u32);
++ assert_eq!(42, mock.bar(SendFoo{}));
++}
+diff --git a/tests/automock_refmut_arguments.rs b/tests/automock_refmut_arguments.rs
+new file mode 100644
+index 0000000..d65a00e
+--- /dev/null
++++ b/tests/automock_refmut_arguments.rs
+@@ -0,0 +1,23 @@
++// vim: tw=80
++//! A method that takes mutable reference arguments, returning information
++//! through its arguments like C functions often do.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait T {
++ fn foo(&self, x: &mut u32);
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockT::new();
++ let mut x = 5;
++ mock.expect_foo()
++ .returning(|x: &mut u32| {
++ *x = 42;
++ });
++ mock.foo(&mut x);
++ assert_eq!(42, x);
++}
+diff --git a/tests/automock_return_mutable_ref.rs b/tests/automock_return_mutable_ref.rs
+new file mode 100644
+index 0000000..705a3eb
+--- /dev/null
++++ b/tests/automock_return_mutable_ref.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! A method that returns a mutable reference
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++ fn foo(&mut self) -> &mut u32;
++}
++
++#[test]
++fn return_var() {
++ let mut mock = MockA::new();
++ mock.expect_foo().return_var(5);
++ {
++ let r = mock.foo();
++ assert_eq!(5, *r);
++ *r = 6;
++ }
++ assert_eq!(6, *mock.foo());
++}
+diff --git a/tests/automock_return_owned.rs b/tests/automock_return_owned.rs
+new file mode 100644
+index 0000000..826d711
+--- /dev/null
++++ b/tests/automock_return_owned.rs
+@@ -0,0 +1,32 @@
++// vim: tw=80
++//! A method that returns ownership of a value, rather than returning by Copy
++#![deny(warnings)]
++
++use mockall::*;
++
++struct NonCopy {}
++
++#[automock]
++trait T {
++ fn foo(&self) -> NonCopy;
++}
++
++#[test]
++fn return_once() {
++ let mut mock = MockT::new();
++ let r = NonCopy{};
++ mock.expect_foo()
++ .return_once(|| r);
++ mock.foo();
++}
++
++#[test]
++#[should_panic(expected = "MockT::foo: Expectation(<anything>) called twice, but it returns by move")]
++fn return_once_too_many_times() {
++ let mut mock = MockT::new();
++ let r = NonCopy{};
++ mock.expect_foo()
++ .return_once(|| r);
++ mock.foo();
++ mock.foo();
++}
+diff --git a/tests/automock_return_reference.rs b/tests/automock_return_reference.rs
+new file mode 100644
+index 0000000..f312217
+--- /dev/null
++++ b/tests/automock_return_reference.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++//! A method that returns an immutable reference
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++ fn foo(&self) -> &u32;
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockA::new();
++ mock.expect_foo().return_const(5);
++ assert_eq!(5, *mock.foo());
++}
+diff --git a/tests/automock_return_static_ref.rs b/tests/automock_return_static_ref.rs
+new file mode 100644
+index 0000000..1f8c533
+--- /dev/null
++++ b/tests/automock_return_static_ref.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++//! A method that returns an immutable 'static reference
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++ fn foo(&self) -> &'static u32;
++}
++
++#[test]
++fn return_const() {
++ const X: u32 = 5;
++ let mut mock = MockA::new();
++ mock.expect_foo().return_const(&X);
++ assert_eq!(5, *mock.foo());
++}
+diff --git a/tests/automock_rpitit.rs b/tests/automock_rpitit.rs
+new file mode 100644
+index 0000000..4bf2974
+--- /dev/null
++++ b/tests/automock_rpitit.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! Return position Impl Trait in Traits
++//! https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html
++#![cfg(feature = "nightly")]
++#![deny(warnings)]
++
++use std::fmt::Debug;
++
++use mockall::*;
++
++#[automock]
++trait Foo {
++ fn bar(&self) -> impl Debug;
++}
++
++#[test]
++fn returning() {
++ let mut foo = MockFoo::default();
++ foo.expect_bar()
++ .returning(|| Box::new(42u32));
++ assert_eq!("42", format!("{:?}", foo.bar()));
++}
+diff --git a/tests/automock_self_by_value.rs b/tests/automock_self_by_value.rs
+new file mode 100644
+index 0000000..45af055
+--- /dev/null
++++ b/tests/automock_self_by_value.rs
+@@ -0,0 +1,30 @@
++// vim: tw=80
++//! A method that consumes self
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct MethodByValue {}
++
++#[automock]
++impl MethodByValue {
++ pub fn foo(self, _x: u32) -> i64 {0}
++ #[allow(unused_mut)]
++ pub fn bar(mut self) {}
++}
++
++#[test]
++fn immutable() {
++ let mut mock = MockMethodByValue::new();
++ mock.expect_foo()
++ .returning(|x| i64::from(x) + 1);
++ assert_eq!(5, mock.foo(4));
++}
++
++#[test]
++fn mutable() {
++ let mut mock = MockMethodByValue::new();
++ mock.expect_bar()
++ .returning(|| ());
++ mock.bar();
++}
+diff --git a/tests/automock_send.rs b/tests/automock_send.rs
+new file mode 100644
+index 0000000..1f7d468
+--- /dev/null
++++ b/tests/automock_send.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++//! A mock object should be Send
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub trait T {
++ fn foo(&self) -> u32;
++}
++
++#[test]
++#[allow(clippy::unnecessary_operation)] // The cast is the whole point
++fn cast_to_send() {
++ let mock = MockT::new();
++ let _m = Box::new(mock) as Box<dyn T + Send>;
++}
+diff --git a/tests/automock_seven_args.rs b/tests/automock_seven_args.rs
+new file mode 100644
+index 0000000..6760f02
+--- /dev/null
++++ b/tests/automock_seven_args.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! When mocking static functions just at the threshold of Clippy's type
++//! complexity limit, no warnings should be emitted regarding the generated
++//! code.
++#![deny(warnings)]
++
++use mockall::automock;
++
++#[automock]
++trait ManyArgs {
++ fn foo(_a0: u8, _a1: u8, _a2: u8, _a3: u8, _a4: u8, _a5: u8, _a6: u8);
++}
++
++#[test]
++fn static_method_returning() {
++ let ctx = MockManyArgs::foo_context();
++ ctx.expect()
++ .returning(|_, _, _, _, _, _, _| ());
++ MockManyArgs::foo(0, 0, 0, 0, 0, 0, 0);
++}
++
++
+diff --git a/tests/automock_slice_arguments.rs b/tests/automock_slice_arguments.rs
+new file mode 100644
+index 0000000..37044ac
+--- /dev/null
++++ b/tests/automock_slice_arguments.rs
+@@ -0,0 +1,35 @@
++// vim: tw=80
++//! a method with slice arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo {
++ fn foo(&self, x: &[u8]);
++}
++
++mod withf {
++ use super::*;
++
++ #[test]
++ #[should_panic(expected = "MockFoo::foo([1, 2, 3, 4]): No matching expectation found")]
++ fn fail() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .withf(|sl| sl == [1, 2, 3])
++ .returning(|_| ());
++ let x = vec![1, 2, 3, 4];
++ mock.foo(&x);
++ }
++
++ #[test]
++ fn ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .withf(|sl| sl == [1, 2, 3])
++ .returning(|_| ());
++ let x = vec![1, 2, 3];
++ mock.foo(&x);
++ }
++}
+diff --git a/tests/automock_specializing_method_of_nongeneric_struct.rs b/tests/automock_specializing_method_of_nongeneric_struct.rs
+new file mode 100644
+index 0000000..8f82f57
+--- /dev/null
++++ b/tests/automock_specializing_method_of_nongeneric_struct.rs
+@@ -0,0 +1,29 @@
++// vim: tw=80
++//! Non-generic structs can have specializing methods, too. For example, some
++//! methods place constraints on Self. It's even possible for a where clause to
++//! place a constraint on types that appear nowhere in the struct's signatures.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Bar {
++ fn bar(&self) where Self: Sized;
++ fn baz() where Self: Sized;
++}
++
++#[test]
++fn nonstatic() {
++ let mut mock = MockBar::default();
++ mock.expect_bar()
++ .return_const(());
++ mock.bar();
++}
++
++#[test]
++fn static_method() {
++ let ctx = MockBar::baz_context();
++ ctx.expect()
++ .return_const(());
++ MockBar::baz();
++}
+diff --git a/tests/automock_specializing_methods.rs b/tests/automock_specializing_methods.rs
+new file mode 100644
+index 0000000..e4f3af4
+--- /dev/null
++++ b/tests/automock_specializing_methods.rs
+@@ -0,0 +1,33 @@
++// vim: tw=80
++//! A specializing method is a non-generic method of a generic struct that
++//! places additional bounds on the struct's generic types via a where
++//! clause.
++#![deny(warnings)]
++
++use mockall::*;
++
++struct G<T: Copy + Default>(T);
++
++#[derive(Clone, Copy)]
++struct NonDefault{}
++
++#[automock]
++trait Foo<T> where T: Copy {
++ fn foo(&self, t: T) -> G<T> where T: Default + 'static;
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::<u32>::default();
++ mock.expect_foo()
++ .returning(G);
++ assert_eq!(42u32, mock.foo(42u32).0);
++
++ // It's possible to instantiate a mock object that doesn't satisfy the
++ // specializing method's requirements:
++ let _mock2 = MockFoo::<NonDefault>::default();
++ // But you can't call the specializing method. This won't work:
++ // _mock2.expect_foo()
++ // .returning(|h| G(h));
++ // _mock2.foo(NonDefault{});
++}
+diff --git a/tests/automock_static_method.rs b/tests/automock_static_method.rs
+new file mode 100644
+index 0000000..bcdff4d
+--- /dev/null
++++ b/tests/automock_static_method.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++//! automocking a trait with a static method
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++ fn bar() -> u32;
++}
++
++#[test]
++fn returning() {
++ let ctx = MockA::bar_context();
++ ctx.expect()
++ .returning(|| 42);
++ assert_eq!(42, MockA::bar());
++}
+diff --git a/tests/automock_struct.rs b/tests/automock_struct.rs
+new file mode 100644
+index 0000000..d344167
+--- /dev/null
++++ b/tests/automock_struct.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! automocking a struct
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct SimpleStruct {}
++
++#[automock]
++impl SimpleStruct {
++ pub fn foo(&self, _x: u32) -> i64 {
++ 42
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockSimpleStruct::new();
++ mock.expect_foo()
++ .returning(|x| i64::from(x) + 1);
++ assert_eq!(5, mock.foo(4));
++}
+diff --git a/tests/automock_trait.rs b/tests/automock_trait.rs
+new file mode 100644
+index 0000000..81261d6
+--- /dev/null
++++ b/tests/automock_trait.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++//! automocking a trait
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait SimpleTrait {
++ fn foo(&self, x: u32) -> u32;
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockSimpleTrait::new();
++ mock.expect_foo()
++ .returning(|x| x + 1);
++ assert_eq!(5, mock.foo(4));
++}
+diff --git a/tests/automock_trait_object.rs b/tests/automock_trait_object.rs
+new file mode 100644
+index 0000000..78f93a0
+--- /dev/null
++++ b/tests/automock_trait_object.rs
+@@ -0,0 +1,42 @@
++// vim: tw=80
++//! a method that uses unboxed trait object arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo {
++ fn foo(&self, x: &dyn PartialEq<u32>);
++}
++
++// It's almost impossible to construct a Predicate object that will work with
++// trait objects for two reasons:
++// * Mockall requires the predicates to be Debug, and any useful predicate will
++// also be Eq, Ord, or similar, but Rust only allows up to one non-auto trait
++// per trait object.
++// * The predicate is requird to meet the HRTB
++// for<'a> Predicate<(dyn Trait + 'a)>
++// That's not impossible, but Mockall doesn't provide any way to construct
++// such a predicate.
++// So, use of `with` is pretty much limited to predicates like `always` and
++// `function`.
++#[test]
++fn with() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .with(predicate::always())
++ .return_const(());
++ mock.foo(&42u32)
++}
++
++/// trait object arguments can't be matched with `predicate::eq`, because
++/// `PartialEq<Self>` cannot be made into a trait object. But withf still
++/// works.
++#[test]
++fn withf() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .withf(|x| *x == 42u32)
++ .return_const(());
++ mock.foo(&42u32);
++}
+diff --git a/tests/automock_unsafe_trait.rs b/tests/automock_unsafe_trait.rs
+new file mode 100644
+index 0000000..ff64eb7
+--- /dev/null
++++ b/tests/automock_unsafe_trait.rs
+@@ -0,0 +1,37 @@
++// vim: ts=80
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++#[allow(clippy::missing_safety_doc)]
++pub unsafe trait Foo {
++ fn foo(&self) -> i32;
++}
++
++pub struct Baz{}
++
++#[automock]
++unsafe impl Foo for Baz {
++ fn foo(&self) -> i32 {
++ unimplemented!()
++ }
++}
++
++#[test]
++fn automock_trait() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .return_const(42);
++
++ assert_eq!(42, mock.foo());
++}
++
++#[test]
++fn automock_trait_impl() {
++ let mut mock = MockBaz::new();
++ mock.expect_foo()
++ .return_const(42);
++
++ assert_eq!(42, mock.foo());
++}
+diff --git a/tests/automock_where_self.rs b/tests/automock_where_self.rs
+new file mode 100644
+index 0000000..eedf34f
+--- /dev/null
++++ b/tests/automock_where_self.rs
+@@ -0,0 +1,29 @@
++// vim: ts=80
++//! Methods with a "where Self: ..." where clause should be mocked as concrete,
++//! not generic.
++#![deny(warnings)]
++#![allow(clippy::needless_lifetimes)]
++
++// Enclose the mocked trait within a non-public module. With some versions of
++// rustc, that causes "unused method" errors for the generic code, but not the
++// concrete code.
++// rustc 1.66.0-nightly (e7119a030 2022-09-22)
++mod mymod {
++
++ #[mockall::automock]
++ pub trait Server {
++ fn version<'a>(&'a self) -> Option<&'static str> where Self: Sized;
++ }
++
++}
++
++use mymod::{MockServer, Server};
++
++#[test]
++fn return_const() {
++ let mut mock = MockServer::new();
++ mock.expect_version()
++ .return_const(None);
++
++ mock.version();
++}
+diff --git a/tests/cfg_attr_concretize.rs b/tests/cfg_attr_concretize.rs
+new file mode 100644
+index 0000000..93af750
+--- /dev/null
++++ b/tests/cfg_attr_concretize.rs
+@@ -0,0 +1,26 @@
++// vim: tw=80
++//! #[concretize] can be used inside of #[cfg_attr()]`
++#![deny(warnings)]
++
++use std::path::{Path, PathBuf};
++
++use mockall::{automock, concretize};
++
++#[automock]
++trait Foo {
++ #[cfg_attr(not(target_os = "ia64-unknown-multics"), concretize)]
++ fn foo<P: AsRef<Path>>(&self, p: P);
++}
++
++
++#[test]
++fn withf() {
++ let mut foo = MockFoo::new();
++ foo.expect_foo()
++ .withf(|p| p.as_ref() == Path::new("/tmp"))
++ .times(3)
++ .return_const(());
++ foo.foo(Path::new("/tmp"));
++ foo.foo(PathBuf::from(Path::new("/tmp")));
++ foo.foo("/tmp");
++}
+diff --git a/tests/clear_expectations_on_panic.rs b/tests/clear_expectations_on_panic.rs
+new file mode 100644
+index 0000000..a70df15
+--- /dev/null
++++ b/tests/clear_expectations_on_panic.rs
+@@ -0,0 +1,50 @@
++// vim: tw=80
++//! Static methods' expectations should be dropped during panic.
++//!
++//! https://github.com/asomers/mockall/issues/442
++#![deny(warnings)]
++
++use std::panic;
++
++use mockall::*;
++
++#[automock]
++pub trait Foo {
++ fn foo() -> i32;
++ fn bar() -> i32;
++}
++
++#[test]
++fn too_few_calls() {
++ panic::catch_unwind(|| {
++ let ctx = MockFoo::foo_context();
++ ctx.expect()
++ .times(1)
++ .return_const(42);
++ }).unwrap_err();
++
++ // The previously set expectation should've been cleared during the panic,
++ // so we must set a new one.
++ let ctx = MockFoo::foo_context();
++ ctx.expect()
++ .times(1)
++ .return_const(42);
++ assert_eq!(42, MockFoo::foo());
++}
++
++// We shouldn't panic during drop in this case. Regression test for
++// https://github.com/asomers/mockall/issues/491
++#[cfg_attr(not(feature = "nightly"), ignore)]
++#[test]
++fn too_many_calls() {
++ panic::catch_unwind(|| {
++ let ctx = MockFoo::bar_context();
++ ctx.expect()
++ .times(0);
++ MockFoo::bar();
++ }).unwrap_err();
++
++ // This line will panic with a PoisonError, at least until issue #515 is
++ // complete.
++ let _ctx = MockFoo::bar_context();
++}
+diff --git a/tests/link_name.rs b/tests/link_name.rs
+new file mode 100644
+index 0000000..0987cce
+--- /dev/null
++++ b/tests/link_name.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub mod ffi {
++ extern "C" {
++ #[link_name = "foo__extern"]
++ pub fn foo() -> u32;
++ }
++}
++
++#[test]
++fn return_const() {
++ let ctx = mock_ffi::foo_context();
++ ctx.expect().return_const(42u32);
++ assert_eq!(42, unsafe{mock_ffi::foo()});
++}
+diff --git a/tests/mock_associated_const.rs b/tests/mock_associated_const.rs
+new file mode 100644
+index 0000000..eae84ff
+--- /dev/null
++++ b/tests/mock_associated_const.rs
+@@ -0,0 +1,34 @@
++// vim: tw=80
++//! A trait with an associated constant
++//!
++//! https://github.com/asomers/mockall/issues/97
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++ const X: i32;
++
++ fn x_plus_one(&self) -> i32 {
++ Self::X + 1
++ }
++}
++
++mock! {
++ Foo {
++ const Y: i32 = 69;
++ }
++ impl Foo for Foo {
++ const X: i32 = 42;
++ }
++}
++
++#[test]
++fn default_method() {
++ assert_eq!(MockFoo::new().x_plus_one(), 43);
++}
++
++#[test]
++fn on_the_struct() {
++ assert_eq!(MockFoo::Y, 69);
++}
+diff --git a/tests/mock_associated_types.rs b/tests/mock_associated_types.rs
+new file mode 100644
+index 0000000..8cf7aa9
+--- /dev/null
++++ b/tests/mock_associated_types.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ MyIter {}
++ impl Iterator for MyIter {
++ type Item=u32;
++
++ fn next(&mut self) -> Option<u32>;
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockMyIter::new();
++ mock.expect_next()
++ .returning(|| Some(5));
++ assert_eq!(5, mock.next().unwrap());
++}
++
+diff --git a/tests/mock_async_fn.rs b/tests/mock_async_fn.rs
+new file mode 100644
+index 0000000..0988559
+--- /dev/null
++++ b/tests/mock_async_fn.rs
+@@ -0,0 +1,39 @@
++// vim: tw=80
++//! A struct with an async function
++#![deny(warnings)]
++
++use futures::executor::block_on;
++use mockall::*;
++
++mock! {
++ pub Foo {
++ async fn foo(&self) -> u32;
++ async fn bar() -> u32;
++ async fn baz<T: 'static>(&self, t: T) -> T;
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .return_const(42u32);
++ assert_eq!(block_on(mock.foo()), 42);
++}
++
++#[test]
++fn static_method() {
++ let ctx = MockFoo::bar_context();
++ ctx.expect()
++ .return_const(42u32);
++ assert_eq!(block_on(MockFoo::bar()), 42);
++}
++
++#[test]
++fn generic_method() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .with(predicate::eq(69u32))
++ .return_const(42u32);
++ assert_eq!(block_on(mock.baz(69u32)), 42u32);
++}
+diff --git a/tests/mock_async_trait.rs b/tests/mock_async_trait.rs
+new file mode 100644
+index 0000000..7493dd9
+--- /dev/null
++++ b/tests/mock_async_trait.rs
+@@ -0,0 +1,28 @@
++// vim: tw=80
++//! An async trait, for use with Futures
++#![deny(warnings)]
++
++use async_trait::async_trait;
++use futures::executor::block_on;
++use mockall::*;
++
++#[async_trait]
++pub trait Foo {
++ async fn foo(&self) -> u32;
++}
++
++mock! {
++ pub Bar { }
++ #[async_trait]
++ impl Foo for Bar {
++ async fn foo(&self) -> u32;
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockBar::new();
++ mock.expect_foo()
++ .return_const(42u32);
++ assert_eq!(block_on(mock.foo()), 42);
++}
+diff --git a/tests/mock_box_self.rs b/tests/mock_box_self.rs
+new file mode 100644
+index 0000000..8d17754
+--- /dev/null
++++ b/tests/mock_box_self.rs
+@@ -0,0 +1,68 @@
++// vim: tw=80
++//! Methods that take receivers like Box<Self> instead of &self
++#![allow(clippy::borrowed_box, clippy::boxed_local)]
++#![deny(warnings)]
++
++use mockall::*;
++use std::sync::Arc;
++use std::pin::Pin;
++use std::rc::Rc;
++
++mock! {
++ Foo {
++ fn foo(self: &Box<Self>);
++ fn baz(mut self: Box<Self>);
++ fn bar(self: Box<Self>);
++ fn bean(self: Arc<Self>);
++ fn booz(self: Pin<Box<Self>>);
++ fn blez(self: Rc<Self>);
++ }
++}
++
++#[test]
++fn arc() {
++ let mut mock = MockFoo::new();
++ mock.expect_bean()
++ .returning(|| ());
++ Arc::new(mock).bean();
++}
++
++#[test]
++fn pin() {
++ let mut mock = MockFoo::new();
++ mock.expect_booz()
++ .returning(|| ());
++ Pin::new(Box::new(mock)).booz();
++}
++
++#[test]
++fn rc() {
++ let mut mock = MockFoo::new();
++ mock.expect_blez()
++ .returning(|| ());
++ Rc::new(mock).blez();
++}
++
++#[test]
++fn ref_box() {
++ let mut mock = Box::new(MockFoo::new());
++ mock.expect_foo()
++ .returning(|| ());
++ mock.foo();
++}
++
++#[test]
++fn mutable() {
++ let mut mock = Box::new(MockFoo::new());
++ mock.expect_baz()
++ .returning(|| ());
++ mock.baz();
++}
++
++#[test]
++fn owned() {
++ let mut mock = Box::new(MockFoo::new());
++ mock.expect_bar()
++ .returning(|| ());
++ mock.bar();
++}
+diff --git a/tests/mock_cfg.rs b/tests/mock_cfg.rs
+new file mode 100644
+index 0000000..b846a87
+--- /dev/null
++++ b/tests/mock_cfg.rs
+@@ -0,0 +1,65 @@
++// vim: tw=80
++//! mock's methods and trait impls can be conditionally compiled
++#![deny(warnings)]
++
++use mockall::*;
++
++// For this test, use the "nightly" feature as the cfg gate, because it's tested
++// both ways in CI.
++#[cfg(feature = "nightly")]
++pub trait Beez {
++ fn beez(&self);
++}
++#[cfg(not(feature = "nightly"))]
++pub trait Beez {
++ fn beez(&self, x: i32) -> i32;
++}
++
++mock! {
++ pub Foo {
++ #[cfg(feature = "nightly")]
++ pub fn foo(&self);
++ #[cfg(not(feature = "nightly"))]
++ pub fn foo(&self, x: i32) -> i32;
++ }
++ #[cfg(feature = "nightly")]
++ impl Beez for Foo {
++ fn beez(&self);
++ }
++ #[cfg(not(feature = "nightly"))]
++ impl Beez for Foo {
++ fn beez(&self, x: i32) -> i32;
++ }
++}
++
++#[test]
++#[cfg(feature = "nightly")]
++fn test_nightly_method() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|| ());
++}
++
++#[test]
++#[cfg(feature = "nightly")]
++fn test_nightly_trait() {
++ let mut mock = MockFoo::new();
++ mock.expect_beez()
++ .returning(|| ());
++}
++
++#[test]
++#[cfg(not(feature = "nightly"))]
++fn test_not_nightly_method() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|x| x + 1);
++}
++
++#[test]
++#[cfg(not(feature = "nightly"))]
++fn test_not_nightly_trait() {
++ let mut mock = MockFoo::new();
++ mock.expect_beez()
++ .returning(|x| x + 1);
++}
+diff --git a/tests/mock_clone.rs b/tests/mock_clone.rs
+new file mode 100644
+index 0000000..8f4a227
+--- /dev/null
++++ b/tests/mock_clone.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! Clone-like methods (non-static method with Self return type) need the return
++//! type to be deselfified.
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ pub A {}
++ impl Clone for A {
++ fn clone(&self) -> Self;
++ }
++}
++
++#[allow(clippy::redundant_clone)]
++#[test]
++fn returning() {
++ let mut mock0 = MockA::new();
++ mock0.expect_clone()
++ .returning(MockA::new);
++ let _mock1 = mock0.clone();
++}
+diff --git a/tests/mock_closure.rs b/tests/mock_closure.rs
+new file mode 100644
+index 0000000..412f0f4
+--- /dev/null
++++ b/tests/mock_closure.rs
+@@ -0,0 +1,89 @@
++// vim: tw=80
++//! A method with a closure argument can be mocked, by turning the closure into
++//! a Boxed Fn.
++#![deny(warnings)]
++
++use mockall::*;
++
++struct NonCopy(u32);
++
++mock!{
++ Foo {
++ fn foo<F: Fn(u32) -> u32 + 'static>(&self, f: F) -> u32;
++ fn bar<F: FnMut(u32) -> u32 + 'static>(&self, f: F) -> u32;
++ fn baz<F: FnOnce(u32) -> NonCopy + 'static>(&self, f: F) -> NonCopy;
++ fn bean<F: Fn(u32) -> u32 + 'static>(f: F) -> u32;
++ // Not technically a closure, but it should work too
++ fn bang(&self, f: fn(u32) -> u32) -> u32;
++ // Identical to foo, but it uses a where clause
++ fn food<F>(&self, f: F) -> u32 where F: Fn(u32) -> u32 + 'static;
++ // Identical to foo, but with extra unrelated where predicates
++ fn foody<F, G>(&self, f: F, g:G) -> u32
++ where F: Fn(u32) -> u32 + 'static,
++ G: 'static;
++ }
++}
++
++mod returning {
++ use super::*;
++
++ #[test]
++ fn bare_fn() {
++ let mut mock = MockFoo::new();
++ mock.expect_bang()
++ .returning(|f| f(42));
++ assert_eq!(84, mock.bang(|x| 2 * x));
++ }
++
++ #[test]
++ fn immutable() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|f| f(42));
++ assert_eq!(84, mock.foo(|x| 2 * x));
++ }
++
++ #[test]
++ fn mutable() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .returning(|mut f| {f(42); f(5) } );
++ let mut counter = 0;
++ assert_eq!(47, mock.bar(move |x| { counter += x; counter } ));
++ }
++
++ #[test]
++ fn once() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .returning(|f| f(42));
++ let initial = NonCopy(5);
++ assert_eq!(47, mock.baz(move |x| NonCopy(initial.0 + x)).0);
++ }
++
++ #[test]
++ fn static_method() {
++ let ctx = MockFoo::bean_context();
++ ctx.expect()
++ .returning(|f| f(42));
++ assert_eq!(84, MockFoo::bean(|x| 2 * x));
++ }
++
++ // food's where clause should be completely deleted in the mock
++ // implementation.
++ #[test]
++ fn deleted_where_clause() {
++ let mut mock = MockFoo::new();
++ mock.expect_food()
++ .returning(|f| f(42));
++ assert_eq!(84, mock.food(|x| 2 * x));
++ }
++
++ #[test]
++ fn where_clause() {
++ let mut mock = MockFoo::new();
++ mock.expect_foody()
++ .returning(|f, _g: u32| f(42));
++ assert_eq!(84, mock.foody(|x| 2u32 * x, 0u32));
++ }
++}
+diff --git a/tests/mock_concrete_struct_with_generic_trait.rs b/tests/mock_concrete_struct_with_generic_trait.rs
+new file mode 100644
+index 0000000..2fd07f5
+--- /dev/null
++++ b/tests/mock_concrete_struct_with_generic_trait.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++//! A concrete struct that implements a generic trait
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo<T> {
++ fn foo(&self, x: T) -> T;
++}
++mock! {
++ Bar {}
++ impl Foo<i32> for Bar {
++ fn foo(&self, x: i32) -> i32;
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockBar::new();
++ mock.expect_foo()
++ .with(predicate::eq(42))
++ .returning(|x| x + 1);
++ assert_eq!(43, mock.foo(42));
++}
+diff --git a/tests/mock_concretize.rs b/tests/mock_concretize.rs
+new file mode 100644
+index 0000000..f9d73ef
+--- /dev/null
++++ b/tests/mock_concretize.rs
+@@ -0,0 +1,140 @@
++// vim: tw=80
++//! Some generic methods with non-`'static` generic parameters can be mocked by
++//! transforming the function arguments into trait objects.
++#![deny(warnings)]
++
++use mockall::*;
++use std::path::{Path, PathBuf};
++
++trait AsRefMut<T: ?Sized>: AsRef<T> + AsMut<T> {}
++impl<Q, T> AsRefMut<T> for Q where Q: AsRef<T> + AsMut<T>, T: ?Sized {}
++
++mock! {
++ Foo {
++ /// Base concretized function
++ #[mockall::concretize]
++ fn foo<P: AsRef<std::path::Path>>(&self, x: P);
++
++ /// With a where clause
++ #[mockall::concretize]
++ fn boom<P>(&self, x: P) where P: AsRef<std::path::Path>;
++
++ /// Static function
++ #[mockall::concretize]
++ fn bang<P: AsRef<std::path::Path>>(x: P);
++
++ /// Reference argument
++ #[mockall::concretize]
++ fn boomref<P: AsRef<std::path::Path>>(&self, x: &P);
++
++ /// Mutable reference argument
++ #[mockall::concretize]
++ fn boom_mutref<T: AsRefMut<str>>(&self, x: &mut T);
++
++ /// Slice argument
++ #[mockall::concretize]
++ fn boomv<P>(&self, x: &[P]) where P: AsRef<std::path::Path>;
++
++ /// Public visiblity
++ #[mockall::concretize]
++ pub fn foopub<P: AsRef<std::path::Path>>(&self, x: P);
++ }
++}
++
++mod generic_arg {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let mut foo = MockFoo::new();
++ foo.expect_foo()
++ .withf(|p| p.as_ref() == Path::new("/tmp"))
++ .times(3)
++ .return_const(());
++ foo.foo(Path::new("/tmp"));
++ foo.foo(PathBuf::from(Path::new("/tmp")));
++ foo.foo("/tmp");
++ }
++}
++
++mod where_clause {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let mut foo = MockFoo::new();
++ foo.expect_boom()
++ .withf(|p| p.as_ref() == Path::new("/tmp"))
++ .times(3)
++ .return_const(());
++ foo.boom(Path::new("/tmp"));
++ foo.boom(PathBuf::from(Path::new("/tmp")));
++ foo.boom("/tmp");
++ }
++}
++
++mod mutable_reference_arg {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let mut foo = MockFoo::new();
++ foo.expect_boom_mutref()
++ .withf(|p| p.as_ref() == "/tmp")
++ .once()
++ .returning(|s| s.as_mut().make_ascii_uppercase());
++ let mut s = String::from("/tmp");
++ foo.boom_mutref(&mut s);
++ assert_eq!(s, "/TMP");
++ }
++}
++
++mod reference_arg {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let mut foo = MockFoo::new();
++ foo.expect_boomref()
++ .withf(|p| p.as_ref() == Path::new("/tmp"))
++ .times(3)
++ .return_const(());
++ foo.boomref(&Path::new("/tmp"));
++ foo.boomref(&PathBuf::from(Path::new("/tmp")));
++ foo.boomref(&"/tmp");
++ }
++}
++
++mod slice {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let mut foo = MockFoo::new();
++ foo.expect_boomv()
++ .withf(|v|
++ v[0].as_ref() == Path::new("/tmp") &&
++ v[1].as_ref() == Path::new("/mnt")
++ ).times(3)
++ .return_const(());
++ foo.boomv(&[Path::new("/tmp"), Path::new("/mnt")]);
++ foo.boomv(&[PathBuf::from("/tmp"), PathBuf::from("/mnt")]);
++ foo.boomv(&["/tmp", "/mnt"]);
++ }
++}
++
++mod static_method {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let ctx = MockFoo::bang_context();
++ ctx.expect()
++ .withf(|p| p.as_ref() == Path::new("/tmp"))
++ .times(3)
++ .return_const(());
++ MockFoo::bang(Path::new("/tmp"));
++ MockFoo::bang(PathBuf::from(Path::new("/tmp")));
++ MockFoo::bang("/tmp");
++ }
++}
+diff --git a/tests/mock_concretize_with_bounds.rs b/tests/mock_concretize_with_bounds.rs
+new file mode 100644
+index 0000000..76b55a8
+--- /dev/null
++++ b/tests/mock_concretize_with_bounds.rs
+@@ -0,0 +1,135 @@
++// vim: tw=80
++//! Using #[concretize] on generic types with trait bounds
++#![deny(warnings)]
++
++use mockall::*;
++use std::path::{Path, PathBuf};
++
++trait AsRefMut<T: ?Sized>: AsRef<T> + AsMut<T> {}
++impl<Q, T> AsRefMut<T> for Q where Q: AsRef<T> + AsMut<T>, T: ?Sized {}
++
++mock! {
++ Foo {
++ /// Base concretized function
++ #[mockall::concretize]
++ fn foo<P: AsRef<std::path::Path> + Send>(&self, x: P);
++
++ /// With a where clause
++ #[mockall::concretize]
++ fn boom<P>(&self, x: P) where P: AsRef<std::path::Path> + Send;
++
++ /// Static function
++ #[mockall::concretize]
++ fn bang<P: AsRef<std::path::Path> + Send>(x: P);
++
++ /// Reference argument
++ #[mockall::concretize]
++ fn boomref<P: AsRef<std::path::Path> + Send>(&self, x: &P);
++
++ /// Mutable reference argument
++ #[mockall::concretize]
++ fn boom_mutref<T: AsRefMut<str> + Send>(&self, x: &mut T);
++
++ /// Slice argument
++ #[mockall::concretize]
++ fn boomv<P>(&self, x: &[P]) where P: AsRef<std::path::Path> + Send;
++ }
++}
++
++mod generic_arg {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let mut foo = MockFoo::new();
++ foo.expect_foo()
++ .withf(|p| p.as_ref() == Path::new("/tmp"))
++ .times(3)
++ .return_const(());
++ foo.foo(Path::new("/tmp"));
++ foo.foo(PathBuf::from(Path::new("/tmp")));
++ foo.foo("/tmp");
++ }
++}
++
++mod where_clause {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let mut foo = MockFoo::new();
++ foo.expect_boom()
++ .withf(|p| p.as_ref() == Path::new("/tmp"))
++ .times(3)
++ .return_const(());
++ foo.boom(Path::new("/tmp"));
++ foo.boom(PathBuf::from(Path::new("/tmp")));
++ foo.boom("/tmp");
++ }
++}
++
++mod mutable_reference_arg {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let mut foo = MockFoo::new();
++ foo.expect_boom_mutref()
++ .withf(|p| p.as_ref() == "/tmp")
++ .once()
++ .returning(|s| s.as_mut().make_ascii_uppercase());
++ let mut s = String::from("/tmp");
++ foo.boom_mutref(&mut s);
++ assert_eq!(s, "/TMP");
++ }
++}
++
++mod reference_arg {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let mut foo = MockFoo::new();
++ foo.expect_boomref()
++ .withf(|p| p.as_ref() == Path::new("/tmp"))
++ .times(3)
++ .return_const(());
++ foo.boomref(&Path::new("/tmp"));
++ foo.boomref(&PathBuf::from(Path::new("/tmp")));
++ foo.boomref(&"/tmp");
++ }
++}
++
++mod slice {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let mut foo = MockFoo::new();
++ foo.expect_boomv()
++ .withf(|v|
++ v[0].as_ref() == Path::new("/tmp") &&
++ v[1].as_ref() == Path::new("/mnt")
++ ).times(3)
++ .return_const(());
++ foo.boomv(&[Path::new("/tmp"), Path::new("/mnt")]);
++ foo.boomv(&[PathBuf::from("/tmp"), PathBuf::from("/mnt")]);
++ foo.boomv(&["/tmp", "/mnt"]);
++ }
++}
++
++mod static_method {
++ use super::*;
++
++ #[test]
++ fn withf() {
++ let ctx = MockFoo::bang_context();
++ ctx.expect()
++ .withf(|p| p.as_ref() == Path::new("/tmp"))
++ .times(3)
++ .return_const(());
++ MockFoo::bang(Path::new("/tmp"));
++ MockFoo::bang(PathBuf::from(Path::new("/tmp")));
++ MockFoo::bang("/tmp");
++ }
++}
+diff --git a/tests/mock_constructor_with_args.rs b/tests/mock_constructor_with_args.rs
+new file mode 100644
+index 0000000..c12c442
+--- /dev/null
++++ b/tests/mock_constructor_with_args.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++//! A struct with a constructor method named "new" that has arguments.
++//! mockall should mock the provided method, and not autogenerate a 0-argument
++//! "new" method.
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ pub Foo {
++ fn new(x: u32) -> Self;
++ }
++}
++
++#[test]
++fn returning_once() {
++ let mock = MockFoo::default();
++
++ let ctx = MockFoo::new_context();
++ ctx.expect()
++ .return_once(|_| mock);
++
++ let _mock = MockFoo::new(5);
++}
+diff --git a/tests/mock_debug.rs b/tests/mock_debug.rs
+new file mode 100644
+index 0000000..81e30cd
+--- /dev/null
++++ b/tests/mock_debug.rs
+@@ -0,0 +1,40 @@
++// vim: tw=80
++//! A mocked struct should implement Debug
++#![deny(warnings)]
++
++use mockall::*;
++use std::fmt::{self, Debug, Formatter};
++
++// using derive(Debug) tells mockall to generate the Debug impl automatically
++mock!{
++ #[derive(Debug)]
++ pub Bar { }
++ impl Clone for Bar {
++ fn clone(&self) -> Self;
++ }
++}
++
++// With no derive(Debug), mockall won't genetate the debug impl automatically
++mock!{
++ pub Baz { }
++ impl Clone for Baz {
++ fn clone(&self) -> Self;
++ }
++}
++impl Debug for MockBaz {
++ fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
++ f.debug_struct("XXX").finish()
++ }
++}
++
++#[test]
++fn automatic() {
++ let bar = MockBar::new();
++ assert_eq!("MockBar", format!("{bar:?}"));
++}
++
++#[test]
++fn manual() {
++ let baz = MockBaz::new();
++ assert_eq!("XXX", format!("{baz:?}"));
++}
+diff --git a/tests/mock_deref.rs b/tests/mock_deref.rs
+new file mode 100644
+index 0000000..852b891
+--- /dev/null
++++ b/tests/mock_deref.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++//! A method that returns a type which is a common target for std::ops::Deref
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ Foo {
++ fn foo(&self) -> &str;
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .return_const("Stuff".to_owned());
++ assert_eq!("Stuff", mock.foo());
++}
+diff --git a/tests/mock_deref_args.rs b/tests/mock_deref_args.rs
+new file mode 100644
+index 0000000..d0789d6
+--- /dev/null
++++ b/tests/mock_deref_args.rs
+@@ -0,0 +1,120 @@
++// vim: tw=80
++//! A method whose argument is a common `Deref` implementor
++#![deny(warnings)]
++
++use mockall::*;
++use std::{
++ ffi::{CStr, CString, OsStr, OsString},
++ path::{Path, PathBuf},
++};
++
++mock! {
++ Foo {
++ fn foo<T: 'static>(&self, x: Vec<T>);
++ fn bar(&self, x: String);
++ fn baz(&self, x: CString);
++ fn bean(&self, x: OsString);
++ fn boom(&self, x: PathBuf);
++ }
++}
++
++mod with {
++ use super::*;
++
++ #[test]
++ fn cstr() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .with(predicate::eq(CString::new("xxx").unwrap()))
++ .return_const(());
++ mock.baz(CString::new("xxx").unwrap());
++ }
++
++ #[test]
++ fn osstr() {
++ let mut mock = MockFoo::new();
++ mock.expect_bean()
++ .with(predicate::eq(OsStr::new("xxx").to_owned()))
++ .return_const(());
++ mock.bean(OsString::from("xxx"));
++ }
++
++ #[test]
++ fn path() {
++ let mut mock = MockFoo::new();
++ mock.expect_boom()
++ .with(predicate::eq(Path::new("dir/file").to_owned()))
++ .return_const(());
++ mock.boom(PathBuf::from("dir/file"));
++ }
++
++ #[test]
++ fn string() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .with(predicate::eq("xxx".to_owned()))
++ .return_const(());
++ mock.bar(String::from("xxx"));
++ }
++
++ #[test]
++ fn vec() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<i32>()
++ .with(predicate::eq(vec![1, 2, 3]))
++ .return_const(());
++ mock.foo(vec![1, 2, 3]);
++ }
++}
++
++mod withf {
++ use super::*;
++
++ #[test]
++ fn cstr() {
++ let mut mock = MockFoo::new();
++ const WANT: [u8; 4] = [120u8, 120, 120, 0];
++ let want = CStr::from_bytes_with_nul(&WANT[..]).unwrap();
++ mock.expect_baz()
++ .withf(move |s| s.as_c_str() == want)
++ .return_const(());
++ mock.baz(CString::new("xxx").unwrap());
++ }
++
++ #[test]
++ fn osstr() {
++ let mut mock = MockFoo::new();
++ mock.expect_bean()
++ .withf(move |s| s.as_os_str() == OsStr::new("xxx"))
++ .return_const(());
++ mock.bean(OsString::from("xxx"));
++ }
++
++ #[test]
++ fn path() {
++ let mut mock = MockFoo::new();
++ mock.expect_boom()
++ .withf(move |s| s.as_path() == Path::new("dir/file"))
++ .return_const(());
++ mock.boom(PathBuf::from("dir/file"));
++ }
++
++ #[test]
++ fn string() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .withf(|sl: &String| sl == "xxx")
++ .return_const(());
++ mock.bar(String::from("xxx"));
++ }
++
++ #[test]
++ fn vec() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<i32>()
++ .withf(|sl: &Vec<i32>| sl == &[1, 2, 3])
++ .return_const(());
++ mock.foo(vec![1, 2, 3]);
++ }
++
++}
+diff --git a/tests/mock_docs.rs b/tests/mock_docs.rs
+new file mode 100644
+index 0000000..f1fd7ce
+--- /dev/null
++++ b/tests/mock_docs.rs
+@@ -0,0 +1,26 @@
++// vim: tw=80
++#![deny(missing_docs)]
++#![deny(warnings)]
++
++use mockall::*;
++
++// mock! should allow doc comments in all reasonable positions. This test
++// ensures that the code will compile. mockall_derive has a unit test to ensure
++// that the doc comments are correctly placed.
++
++pub trait Tr {
++ fn bar(&self);
++}
++
++mock!{
++ /// Struct docs
++ pub Foo {
++ /// Method docs
++ fn foo(&self);
++ }
++ /// Trait docs
++ impl Tr for Foo {
++ /// Trait method docs
++ fn bar(&self);
++ }
++}
+diff --git a/tests/mock_generic_and_reference_arguments.rs b/tests/mock_generic_and_reference_arguments.rs
+new file mode 100644
+index 0000000..02f3767
+--- /dev/null
++++ b/tests/mock_generic_and_reference_arguments.rs
+@@ -0,0 +1,20 @@
++// vim: tw=80
++//! A generic method may have non-generic reference arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ Foo {
++ fn foo<T: 'static>(&self, t: T, x: &i16) -> u32;
++ }
++}
++
++#[test]
++fn with() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<i32>()
++ .with(predicate::eq(4), predicate::eq(5))
++ .return_const(42u32);
++ assert_eq!(42, mock.foo(4i32, &5i16));
++}
+diff --git a/tests/mock_generic_arguments.rs b/tests/mock_generic_arguments.rs
+new file mode 100644
+index 0000000..aa3aaf4
+--- /dev/null
++++ b/tests/mock_generic_arguments.rs
+@@ -0,0 +1,68 @@
++// vim: tw=80
++//! A struct with a generic method that has generic arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ Foo {
++ fn foo<T: 'static + std::fmt::Debug>(&self, t: T) -> i32;
++ fn bar<T: 'static>(&self, t: T) -> i32;
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<i16>()
++ .return_const(0);
++ assert_eq!(0, mock.foo(0i16));
++}
++
++mod with {
++ use super::*;
++
++ /// Multiple generic methods with the same set of generic parameters are in
++ /// scope at the same time. Their expectations should not get scrambled.
++ #[test]
++ fn multiple_methods() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<i16>()
++ .with(predicate::eq(4))
++ .return_const(0);
++ mock.expect_bar::<i16>()
++ .with(predicate::eq(5))
++ .return_const(0);
++ mock.bar(5i16);
++ mock.foo(4i16);
++ }
++
++ #[test]
++ fn ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<i16>()
++ .with(predicate::eq(4))
++ .return_const(0);
++ mock.foo(4i16);
++ }
++
++ #[test]
++ #[should_panic(expected = "MockFoo::foo(4): No matching expectation found")]
++ fn wrong_generic_type() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<i16>()
++ .with(predicate::eq(4))
++ .return_const(0);
++ mock.foo(4i32);
++ }
++
++ #[test]
++ #[should_panic(expected = "MockFoo::bar(?): No matching expectation found")]
++ fn no_debug_trait_bound() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar::<i16>()
++ .with(predicate::eq(4))
++ .return_const(0);
++ mock.bar(4i32);
++ }
++}
+diff --git a/tests/mock_generic_arguments_returning_reference.rs b/tests/mock_generic_arguments_returning_reference.rs
+new file mode 100644
+index 0000000..ea0ea31
+--- /dev/null
++++ b/tests/mock_generic_arguments_returning_reference.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++ fn foo<T: 'static>(&self, t: T) -> &u32;
++}
++
++mock!{
++ MyStruct {}
++ impl Foo for MyStruct {
++ fn foo<T: 'static>(&self, t: T) -> &u32;
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockMyStruct::new();
++ mock.expect_foo::<i16>().return_const(5u32);
++ assert_eq!(5u32, *mock.foo(99i16));
++}
+diff --git a/tests/mock_generic_constructor.rs b/tests/mock_generic_constructor.rs
+new file mode 100644
+index 0000000..c81b0cf
+--- /dev/null
++++ b/tests/mock_generic_constructor.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! A generic struct with bounds on its generic parameters can have a
++//! constructor method
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ pub Foo<T: Default + 'static> {
++ fn build() -> MockFoo<T>;
++ }
++}
++
++#[test]
++fn returning_once() {
++ let ctx = MockFoo::<i16>::build_context();
++ ctx.expect()
++ .return_once(MockFoo::<i16>::default);
++
++ let _mock: MockFoo<i16> = MockFoo::<i16>::build();
++}
+diff --git a/tests/mock_generic_constructor_with_where_clause.rs b/tests/mock_generic_constructor_with_where_clause.rs
+new file mode 100644
+index 0000000..2298ccc
+--- /dev/null
++++ b/tests/mock_generic_constructor_with_where_clause.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! A generic struct with a where clause on its generic parameters can have a
++//! constructor method
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ pub Foo<T> where T: Default + 'static {
++ fn build() -> MockFoo<T>;
++ }
++}
++
++#[test]
++fn returning_once() {
++ let ctx = MockFoo::<i16>::build_context();
++ ctx.expect()
++ .return_once(MockFoo::<i16>::default);
++
++ let _mock: MockFoo<i16> = MockFoo::<i16>::build();
++}
+diff --git a/tests/mock_generic_method_on_generic_struct_returning_nonstatic.rs b/tests/mock_generic_method_on_generic_struct_returning_nonstatic.rs
+new file mode 100644
+index 0000000..819e70a
+--- /dev/null
++++ b/tests/mock_generic_method_on_generic_struct_returning_nonstatic.rs
+@@ -0,0 +1,116 @@
++//! Mocking a generic method whose return value's lifetime is a generic
++//! parameter on a generic struct requires extra care for the Expectation
++//! object's type generics.
++//! https://github.com/asomers/mockall/issues/306
++#![deny(warnings)]
++
++use mockall::*;
++
++#[derive(Clone)]
++struct X<'a>(&'a u32);
++
++trait Bong {
++ fn trait_foo<'a>(&self) -> X<'a>;
++ fn trait_baz<'a>(&self) -> &X<'a>;
++}
++
++mock! {
++ Thing<T> {
++ fn foo<'a>(&self) -> X<'a>;
++
++ // XXX static methods don't work yet.
++ // fn bar<'a>() -> X<'a>;
++
++ fn baz<'a>(&self) -> &X<'a>;
++
++ // Methods returning a mutable reference to a non-static value won't
++ // work unless 'a is static. I doubt there are any real-life methods
++ // that fit this pattern; open an issue if you find one.
++ //fn bang<'a>(&mut self) -> &mut X<'a>;
++
++ // Generic methods can't return non-static values either, because
++ // Mockall requires generic methods' generic parameters to implement
++ // std::any::Any, which means they must be 'static.
++ //fn bean<'a, T: 'static>(&self, t: T) -> X<'a>;
++ }
++ // The same types of methods should work if they are Trait methods.
++ impl<T> Bong for Thing<T> {
++ fn trait_foo<'a>(&self) -> X<'a>;
++ fn trait_baz<'a>(&self) -> &X<'a>;
++ }
++}
++
++#[test]
++fn return_static() {
++ const D: u32 = 42;
++ let x = X(&D);
++ let mut thing = MockThing::<u32>::new();
++ thing.expect_foo()
++ .return_const(x);
++
++ assert_eq!(42u32, *thing.foo().0);
++}
++
++#[test]
++fn return_static_ref() {
++ const D: u32 = 42;
++ let x = X(&D);
++ let mut thing = MockThing::<u32>::new();
++ thing.expect_baz()
++ .return_const(x);
++
++ assert_eq!(42u32, *thing.baz().0);
++}
++
++// It isn't possible to safely set an expectation for a non-'static return value
++// (because the mock object doesn't have any lifetime parameters itself), but
++// unsafely setting such an expectation is a common use case.
++#[test]
++fn return_nonstatic() {
++ let d = 42u32;
++ let x = X(&d);
++ let xstatic: X<'static> = unsafe{ std::mem::transmute(x) };
++ let mut thing = MockThing::<u32>::new();
++ thing.expect_foo()
++ .returning(move || xstatic.clone());
++
++ assert_eq!(42u32, *thing.foo().0);
++}
++
++mod trait_methods {
++ use super::*;
++
++ #[test]
++ fn return_static() {
++ const D: u32 = 42;
++ let x = X(&D);
++ let mut thing = MockThing::<u32>::new();
++ thing.expect_trait_foo()
++ .return_const(x);
++
++ assert_eq!(42u32, *thing.trait_foo().0);
++ }
++
++ #[test]
++ fn return_static_ref() {
++ const D: u32 = 42;
++ let x = X(&D);
++ let mut thing = MockThing::<u32>::new();
++ thing.expect_trait_baz()
++ .return_const(x);
++
++ assert_eq!(42u32, *thing.trait_baz().0);
++ }
++
++ #[test]
++ fn return_nonstatic() {
++ let d = 42u32;
++ let x = X(&d);
++ let xstatic: X<'static> = unsafe{ std::mem::transmute(x) };
++ let mut thing = MockThing::<u32>::new();
++ thing.expect_trait_foo()
++ .returning(move || xstatic.clone());
++
++ assert_eq!(42u32, *thing.trait_foo().0);
++ }
++}
+diff --git a/tests/mock_generic_method_returning_nonstatic.rs b/tests/mock_generic_method_returning_nonstatic.rs
+new file mode 100644
+index 0000000..7b85ee1
+--- /dev/null
++++ b/tests/mock_generic_method_returning_nonstatic.rs
+@@ -0,0 +1,117 @@
++// vim: tw=80
++//! A generic method whose return value's lifetime is a generic parameter is a
++//! special case. Mockall can only mock such methods if the expectation is
++//! 'static.
++//! https://github.com/asomers/mockall/issues/76
++#![deny(warnings)]
++
++use mockall::*;
++
++#[derive(Clone)]
++struct X<'a>(&'a u32);
++
++trait Bong {
++ fn trait_foo<'a>(&self) -> X<'a>;
++ fn trait_baz<'a>(&self) -> &X<'a>;
++}
++
++mock! {
++ Thing {
++ fn foo<'a>(&self) -> X<'a>;
++
++ // XXX static methods don't work yet.
++ // fn bar<'a>() -> X<'a>;
++
++ fn baz<'a>(&self) -> &X<'a>;
++
++ // Methods returning a mutable reference to a non-static value won't
++ // work unless 'a is static. I doubt there are any real-life methods
++ // that fit this pattern; open an issue if you find one.
++ // fn bang<'a>(&mut self) -> &mut X<'a>;
++
++ // Generic methods can't return non-static values either, because
++ // Mockall requires generic methods' generic parameters to implement
++ // std::any::Any, which means they must be 'static.
++ //fn bean<'a, T: 'static>(&self, t: T) -> X<'a>;
++ }
++ // The same types of methods should work if they are Trait methods.
++ impl Bong for Thing {
++ fn trait_foo<'a>(&self) -> X<'a>;
++ fn trait_baz<'a>(&self) -> &X<'a>;
++ }
++}
++
++#[test]
++fn return_static() {
++ const D: u32 = 42;
++ let x = X(&D);
++ let mut thing = MockThing::new();
++ thing.expect_foo()
++ .return_const(x);
++
++ assert_eq!(42u32, *thing.foo().0);
++}
++
++#[test]
++fn return_static_ref() {
++ const D: u32 = 42;
++ let x = X(&D);
++ let mut thing = MockThing::new();
++ thing.expect_baz()
++ .return_const(x);
++
++ assert_eq!(42u32, *thing.baz().0);
++}
++
++// It isn't possible to safely set an expectation for a non-'static return value
++// (because the mock object doesn't have any lifetime parameters itself), but
++// unsafely setting such an expectation is a common use case.
++#[test]
++fn return_nonstatic() {
++ let d = 42u32;
++ let x = X(&d);
++ let xstatic: X<'static> = unsafe{ std::mem::transmute(x) };
++ let mut thing = MockThing::new();
++ thing.expect_foo()
++ .returning(move || xstatic.clone());
++
++ assert_eq!(42u32, *thing.foo().0);
++}
++
++mod trait_methods {
++ use super::*;
++
++ #[test]
++ fn return_static() {
++ const D: u32 = 42;
++ let x = X(&D);
++ let mut thing = MockThing::new();
++ thing.expect_trait_foo()
++ .return_const(x);
++
++ assert_eq!(42u32, *thing.trait_foo().0);
++ }
++
++ #[test]
++ fn return_static_ref() {
++ const D: u32 = 42;
++ let x = X(&D);
++ let mut thing = MockThing::new();
++ thing.expect_trait_baz()
++ .return_const(x);
++
++ assert_eq!(42u32, *thing.trait_baz().0);
++ }
++
++ #[test]
++ fn return_nonstatic() {
++ let d = 42u32;
++ let x = X(&d);
++ let xstatic: X<'static> = unsafe{ std::mem::transmute(x) };
++ let mut thing = MockThing::new();
++ thing.expect_trait_foo()
++ .returning(move || xstatic.clone());
++
++ assert_eq!(42u32, *thing.trait_foo().0);
++ }
++}
+diff --git a/tests/mock_generic_method_with_lifetime_parameter.rs b/tests/mock_generic_method_with_lifetime_parameter.rs
+new file mode 100644
+index 0000000..3a3d97d
+--- /dev/null
++++ b/tests/mock_generic_method_with_lifetime_parameter.rs
+@@ -0,0 +1,65 @@
++// vim: tw=80
++//! A generic method whose only generic parameter is a lifetime parameter is,
++//! from Mockall's perspective, pretty much the same as a non-generic method.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[derive(Debug, Eq)]
++struct X<'a>(&'a u32);
++
++impl<'a> PartialEq for X<'a> {
++ fn eq(&self, other: &X<'a>) -> bool {
++ self.0 == other.0
++ }
++}
++
++mock!{
++ Foo {
++ fn foo<'a>(&self, x: &'a X<'a>) -> u32;
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .return_const(42u32);
++ let x = X(&5);
++ assert_eq!(42, mock.foo(&x));
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|f| *f.0);
++ let x = X(&5);
++ assert_eq!(5, mock.foo(&x));
++}
++
++// I can't get this to work. How can I create a Predicate that's valid for all
++// lifetimes? 'static should be reduceable to any other lifetime, but rustc
++// doesn't seem to understand that.
++//#[test]
++//fn with() {
++ //const X1: u32 = 5;
++ //const OTHER: X<'static> = X(&X1);
++ //let mut mock = MockFoo::new();
++ //mock.expect_foo()
++ //.with(mockall::predicate::eq(&OTHER))
++ //.return_const(42u32);
++ //let inner = 5;
++ //let x = X(&5);
++ //assert_eq!(42, mock.foo(&x));
++//}
++
++#[test]
++fn withf() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .withf(|f| *f.0 == 5)
++ .return_const(42u32);
++ let x = X(&5);
++ assert_eq!(42, mock.foo(&x));
++}
+diff --git a/tests/mock_generic_method_with_where_clause.rs b/tests/mock_generic_method_with_where_clause.rs
+new file mode 100644
+index 0000000..8aaa7cb
+--- /dev/null
++++ b/tests/mock_generic_method_with_where_clause.rs
+@@ -0,0 +1,43 @@
++// vim: tw=80
++#![deny(warnings)]
++use mockall::*;
++
++struct G<T> where T: Copy {t: T}
++
++mock! {
++ Foo {
++ fn foo<T>(&self, t: T) -> G<T> where T: Copy + 'static;
++ fn bar<T>(&self, g: G<T>) -> T where T: Copy + 'static;
++ fn baz<T>(&self) -> &G<T> where T: Copy + 'static;
++ fn bean<T>(&mut self) -> &mut G<T> where T: Copy + 'static;
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<u32>()
++ .returning(|t| G{t});
++ assert_eq!(42, mock.foo(42u32).t);
++
++ mock.expect_bar::<u32>()
++ .returning(|g| g.t);
++ assert_eq!(42u32, mock.bar(G{t: 42}));
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz::<u32>()
++ .return_const(G{t: 42});
++ assert_eq!(42u32, mock.baz().t);
++}
++
++#[test]
++fn return_var() {
++ let mut mock = MockFoo::new();
++ mock.expect_bean::<u32>()
++ .return_var(G{t: 42});
++ mock.bean::<u32>().t += 1;
++ assert_eq!(43u32, mock.bean().t);
++}
+diff --git a/tests/mock_generic_methods_returning_mutable_reference.rs b/tests/mock_generic_methods_returning_mutable_reference.rs
+new file mode 100644
+index 0000000..1e708b6
+--- /dev/null
++++ b/tests/mock_generic_methods_returning_mutable_reference.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock!{
++ MyStruct {
++ fn foo<T: 'static>(&mut self, t: T) -> &mut u32;
++ }
++}
++
++#[test]
++fn return_var() {
++ let mut mock = MockMyStruct::new();
++ mock.expect_foo::<i16>().return_var(5u32);
++ *mock.foo(1i16) += 1;
++ assert_eq!(6u32, *mock.foo(2i16));
++}
+diff --git a/tests/mock_generic_return.rs b/tests/mock_generic_return.rs
+new file mode 100644
+index 0000000..8fd2a0a
+--- /dev/null
++++ b/tests/mock_generic_return.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ Foo {
++ fn foo<O: 'static>(&self) -> O;
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<i32>().return_const(42i32);
++ mock.expect_foo::<u16>().return_const(69u16);
++ assert_eq!(42i32, mock.foo());
++ assert_eq!(69u16, mock.foo());
++}
+diff --git a/tests/mock_generic_static_method_with_where_clause.rs b/tests/mock_generic_static_method_with_where_clause.rs
+new file mode 100644
+index 0000000..f70d4c7
+--- /dev/null
++++ b/tests/mock_generic_static_method_with_where_clause.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++#![deny(warnings)]
++// multiple bound locations is deliberate; we want to ensure that Mockall can
++// handle it correctly.
++#![allow(clippy::multiple_bound_locations)]
++
++use mockall::*;
++
++struct G<T> where T: Copy {t: T}
++
++mock! {
++ Foo {
++ fn make_g<T: 'static>(x: T) -> G<T> where T: Copy;
++ }
++}
++
++#[test]
++fn returning() {
++ let ctx = MockFoo::make_g_context();
++ ctx.expect::<i16>()
++ .returning(|t| G{t});
++ let g = MockFoo::make_g(42i16);
++ assert_eq!(g.t, 42i16);
++}
+diff --git a/tests/mock_generic_struct.rs b/tests/mock_generic_struct.rs
+new file mode 100644
+index 0000000..0863b44
+--- /dev/null
++++ b/tests/mock_generic_struct.rs
+@@ -0,0 +1,33 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++#[derive(Clone)]
++struct NonCopy(u32);
++
++// A struct with a definition like this:
++// pub struct ExtGenericStruct<T: Clone> {
++// _x: i16
++// }
++// impl<T: Clone> ExtGenericStruct<T> {
++// fn foo(&self, _x: T) -> T {
++// 42
++// }
++// }
++// Could be mocked like this:
++mock!{
++ pub ExtGenericStruct<T: Clone> {
++ fn foo(&self, x: T) -> T;
++ }
++}
++
++#[test]
++#[allow(clippy::redundant_clone)]
++fn returning() {
++ let mut mock = MockExtGenericStruct::<NonCopy>::new();
++ // An explicit .clone() is required so as not to return by move
++ mock.expect_foo()
++ .returning(|x| x.clone());
++ assert_eq!(5, mock.foo(NonCopy(5)).0);
++}
+diff --git a/tests/mock_generic_struct_with_bounds.rs b/tests/mock_generic_struct_with_bounds.rs
+new file mode 100644
+index 0000000..4f15836
+--- /dev/null
++++ b/tests/mock_generic_struct_with_bounds.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ pub Foo<T: Clone + Copy> {
++ fn foo(&self, x: u32) -> i64;
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::<i16>::new();
++ mock.expect_foo().returning(i64::from);
++ assert_eq!(5, mock.foo(5));
++}
+diff --git a/tests/mock_generic_struct_with_generic_method.rs b/tests/mock_generic_struct_with_generic_method.rs
+new file mode 100644
+index 0000000..92fc46f
+--- /dev/null
++++ b/tests/mock_generic_struct_with_generic_method.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock!{
++ pub Foo<T: Clone + 'static> {
++ fn foo<Q: 'static>(&self, q: Q) -> T;
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::<u32>::new();
++ mock.expect_foo::<i16>()
++ .return_const(100_000u32);
++ assert_eq!(100_000, mock.foo(-5i16));
++}
+diff --git a/tests/mock_generic_struct_with_generic_static_method.rs b/tests/mock_generic_struct_with_generic_static_method.rs
+new file mode 100644
+index 0000000..1f93f3f
+--- /dev/null
++++ b/tests/mock_generic_struct_with_generic_static_method.rs
+@@ -0,0 +1,102 @@
++// vim: tw=80
++//! A generic struct with a generic method on a different parameter
++#![deny(warnings)]
++
++use mockall::*;
++use std::sync::Mutex;
++
++mock! {
++ Foo<T: 'static + std::fmt::Debug> {
++ fn foo<Q: 'static + std::fmt::Debug>(t: T, q: Q) -> u64;
++ }
++}
++
++static FOO_MTX: Mutex<()> = Mutex::new(());
++
++// Checkpointing the mock object should not checkpoint static methods too
++#[test]
++fn checkpoint() {
++ let _m = FOO_MTX.lock();
++
++ let mut mock = MockFoo::<u32>::new();
++ let ctx = MockFoo::<u32>::foo_context();
++ ctx.expect::<i16>()
++ .returning(|_, _| 0)
++ .times(1..3);
++ mock.checkpoint();
++ MockFoo::foo(42u32, 69i16);
++}
++
++// It should also be possible to checkpoint just the context object
++#[test]
++#[should_panic(expected =
++ "MockFoo::foo: Expectation(<anything>) called 0 time(s) which is fewer than expected 1")]
++fn ctx_checkpoint() {
++ let _m = FOO_MTX.lock();
++ let ctx = MockFoo::<u32>::foo_context();
++ ctx.expect::<i16>()
++ .returning(|_, _| 0)
++ .times(1..3);
++ ctx.checkpoint();
++ panic!("Shouldn't get here!");
++}
++
++// Expectations should be cleared when a context object drops
++#[test]
++#[should_panic(expected = "MockFoo::foo(42, 69): No matching expectation found")]
++fn ctx_hygiene() {
++ let _m = FOO_MTX.lock();
++ {
++ let ctx0 = MockFoo::<u32>::foo_context();
++ ctx0.expect::<i16>()
++ .returning(|_, _| 0);
++ }
++ MockFoo::foo(42, 69);
++}
++
++#[cfg_attr(not(feature = "nightly"), ignore)]
++#[cfg_attr(not(feature = "nightly"), allow(unused_must_use))]
++#[test]
++fn return_default() {
++ let _m = FOO_MTX.lock();
++
++ let ctx = MockFoo::<u32>::foo_context();
++ ctx.expect::<i16>();
++ MockFoo::foo(5u32, 6i16);
++}
++
++#[test]
++fn returning() {
++ let _m = FOO_MTX.lock();
++
++ let ctx = MockFoo::<u32>::foo_context();
++ ctx.expect::<i16>()
++ .returning(|_, _| 0);
++ MockFoo::foo(41u32, 42i16);
++}
++
++#[test]
++fn two_matches() {
++ let _m = FOO_MTX.lock();
++
++ let ctx = MockFoo::<u32>::foo_context();
++ ctx.expect::<i16>()
++ .with(predicate::eq(42u32), predicate::eq(0i16))
++ .return_const(99u64);
++ ctx.expect::<i16>()
++ .with(predicate::eq(69u32), predicate::eq(0i16))
++ .return_const(101u64);
++ assert_eq!(101, MockFoo::foo(69u32, 0i16));
++ assert_eq!(99, MockFoo::foo(42u32, 0i16));
++}
++
++#[test]
++fn with() {
++ let _m = FOO_MTX.lock();
++
++ let ctx = MockFoo::<u32>::foo_context();
++ ctx.expect::<i16>()
++ .with(predicate::eq(42u32), predicate::eq(99i16))
++ .returning(|_, _| 0);
++ MockFoo::foo(42u32, 99i16);
++}
+diff --git a/tests/mock_generic_struct_with_generic_trait.rs b/tests/mock_generic_struct_with_generic_trait.rs
+new file mode 100644
+index 0000000..c955441
+--- /dev/null
++++ b/tests/mock_generic_struct_with_generic_trait.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo<T> {
++ fn foo(&self, x: T) -> T;
++}
++mock! {
++ Bar<T, Z> {}
++ impl<T, Z> Foo<T> for Bar<T, Z> {
++ fn foo(&self, x: T) -> T;
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockBar::<u32, u64>::new();
++ mock.expect_foo()
++ .returning(|x| x);
++ assert_eq!(5u32, mock.foo(5u32));
++}
+diff --git a/tests/mock_generic_struct_with_generic_trait_with_different_bounds.rs b/tests/mock_generic_struct_with_generic_trait_with_different_bounds.rs
+new file mode 100644
+index 0000000..efb0d58
+--- /dev/null
++++ b/tests/mock_generic_struct_with_generic_trait_with_different_bounds.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo<T> {
++ fn foo(&self, x: T) -> T;
++}
++mock! {
++ Bar<T> {}
++ impl<T: Copy> Foo<T> for Bar<T> {
++ fn foo(&self, x: T) -> T;
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockBar::<u32>::new();
++ mock.expect_foo()
++ .returning(|x| x);
++ assert_eq!(5u32, mock.foo(5u32));
++}
+diff --git a/tests/mock_generic_struct_with_nondefault_parameter.rs b/tests/mock_generic_struct_with_nondefault_parameter.rs
+new file mode 100644
+index 0000000..40bfd82
+--- /dev/null
++++ b/tests/mock_generic_struct_with_nondefault_parameter.rs
+@@ -0,0 +1,37 @@
++// vim: tw=80
++//! mock a generic struct and instantiate it with a parameter type that does not
++//! implement Default
++#![deny(warnings)]
++
++use mockall::*;
++
++struct NonDefault();
++
++trait Foo<T> {
++ fn foo(&self) -> T;
++}
++mock! {
++ ExternalStruct<T> {}
++ impl<T> Foo<T> for ExternalStruct<T> {
++ fn foo(&self) -> T;
++ }
++}
++
++#[test]
++#[should_panic(expected =
++ "MockExternalStruct::foo: Expectation(<anything>) Can only return default values for types that impl std::Default")]
++#[cfg_attr(not(feature = "nightly"), ignore)]
++#[cfg_attr(not(feature = "nightly"), allow(unused_must_use))]
++fn return_default() {
++ let mut mock = MockExternalStruct::<NonDefault>::new();
++ mock.expect_foo();
++ mock.foo();
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockExternalStruct::<NonDefault>::new();
++ mock.expect_foo()
++ .returning(NonDefault);
++ mock.foo();
++}
+diff --git a/tests/mock_generic_struct_with_static_method.rs b/tests/mock_generic_struct_with_static_method.rs
+new file mode 100644
+index 0000000..6b2928b
+--- /dev/null
++++ b/tests/mock_generic_struct_with_static_method.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! static non-generic methods of generic structs shouldn't require any special
++//! treatment when mocking. Prior to version 0.3.0, the struct's generic
++//! parameters had to be duplicated as generic parameters of the method.
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ Foo<T: 'static> {
++ fn foo(t: T);
++ }
++}
++
++#[test]
++fn returning() {
++ let ctx = MockFoo::<u32>::foo_context();
++ ctx.expect()
++ .returning(|_| ());
++ MockFoo::foo(42u32);
++}
+diff --git a/tests/mock_generic_struct_with_trait.rs b/tests/mock_generic_struct_with_trait.rs
+new file mode 100644
+index 0000000..a772c99
+--- /dev/null
++++ b/tests/mock_generic_struct_with_trait.rs
+@@ -0,0 +1,23 @@
++// vim: ts=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++ fn foo(&self, x: u32) -> u32;
++}
++
++mock! {
++ Bar<T: Copy> {}
++ impl<T: Copy> Foo for Bar<T> {
++ fn foo(&self, x: u32) -> u32;
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockBar::<u32>::new();
++ mock.expect_foo()
++ .return_const(43u32);
++ assert_eq!(43, mock.foo(42));
++}
+diff --git a/tests/mock_generic_struct_with_trait_with_associated_types.rs b/tests/mock_generic_struct_with_trait_with_associated_types.rs
+new file mode 100644
+index 0000000..ced6e9e
+--- /dev/null
++++ b/tests/mock_generic_struct_with_trait_with_associated_types.rs
+@@ -0,0 +1,20 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ Foo<T> {}
++ impl<T> Iterator for Foo<T> {
++ type Item=T;
++ fn next(&mut self) -> Option<T>;
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::<u32>::new();
++ mock.expect_next()
++ .return_const(None);
++ assert!(mock.next().is_none());
++}
+diff --git a/tests/mock_generic_struct_with_where_clause.rs b/tests/mock_generic_struct_with_where_clause.rs
+new file mode 100644
+index 0000000..14a8e10
+--- /dev/null
++++ b/tests/mock_generic_struct_with_where_clause.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! A generic struct with a where clause
++#![deny(warnings)]
++
++// An explicit clone is required so as not to return by move
++#![allow(clippy::clone_on_copy)]
++
++use mockall::*;
++
++mock! {
++ Foo<T> where T:Clone {
++ fn foo(&self, t: T) -> T;
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|t: u32| t.clone());
++ assert_eq!(5u32, mock.foo(5u32));
++}
+diff --git a/tests/mock_generic_struct_with_where_clause_and_trait.rs b/tests/mock_generic_struct_with_where_clause_and_trait.rs
+new file mode 100644
+index 0000000..fd9b5ac
+--- /dev/null
++++ b/tests/mock_generic_struct_with_where_clause_and_trait.rs
+@@ -0,0 +1,31 @@
++// vim: tw=80
++//! A generic struct with a where clause, that also implements a trait
++#![deny(warnings)]
++
++// An explicit clone is required so as not to return by move
++#![allow(clippy::clone_on_copy)]
++
++use mockall::*;
++
++trait Bar {
++ fn bar(&self);
++}
++mock! {
++ Foo<T> where T: Clone {
++ fn foo(&self, t: T) -> T;
++ }
++ impl<T> Bar for Foo<T> where T: Clone {
++ fn bar(&self);
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|t: u32| t.clone());
++ mock.expect_bar()
++ .returning(|| ());
++ assert_eq!(5u32, mock.foo(5u32));
++ mock.bar();
++}
+diff --git a/tests/mock_generic_trait.rs b/tests/mock_generic_trait.rs
+new file mode 100644
+index 0000000..24413bc
+--- /dev/null
++++ b/tests/mock_generic_trait.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++ fn foo(&self);
++}
++
++mock! {
++ Bar<T> {}
++ impl<T> Foo for Bar<T> {
++ fn foo(&self);
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockBar::<u32>::new();
++ mock.expect_foo().return_const(());
++ mock.foo();
++}
+diff --git a/tests/mock_impl_generic_trait.rs b/tests/mock_impl_generic_trait.rs
+new file mode 100644
+index 0000000..6819c81
+--- /dev/null
++++ b/tests/mock_impl_generic_trait.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait MyTrait<T> {}
++
++struct MyStruct<T>(T);
++impl<T> MyTrait<T> for MyStruct<T> {}
++
++mock!{
++ Foo {
++ fn foo<R: 'static>(&self) -> impl MyTrait<R>;
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<u32>().returning(|| Box::new(MyStruct(42u32)));
++ let _mto: Box<dyn MyTrait<u32>> = mock.foo();
++}
+diff --git a/tests/mock_impl_trait.rs b/tests/mock_impl_trait.rs
+new file mode 100644
+index 0000000..fb1bb7a
+--- /dev/null
++++ b/tests/mock_impl_trait.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++//! a method that returns impl Trait
++#![deny(warnings)]
++
++use mockall::*;
++use std::fmt::Debug;
++
++mock!{
++ Foo {
++ fn foo(&self) -> impl Debug + Send;
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo().returning(|| Box::new(4));
++ format!("{:?}", mock.foo());
++}
+diff --git a/tests/mock_inherited_traits.rs b/tests/mock_inherited_traits.rs
+new file mode 100644
+index 0000000..940b822
+--- /dev/null
++++ b/tests/mock_inherited_traits.rs
+@@ -0,0 +1,32 @@
++// vim: tw=80
++//! A struct that implements a trait that inherits another trait
++#![deny(warnings)]
++
++use mockall::*;
++
++trait A {
++ fn foo(&self);
++}
++
++trait B: A {
++ fn bar(&self);
++}
++
++mock!{
++ B {}
++ impl A for B {
++ fn foo(&self);
++ }
++ impl B for B {
++ fn bar(&self);
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockB::new();
++ mock.expect_foo().returning(|| ());
++ mock.expect_bar().returning(|| ());
++ mock.foo();
++ mock.bar();
++}
+diff --git a/tests/mock_life0.rs b/tests/mock_life0.rs
+new file mode 100644
+index 0000000..722f78e
+--- /dev/null
++++ b/tests/mock_life0.rs
+@@ -0,0 +1,16 @@
++// vim: tw=80
++//! mock a method whose self parameter has an explicit lifetime
++//! https://github.com/asomers/mockall/issues/95
++#![deny(warnings)]
++
++use mockall::*;
++
++mock!{
++ Foo {
++ fn foo<'life0>(&'life0 self, x: u32) -> u32;
++ }
++}
++
++// TODO: test that the mock method respects the lifetime bound, once Mockall
++// supports mocking non-static structs
++// (https://github.com/asomers/mockall/issues/4)
+diff --git a/tests/mock_multiple_generic_arguments.rs b/tests/mock_multiple_generic_arguments.rs
+new file mode 100644
+index 0000000..1221c71
+--- /dev/null
++++ b/tests/mock_multiple_generic_arguments.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++
++mock! {
++ Foo {
++ fn foo<T: 'static, Q: 'static>(&self, t: T, q: Q);
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo::<i16, i32>().return_const(());
++ mock.foo(0i16, 1i32)
++}
+diff --git a/tests/mock_multiple_traits.rs b/tests/mock_multiple_traits.rs
+new file mode 100644
+index 0000000..df4c0e1
+--- /dev/null
++++ b/tests/mock_multiple_traits.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! A struct that implements multiple traits
++#![deny(warnings)]
++
++use mockall::*;
++
++trait A {}
++trait B {}
++mock!{
++ MultiTrait {}
++ impl A for MultiTrait {}
++ impl B for MultiTrait {}
++}
++
++#[test]
++fn new() {
++ fn foo<T: A + B>(_t: T) {}
++
++ let mock = MockMultiTrait::new();
++ foo(mock);
++}
+diff --git a/tests/mock_nonlocal_trait.rs b/tests/mock_nonlocal_trait.rs
+new file mode 100644
+index 0000000..5a140c6
+--- /dev/null
++++ b/tests/mock_nonlocal_trait.rs
+@@ -0,0 +1,28 @@
++// vim: tw=80
++//! A trait that isn't imported directly into the local namespace
++#![deny(warnings)]
++
++use mockall::*;
++
++mod my_module {
++ pub trait Foo {
++ fn foo(&self) -> i32;
++ }
++}
++
++mock! {
++ Bar {}
++ impl my_module::Foo for Bar {
++ fn foo(&self) -> i32;
++ }
++}
++
++#[test]
++fn returning() {
++ use my_module::Foo;
++
++ let mut mock = MockBar::new();
++ mock.expect_foo()
++ .returning(|| 42);
++ assert_eq!(42, mock.foo());
++}
+diff --git a/tests/mock_nonpub.rs b/tests/mock_nonpub.rs
+new file mode 100644
+index 0000000..a349175
+--- /dev/null
++++ b/tests/mock_nonpub.rs
+@@ -0,0 +1,37 @@
++// vim: tw=80
++//! methods can use non-public types, as long as the object's visibility is
++//! compatible.
++#![deny(warnings)]
++
++use mockall::*;
++
++mod outer {
++ struct SuperT();
++ trait SuperTrait {}
++
++ mod inner {
++ use super::super::mock;
++
++ pub(crate) struct PubCrateT();
++ struct PrivT();
++
++ mock! {
++ Foo {
++ fn foo(&self, x: PubCrateT) -> PubCrateT;
++ fn bar(&self, x: PrivT) -> PrivT;
++ fn baz(&self, x: super::SuperT) -> super::SuperT;
++ fn refbaz(&self, x: super::SuperT) -> &super::SuperT;
++ fn refmutbaz(&mut self, x: super::SuperT) -> &mut super::SuperT;
++ fn staticbaz(x: super::SuperT) -> super::SuperT;
++ fn bang(&self, x: crate::outer::SuperT) -> crate::outer::SuperT;
++ fn bean(&self, x: self::PrivT) -> self::PrivT;
++ fn goo<T: super::SuperTrait + 'static>(t: T);
++ fn goo_wc<T>(t: T) where T: super::SuperTrait + 'static;
++ fn boob<F: Fn(u32) -> super::SuperT + 'static>(&self, f: F)
++ -> u32;
++ fn boobwc<F>(&self, f: F) -> u32
++ where F: Fn(u32) -> super::SuperT + 'static;
++ }
++ }
++ }
++}
+diff --git a/tests/mock_ref_and_nonref_arguments.rs b/tests/mock_ref_and_nonref_arguments.rs
+new file mode 100644
+index 0000000..b5330df
+--- /dev/null
++++ b/tests/mock_ref_and_nonref_arguments.rs
+@@ -0,0 +1,34 @@
++// vim: tw=80
++//! A method that has both a reference and a nonreference argument
++#![deny(warnings)]
++
++use mockall::*;
++
++mock!{
++ Foo {
++ fn foo(&self, i0: i32, i1: &u16) -> i32;
++ }
++}
++
++#[test]
++fn with() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .with(predicate::eq(42), predicate::eq(1))
++ .returning(|x, y| x + i32::from(*y));
++ let x = 42i32;
++ let y = 1u16;
++ assert_eq!(43i32, mock.foo(x, &y));
++}
++
++#[test]
++fn withf() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .withf(|x, y| *x == i32::from(*y))
++ .returning(|x, y| x + i32::from(*y));
++ let x = 42i32;
++ let y = 42u16;
++ assert_eq!(84i32, mock.foo(x, &y));
++}
++
+diff --git a/tests/mock_reference_arguments.rs b/tests/mock_reference_arguments.rs
+new file mode 100644
+index 0000000..53761b5
+--- /dev/null
++++ b/tests/mock_reference_arguments.rs
+@@ -0,0 +1,142 @@
++// vim: tw=80
++//! A struct with methods that take arguments by reference
++#![deny(warnings)]
++
++use mockall::*;
++
++const X: u32 = 99;
++
++mock!{
++ Foo {
++ fn foo(&self, x: &u32) -> u32;
++ fn bar(&self, y: &'static u32);
++ }
++}
++
++mod r#match {
++ use super::*;
++
++ #[test]
++ fn with() {
++ const Y: u32 = 5;
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .with(predicate::eq(5u32))
++ .returning(|x| *x);
++ mock.expect_bar()
++ .with(predicate::eq(99u32))
++ .returning(|_| ());
++ let r = mock.foo(&Y);
++ assert_eq!(5, r);
++ mock.bar(&X);
++ }
++
++ #[test]
++ fn withf() {
++ const Y: u32 = 5;
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .withf(|x| *x == 5)
++ .returning(|x| *x);
++ mock.expect_bar()
++ .withf(|x| *x == 99)
++ .returning(|_| ());
++ let r = mock.foo(&Y);
++ assert_eq!(5, r);
++ mock.bar(&X);
++ }
++}
++
++mod times {
++ use super::*;
++ const X: u32 = 42;
++
++ #[test]
++ fn ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|_| 0)
++ .times(2);
++ mock.foo(&X);
++ mock.foo(&X);
++ }
++
++ #[test]
++ #[should_panic(
++ expected = "MockFoo::foo: Expectation(<anything>) called 1 time(s) which is fewer than expected 2"
++ )]
++ fn too_few() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|_| 0)
++ .times(2);
++ mock.foo(&X);
++ }
++
++ #[test]
++ #[should_panic(
++ expected = "MockFoo::foo: Expectation(<anything>) called 3 times which is more than the expected 2"
++ )]
++ fn too_many() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|_| 0)
++ .times(2);
++ mock.foo(&X);
++ mock.foo(&X);
++ mock.foo(&X);
++ // Verify that we panic quickly and don't reach code below this point.
++ panic!("Shouldn't get here!");
++ }
++
++ #[test]
++ fn range_ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|_| 0)
++ .times(2..4);
++ mock.foo(&X);
++ mock.foo(&X);
++ }
++
++ #[test]
++ #[should_panic(
++ expected = "MockFoo::foo: Expectation(<anything>) called 1 time(s) which is fewer than expected 2"
++ )]
++ fn range_too_few() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|_| 0)
++ .times(2..4);
++ mock.foo(&X);
++ }
++
++ #[test]
++ #[should_panic(
++ expected = "MockFoo::foo: Expectation(<anything>) called 4 times which is more than the expected 3"
++ )]
++ fn range_too_many() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|_| 0)
++ .times(2..4);
++ mock.foo(&X);
++ mock.foo(&X);
++ mock.foo(&X);
++ mock.foo(&X);
++ // Verify that we panic quickly and don't reach code below this point.
++ panic!("Shouldn't get here!");
++ }
++}
++
++#[test]
++fn times_full() {
++ const X: u32 = 42;
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|_| 0)
++ .times(1)
++ .times(..);
++ mock.foo(&X);
++ mock.foo(&X);
++}
+diff --git a/tests/mock_refmut_arguments.rs b/tests/mock_refmut_arguments.rs
+new file mode 100644
+index 0000000..66589c4
+--- /dev/null
++++ b/tests/mock_refmut_arguments.rs
+@@ -0,0 +1,52 @@
++// vim: tw=80
++//! A struct with methods that take arguments by mutable reference.
++#![deny(warnings)]
++
++use std::mem;
++
++use mockall::*;
++
++mock!{
++ Foo {
++ fn foo(&self, x: &mut u32);
++ // This is almost never safe, but it should still work.
++ fn bar(&self, y: &'static mut u32);
++ }
++}
++
++#[test]
++fn returning() {
++ let mut x: u32 = 5;
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .withf(|x| *x == 5)
++ .returning(|x| { *x = 42;} );
++ mock.foo(&mut x);
++ assert_eq!(x, 42);
++}
++
++#[test]
++fn with() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .with(predicate::eq(0u32))
++ .returning(|x| {*x = 6;});
++ mock.expect_foo()
++ .with(predicate::eq(42u32))
++ .returning(|x| {*x = 5;});
++ let mut x = 42u32;
++ mock.foo(&mut x);
++ assert_eq!(5, x);
++}
++
++#[test]
++fn static_mut() {
++ let mut x: u32 = 5;
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .withf(|x| *x == 5)
++ .returning(|x| { *x = 42;} );
++ // Safe because mock leaves scope before x
++ unsafe { mock.bar(mem::transmute(&mut x)); }
++ assert_eq!(x, 42);
++}
+diff --git a/tests/mock_return_anonymous_lifetime.rs b/tests/mock_return_anonymous_lifetime.rs
+new file mode 100644
+index 0000000..1713c57
+--- /dev/null
++++ b/tests/mock_return_anonymous_lifetime.rs
+@@ -0,0 +1,54 @@
++// vim: tw=80
++//! A mock method should be able to return an object parameterized on the
++//! anonymous lifetime.
++//! https://github.com/asomers/mockall/issues/87
++#![deny(warnings)]
++
++use mockall::*;
++
++#[derive(Clone)]
++struct X<'a>(&'a u32);
++
++trait T {
++ fn trait_method(&self) -> X<'_>;
++}
++
++mock! {
++ Foo {
++ fn inherent_method(&self) -> X<'_>;
++ }
++ impl T for Foo {
++ fn trait_method(&self) -> X<'_>;
++ }
++}
++
++// It isn't possible to safely set an expectation for a non-'static return value
++// (because the mock object doesn't have any lifetime parameters itself), but
++// unsafely setting such an expectation is a common use case.
++mod return_nonstatic {
++ use super::*;
++
++ #[test]
++ fn inherent_method() {
++ let d = 42u32;
++ let x = X(&d);
++ let xstatic: X<'static> = unsafe{ std::mem::transmute(x) };
++ let mut mock = MockFoo::new();
++ mock.expect_inherent_method()
++ .returning(move || xstatic.clone());
++
++ assert_eq!(42u32, *mock.inherent_method().0);
++ }
++ #[test]
++ fn trait_method() {
++ let d = 42u32;
++ let x = X(&d);
++ let xstatic: X<'static> = unsafe{ std::mem::transmute(x) };
++ let mut mock = MockFoo::new();
++ mock.expect_trait_method()
++ .returning(move || xstatic.clone());
++
++ assert_eq!(42u32, *mock.trait_method().0);
++ }
++
++}
+diff --git a/tests/mock_return_dyn_trait.rs b/tests/mock_return_dyn_trait.rs
+new file mode 100644
+index 0000000..a22ea60
+--- /dev/null
++++ b/tests/mock_return_dyn_trait.rs
+@@ -0,0 +1,57 @@
++// vim: tw=80
++//! a method that returns a reference to a trait object
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Test: Sync {
++ fn value(&self) -> i32;
++ fn mutate(&mut self);
++}
++
++impl Test for i32 {
++ fn value(&self) -> i32 {
++ *self
++ }
++
++ fn mutate(&mut self) {
++ *self = 0;
++ }
++}
++
++mock! {
++ Foo {
++ fn ref_dyn(&self) -> &dyn Test;
++ fn static_dyn(&self) -> &'static dyn Test;
++ fn mut_dyn(&mut self) -> &mut dyn Test;
++ }
++}
++
++#[test]
++fn ref_dyn() {
++ let mut mock = MockFoo::new();
++ mock.expect_ref_dyn()
++ .return_const(Box::new(42) as Box<dyn Test>);
++
++ assert_eq!(42, mock.ref_dyn().value());
++}
++
++#[test]
++fn static_dyn() {
++ let mut mock = MockFoo::new();
++ mock.expect_static_dyn()
++ .return_const(&42 as &'static dyn Test);
++
++ assert_eq!(42, mock.static_dyn().value());
++}
++
++#[test]
++fn mut_dyn() {
++ let mut mock = MockFoo::new();
++ mock.expect_mut_dyn()
++ .return_var(Box::new(42) as Box<dyn Test>);
++
++ assert_eq!(42, mock.mut_dyn().value());
++ mock.mut_dyn().mutate();
++ assert_eq!(0, mock.mut_dyn().value());
++}
+diff --git a/tests/mock_return_mutable_reference.rs b/tests/mock_return_mutable_reference.rs
+new file mode 100644
+index 0000000..7bc0ed4
+--- /dev/null
++++ b/tests/mock_return_mutable_reference.rs
+@@ -0,0 +1,89 @@
++// vim: tw=80
++//! A struct with a method that returns a mutable reference
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ Foo {
++ fn foo(&mut self, i: u32) -> &mut u32;
++ }
++}
++
++#[test]
++#[cfg_attr(not(feature = "nightly"),
++ should_panic(expected = "MockFoo::foo: Expectation(<anything>) Returning default values requires"))]
++#[cfg_attr(not(feature = "nightly"), allow(unused_must_use))]
++fn return_default() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo();
++ let r = mock.foo(0);
++ assert_eq!(u32::default(), *r);
++}
++
++#[test]
++fn return_var() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .return_var(5u32);
++ {
++ let r = mock.foo(0);
++ assert_eq!(5, *r);
++ *r = 6;
++ }
++ assert_eq!(6, *mock.foo(0));
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|_| 5u32);
++ let r = mock.foo(0);
++ assert_eq!(5, *r);
++}
++
++mod sequence {
++ use super::*;
++
++ #[test]
++ #[should_panic(expected = "MockFoo::foo(4): Method sequence violation")]
++ fn fail() {
++ let mut seq = Sequence::new();
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .with(predicate::eq(3))
++ .times(1)
++ .return_var(0)
++ .in_sequence(&mut seq);
++
++ mock.expect_foo()
++ .with(predicate::eq(4))
++ .times(1)
++ .return_var(0)
++ .in_sequence(&mut seq);
++
++ mock.foo(4);
++ }
++
++ #[test]
++ fn ok() {
++ let mut seq = Sequence::new();
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .with(predicate::eq(3))
++ .times(1)
++ .return_var(0)
++ .in_sequence(&mut seq);
++
++ mock.expect_foo()
++ .with(predicate::eq(4))
++ .times(1)
++ .return_var(0)
++ .in_sequence(&mut seq);
++
++ mock.foo(3);
++ mock.foo(4);
++ }
++
++}
+diff --git a/tests/mock_return_reference.rs b/tests/mock_return_reference.rs
+new file mode 100644
+index 0000000..d3fc71d
+--- /dev/null
++++ b/tests/mock_return_reference.rs
+@@ -0,0 +1,105 @@
++// vim: tw=80
++//! A struct with a method that returns an immutable reference
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ Foo {
++ fn foo(&self, x: i32) -> &u32;
++ fn bar(&self) -> &u32;
++ }
++}
++
++mod never {
++ use super::*;
++
++ #[test]
++ #[should_panic(expected =
++ "MockFoo::bar: Expectation(<anything>) should not have been called")]
++ fn fail() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .return_const(0)
++ .never();
++ mock.bar();
++ }
++
++ #[test]
++ fn ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .never();
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .return_const(5u32);
++ assert_eq!(5, *mock.foo(4));
++}
++
++#[test]
++#[cfg_attr(not(feature = "nightly"),
++ should_panic(expected = "MockFoo::foo: Expectation(<anything>) Returning default values requires"))]
++#[cfg_attr(not(feature = "nightly"), allow(unused_must_use))]
++fn return_default() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo();
++ let r = mock.foo(4);
++ assert_eq!(u32::default(), *r);
++}
++
++mod sequence {
++ use super::*;
++
++ #[test]
++ #[should_panic(expected = "exact call count")]
++ fn ambiguous() {
++ let mut seq = Sequence::new();
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .times(1..3)
++ .in_sequence(&mut seq);
++ mock.foo(4);
++ }
++
++ #[test]
++ #[should_panic(expected = "MockFoo::foo(4): Method sequence violation")]
++ fn fail() {
++ let mut seq = Sequence::new();
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .times(1)
++ .return_const(0)
++ .in_sequence(&mut seq);
++
++ mock.expect_foo()
++ .times(1)
++ .return_const(0)
++ .in_sequence(&mut seq);
++
++ mock.foo(4);
++ mock.bar();
++ }
++
++ #[test]
++ fn ok() {
++ let mut seq = Sequence::new();
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .times(1)
++ .return_const(0)
++ .in_sequence(&mut seq);
++
++ mock.expect_bar()
++ .times(1)
++ .return_const(0)
++ .in_sequence(&mut seq);
++
++ mock.foo(4);
++ mock.bar();
++ }
++}
+diff --git a/tests/mock_same_trait_twice_on_generic_struct.rs b/tests/mock_same_trait_twice_on_generic_struct.rs
+new file mode 100644
+index 0000000..51dd88f
+--- /dev/null
++++ b/tests/mock_same_trait_twice_on_generic_struct.rs
+@@ -0,0 +1,32 @@
++// vim: ts=80
++//! Mock the same generic trait twice on a single struct (with different generic
++//! arguments, of course).
++//!
++#![deny(warnings)]
++#![allow(clippy::from_over_into)]
++
++use mockall::*;
++
++mock! {
++ pub Foo<T> {}
++ impl Into<u32> for Foo<u32> {
++ fn into(self) -> u32;
++ }
++ impl Into<i32> for Foo<i32> {
++ fn into(self) -> i32;
++ }
++}
++
++/// Ensure we can set expectations for both methods simultaneously
++#[test]
++fn return_once() {
++ let mut mocku = MockFoo::<u32>::new();
++ mocku.expect_into()
++ .return_once(|| 42);
++ let mut mocki = MockFoo::<i32>::new();
++ mocki.expect_into()
++ .return_once(|| -42);
++
++ assert_eq!(<MockFoo<u32> as Into<u32>>::into(mocku), 42u32);
++ assert_eq!(<MockFoo<i32> as Into<i32>>::into(mocki), -42);
++}
+diff --git a/tests/mock_specializing_methods.rs b/tests/mock_specializing_methods.rs
+new file mode 100644
+index 0000000..f2c0256
+--- /dev/null
++++ b/tests/mock_specializing_methods.rs
+@@ -0,0 +1,34 @@
++// vim: tw=80
++//! A specializing method is a non-generic method of a generic struct that
++//! places additional bounds on the struct's generic types via a where
++//! clause.
++#![deny(warnings)]
++
++use mockall::*;
++
++struct G<T: Copy + Default>(T);
++
++#[derive(Clone, Copy)]
++struct NonDefault{}
++
++mock!{
++ Foo<T> where T: Copy {
++ fn foo(&self, t: T) -> G<T> where T: Default + 'static;
++ }
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::<u32>::default();
++ mock.expect_foo()
++ .returning(G);
++ assert_eq!(42u32, mock.foo(42u32).0);
++
++ // It's possible to instantiate a mock object that doesn't satisfy the
++ // specializing method's requirements:
++ let _mock2 = MockFoo::<NonDefault>::default();
++ // But you can't call the specializing method. This won't work:
++ // _mock2.expect_foo()
++ // .returning(|h| G(h));
++ // _mock2.foo(NonDefault{});
++}
+diff --git a/tests/mock_static_method_with_generic_args.rs b/tests/mock_static_method_with_generic_args.rs
+new file mode 100644
+index 0000000..5a8d0fe
+--- /dev/null
++++ b/tests/mock_static_method_with_generic_args.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ Foo {
++ fn bar<T: 'static>(x: T);
++ }
++}
++
++#[test]
++fn returning() {
++ let ctx = MockFoo::bar_context();
++ ctx.expect::<i16>().returning(|_| ());
++ MockFoo::bar(0i16)
++}
+diff --git a/tests/mock_static_method_with_generic_return.rs b/tests/mock_static_method_with_generic_return.rs
+new file mode 100644
+index 0000000..98c0cae
+--- /dev/null
++++ b/tests/mock_static_method_with_generic_return.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ Foo {
++ fn bar<T: 'static>(x: T) -> Vec<T>;
++ }
++}
++
++#[test]
++fn returning() {
++ let ctx = MockFoo::bar_context();
++ ctx.expect::<i16>().returning(|x| vec![x]);
++ let v = MockFoo::bar(42i16);
++ assert_eq!(v[0], 42i16);
++}
+diff --git a/tests/mock_static_method_with_lifetime_parameters.rs b/tests/mock_static_method_with_lifetime_parameters.rs
+new file mode 100644
+index 0000000..c71ece5
+--- /dev/null
++++ b/tests/mock_static_method_with_lifetime_parameters.rs
+@@ -0,0 +1,57 @@
++// vim: tw=80
++//! A static generic method whose only generic parameter is a lifetime parameter
++#![deny(warnings)]
++
++use mockall::*;
++use std::sync::Mutex;
++
++#[derive(Debug, Eq)]
++struct X<'a>(&'a u32);
++
++impl<'a> PartialEq for X<'a> {
++ fn eq(&self, other: &X<'a>) -> bool {
++ self.0 == other.0
++ }
++}
++
++mock!{
++ Foo {
++ fn foo<'a>(x: &'a X<'a>) -> u32;
++ }
++}
++
++static FOO_MTX: Mutex<()> = Mutex::new(());
++
++#[test]
++fn return_const() {
++ let _m = FOO_MTX.lock().unwrap();
++
++ let ctx = MockFoo::foo_context();
++ ctx.expect()
++ .return_const(42u32);
++ let x = X(&5);
++ assert_eq!(42, MockFoo::foo(&x));
++}
++
++#[test]
++fn returning() {
++ let _m = FOO_MTX.lock().unwrap();
++
++ let ctx = MockFoo::foo_context();
++ ctx.expect()
++ .returning(|f| *f.0);
++ let x = X(&5);
++ assert_eq!(5, MockFoo::foo(&x));
++}
++
++#[test]
++fn withf() {
++ let _m = FOO_MTX.lock().unwrap();
++
++ let ctx = MockFoo::foo_context();
++ ctx.expect()
++ .withf(|f| *f.0 == 5)
++ .return_const(42u32);
++ let x = X(&5);
++ assert_eq!(42, MockFoo::foo(&x));
++}
+diff --git a/tests/mock_static_method_with_reference_arguments.rs b/tests/mock_static_method_with_reference_arguments.rs
+new file mode 100644
+index 0000000..1785ddc
+--- /dev/null
++++ b/tests/mock_static_method_with_reference_arguments.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock!{
++ Foo {
++ fn bar(x: &u32) -> u64;
++ }
++}
++
++#[test]
++fn with() {
++ let ctx = MockFoo::bar_context();
++ ctx.expect()
++ .with(predicate::eq(42))
++ .return_const(99u64);
++ assert_eq!(99, MockFoo::bar(&42));
++}
+diff --git a/tests/mock_struct.rs b/tests/mock_struct.rs
+new file mode 100644
+index 0000000..71b91e8
+--- /dev/null
++++ b/tests/mock_struct.rs
+@@ -0,0 +1,461 @@
++// vim: tw=80
++//! Structs can be mocked with mock! This is useful when the struct's original
++//! definition is not accessible.
++#![deny(warnings)]
++
++use mockall::*;
++
++// A struct with a definition like this:
++// struct Foo {
++// _x: i16
++// }
++// impl Foo {
++// fn foo(&self, _x: u32) -> u32 {
++// 42
++// }
++// }
++// Could be mocked like this:
++mock!{
++ Foo {
++ fn foo(&self, x: u32) -> u32;
++ fn bar(&self, x: u32);
++ fn baz(&self);
++ }
++}
++
++mod checkpoint {
++ use std::panic;
++ use super::*;
++
++ #[test]
++ fn expect_again() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|_| 5)
++ .times(1..3);
++ mock.foo(0);
++ mock.checkpoint();
++
++ mock.expect_foo()
++ .returning(|_| 25);
++ assert_eq!(25, mock.foo(0));
++ }
++
++ #[test]
++ #[should_panic(expected =
++ "MockFoo::foo: Expectation(<anything>) called 0 time(s) which is fewer than expected 1")]
++ fn not_yet_satisfied() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|_| 42)
++ .times(1);
++ mock.checkpoint();
++ panic!("Shouldn't get here!");
++ }
++
++ #[test]
++ #[should_panic(expected =
++ "MockFoo::foo: Expectation(<anything>) called 1 time(s) which is more than expected 0")]
++ fn too_many_calls() {
++ let mut mock = MockFoo::default();
++ mock.expect_foo()
++ .returning(|_| 42)
++ .times(0);
++ let _ = panic::catch_unwind(|| {
++ mock.foo(0);
++ });
++ mock.checkpoint();
++ panic!("Shouldn't get here!");
++ }
++
++ #[test]
++ fn ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|_| 5)
++ .times(1..3);
++ mock.foo(0);
++ mock.checkpoint();
++ }
++
++ #[test]
++ #[should_panic(expected = "MockFoo::foo(0): No matching expectation found")]
++ fn removes_old_expectations() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|_| 42)
++ .times(1..3);
++ mock.foo(0);
++ mock.checkpoint();
++ mock.foo(0);
++ panic!("Shouldn't get here!");
++ }
++}
++
++mod r#match {
++ use super::*;
++
++ /// Unlike Mockers, Mockall calls should use the oldest matching
++ /// expectation, if multiple expectations match
++ #[test]
++ fn fifo_order() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .with(predicate::eq(5))
++ .returning(|_| 99);
++ mock.expect_foo()
++ .with(predicate::always())
++ .returning(|_| 42);
++
++ assert_eq!(99, mock.foo(5));
++ }
++
++ #[test]
++ fn one_match() {
++ let mut mock0 = MockFoo::new();
++ mock0.expect_foo()
++ .with(predicate::eq(5))
++ .returning(|_| 99);
++ mock0.expect_foo()
++ .with(predicate::eq(6))
++ .returning(|_| 42);
++ assert_eq!(42, mock0.foo(6));
++
++ // And in reverse order
++ let mut mock1 = MockFoo::new();
++ mock1.expect_foo()
++ .with(predicate::eq(5))
++ .returning(|_| 99);
++ mock1.expect_foo()
++ .with(predicate::eq(6))
++ .returning(|_| 42);
++ assert_eq!(99, mock0.foo(5));
++ }
++
++ #[test]
++ #[should_panic(expected = "MockFoo::bar(5): No matching expectation found")]
++ fn with_no_matches() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .with(predicate::eq(4))
++ .return_const(());
++ mock.bar(5);
++ }
++
++ #[test]
++ fn with_ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .with(predicate::eq(5))
++ .return_const(());
++ mock.bar(5);
++ }
++
++ #[test]
++ fn withf_ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .withf(|x: &u32| *x == 5)
++ .return_const(());
++ mock.bar(5);
++ }
++
++ #[test]
++ #[should_panic(expected = "MockFoo::bar(5): No matching expectation found")]
++ fn withf_no_matches() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .withf(|x: &u32| *x == 6)
++ .return_const(());
++ mock.bar(5);
++ }
++
++}
++
++mod never {
++ use super::*;
++
++ #[test]
++ #[should_panic(expected =
++ "MockFoo::bar: Expectation(<anything>) should not have been called")]
++ fn fail() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .returning(|_| ())
++ .never();
++ mock.bar(0);
++ }
++
++ #[test]
++ fn ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .never();
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .return_const(42u32);
++ assert_eq!(42, mock.foo(5));
++}
++
++#[cfg_attr(not(feature = "nightly"),
++ should_panic(expected = "MockFoo::foo: Expectation(<anything>) Returning default values requires"))]
++#[cfg_attr(not(feature = "nightly"), allow(unused_must_use))]
++#[test]
++fn return_default() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo();
++ let r = mock.foo(5);
++ assert_eq!(u32::default(), r);
++}
++
++#[test]
++fn returning() {
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .returning(|x| x + 1);
++ assert_eq!(6, mock.foo(5));
++}
++
++mod sequence {
++ use super::*;
++
++ #[test]
++ #[should_panic(expected = "exact call count")]
++ fn ambiguous() {
++ let mut seq = Sequence::new();
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .times(1..3)
++ .in_sequence(&mut seq);
++ mock.baz();
++ }
++
++ #[test]
++ #[should_panic(expected = "MockFoo::baz(): Method sequence violation")]
++ fn fail() {
++ let mut seq = Sequence::new();
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .times(1)
++ .returning(|_| ())
++ .in_sequence(&mut seq);
++
++ mock.expect_baz()
++ .times(1)
++ .returning(|| ())
++ .in_sequence(&mut seq);
++
++ mock.baz();
++ mock.bar(0);
++ }
++
++ #[test]
++ fn ok() {
++ let mut seq = Sequence::new();
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .times(1)
++ .returning(|| ())
++ .in_sequence(&mut seq);
++
++ mock.expect_bar()
++ .times(1)
++ .returning(|_| ())
++ .in_sequence(&mut seq);
++
++ mock.baz();
++ mock.bar(0);
++ }
++
++ /// When adding multiple calls of a single method, with the same arguments,
++ /// to a sequence, expectations should not be called after they are done if
++ /// there are more expectations to follow.
++ #[test]
++ fn single_method() {
++ let mut seq = Sequence::new();
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .times(1)
++ .in_sequence(&mut seq)
++ .returning(|_| 1);
++ mock.expect_foo()
++ .times(1)
++ .in_sequence(&mut seq)
++ .returning(|_| 2);
++ mock.expect_foo()
++ .times(1)
++ .in_sequence(&mut seq)
++ .returning(|_| 3);
++
++ assert_eq!(1, mock.foo(0));
++ assert_eq!(2, mock.foo(0));
++ assert_eq!(3, mock.foo(0));
++ }
++
++}
++
++mod times {
++ use super::*;
++
++ #[test]
++ fn ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .returning(|| ())
++ .times(2);
++ mock.baz();
++ mock.baz();
++ }
++
++ #[test]
++ #[should_panic(expected =
++ "MockFoo::bar: Expectation(var == 5) called 1 time(s) which is fewer than expected 2")]
++ fn too_few() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .with(predicate::eq(5))
++ .returning(|_| ())
++ .times(2);
++ mock.bar(5);
++ }
++
++ #[test]
++ #[should_panic(expected =
++ "MockFoo::baz: Expectation(<anything>) called 3 times which is more than the expected 2")]
++ fn too_many() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .returning(|| ())
++ .times(2);
++ mock.baz();
++ mock.baz();
++ mock.baz();
++ // Verify that we panic quickly and don't reach code below this point.
++ panic!("Shouldn't get here!");
++ }
++
++ #[test]
++ fn range_ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .returning(|| ())
++ .times(2..4);
++ mock.baz();
++ mock.baz();
++
++ mock.expect_bar()
++ .returning(|_| ())
++ .times(2..4);
++ mock.bar(0);
++ mock.bar(0);
++ mock.bar(0);
++ }
++
++ #[test]
++ #[should_panic(expected =
++ "MockFoo::baz: Expectation(<anything>) called 1 time(s) which is fewer than expected 2")]
++ fn range_too_few() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .returning(|| ())
++ .times(2..4);
++ mock.baz();
++ }
++
++ #[test]
++ #[should_panic(expected =
++ "MockFoo::baz: Expectation(<anything>) called 4 times which is more than the expected 3")]
++ fn range_too_many() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .returning(|| ())
++ .times(2..4);
++ mock.baz();
++ mock.baz();
++ mock.baz();
++ mock.baz();
++ // Verify that we panic quickly and don't reach code below this point.
++ panic!("Shouldn't get here!");
++ }
++
++ #[test]
++ fn rangeto_ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .returning(|_| ())
++ .times(..4);
++ mock.bar(0);
++ mock.bar(0);
++ mock.bar(0);
++ }
++
++ #[test]
++ #[should_panic(expected =
++ "MockFoo::baz: Expectation(<anything>) called 4 times which is more than the expected 3")]
++ fn rangeto_too_many() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .returning(|| ())
++ .times(..4);
++ mock.baz();
++ mock.baz();
++ mock.baz();
++ mock.baz();
++ }
++
++ #[test]
++ fn rangeinclusive_ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .returning(|_| ())
++ .times(2..=4);
++ mock.bar(0);
++ mock.bar(0);
++ mock.bar(0);
++ mock.bar(0);
++ }
++
++ #[test]
++ fn rangefrom_ok() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .returning(|| ())
++ .times(2..);
++ mock.baz();
++ mock.baz();
++
++ mock.expect_bar()
++ .returning(|_| ())
++ .times(2..);
++ mock.bar(0);
++ mock.bar(0);
++ mock.bar(0);
++ }
++
++ #[test]
++ #[should_panic(expected =
++ "MockFoo::baz: Expectation(<anything>) called 1 time(s) which is fewer than expected 2")]
++ fn rangefrom_too_few() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .returning(|| ())
++ .times(2..);
++ mock.baz();
++ }
++}
++
++#[test]
++fn times_full() {
++ let mut mock = MockFoo::new();
++ mock.expect_baz()
++ .returning(|| ())
++ .times(1)
++ .times(..);
++ mock.baz();
++ mock.baz();
++}
+diff --git a/tests/mock_struct_with_static_method.rs b/tests/mock_struct_with_static_method.rs
+new file mode 100644
+index 0000000..ffaebd0
+--- /dev/null
++++ b/tests/mock_struct_with_static_method.rs
+@@ -0,0 +1,103 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++use std::sync::Mutex;
++
++mock!{
++ Foo {
++ fn bar(x: u32) -> u64;
++ }
++}
++
++static BAR_MTX: Mutex<()> = Mutex::new(());
++
++// Checkpointing the mock object should not checkpoint static methods
++#[test]
++fn checkpoint() {
++ let _m = BAR_MTX.lock();
++
++ let mut mock = MockFoo::new();
++ let ctx = MockFoo::bar_context();
++ ctx.expect()
++ .returning(|_| 32)
++ .times(1..3);
++ mock.checkpoint();
++ MockFoo::bar(0);
++}
++
++// It should also be possible to checkpoint just the context object
++#[test]
++#[should_panic(expected =
++ "MockFoo::bar: Expectation(<anything>) called 0 time(s) which is fewer than expected 1")]
++fn ctx_checkpoint() {
++ let _m = BAR_MTX.lock();
++
++ let ctx = MockFoo::bar_context();
++ ctx.expect()
++ .returning(|_| 32)
++ .times(1..3);
++ ctx.checkpoint();
++ panic!("Shouldn't get here!");
++}
++
++// Expectations should be cleared when a context object drops
++#[test]
++#[should_panic(expected = "MockFoo::bar(42): No matching expectation found")]
++fn ctx_hygiene() {
++ let _m = BAR_MTX.lock();
++
++ {
++ let ctx0 = MockFoo::bar_context();
++ ctx0.expect()
++ .returning(|x| u64::from(x + 1));
++ }
++ MockFoo::bar(42);
++}
++
++#[test]
++fn return_const() {
++ let _m = BAR_MTX.lock();
++
++ let ctx = MockFoo::bar_context();
++ ctx.expect()
++ .return_const(42u64);
++ assert_eq!(42, MockFoo::bar(41));
++}
++
++#[cfg_attr(not(feature = "nightly"), ignore)]
++#[cfg_attr(not(feature = "nightly"), allow(unused_must_use))]
++#[test]
++fn return_default() {
++ let _m = BAR_MTX.lock();
++
++ let ctx = MockFoo::bar_context();
++ ctx.expect();
++ let r = MockFoo::bar(5);
++ assert_eq!(u64::default(), r);
++}
++
++#[test]
++fn returning() {
++ let _m = BAR_MTX.lock();
++
++ let ctx = MockFoo::bar_context();
++ ctx.expect()
++ .returning(|x| u64::from(x + 1));
++ assert_eq!(42, MockFoo::bar(41));
++}
++
++#[test]
++fn two_matches() {
++ let _m = BAR_MTX.lock();
++
++ let ctx = MockFoo::bar_context();
++ ctx.expect()
++ .with(predicate::eq(42))
++ .return_const(99u64);
++ ctx.expect()
++ .with(predicate::eq(69))
++ .return_const(101u64);
++ assert_eq!(101, MockFoo::bar(69));
++ assert_eq!(99, MockFoo::bar(42));
++}
+diff --git a/tests/mock_struct_with_trait.rs b/tests/mock_struct_with_trait.rs
+new file mode 100644
+index 0000000..bdf13d4
+--- /dev/null
++++ b/tests/mock_struct_with_trait.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++ fn foo(&self, x: u32) -> i64;
++}
++
++mock!{
++ pub Bar {}
++ impl Foo for Bar {
++ fn foo(&self, x: u32) -> i64;
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockBar::new();
++ mock.expect_foo()
++ .return_const(6);
++ assert_eq!(6, mock.foo(5));
++}
++
+diff --git a/tests/mock_struct_with_trait_with_associated_types.rs b/tests/mock_struct_with_trait_with_associated_types.rs
+new file mode 100644
+index 0000000..03a26e5
+--- /dev/null
++++ b/tests/mock_struct_with_trait_with_associated_types.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ pub MyIter {}
++ impl Iterator for MyIter {
++ type Item=u32;
++
++ fn next(&mut self) -> Option<u32>;
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockMyIter::new();
++ mock.expect_next()
++ .return_const(None);
++ assert!(mock.next().is_none());
++}
+diff --git a/tests/mock_trait_returning_reference.rs b/tests/mock_trait_returning_reference.rs
+new file mode 100644
+index 0000000..746acbd
+--- /dev/null
++++ b/tests/mock_trait_returning_reference.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++//! A trait with a method that returns an immutable reference
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++ fn foo(&self) -> &u32;
++}
++
++mock! {
++ pub Bar {}
++ impl Foo for Bar {
++ fn foo(&self) -> &u32;
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockBar::new();
++ mock.expect_foo()
++ .return_const(5u32);
++ assert_eq!(5, *mock.foo());
++}
+diff --git a/tests/mock_trait_returning_static_reference.rs b/tests/mock_trait_returning_static_reference.rs
+new file mode 100644
+index 0000000..75900d9
+--- /dev/null
++++ b/tests/mock_trait_returning_static_reference.rs
+@@ -0,0 +1,20 @@
++// vim: tw=80
++//! A struct with a method that returns an immutable static reference
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ Foo {
++ fn foo(&self) -> &'static u32;
++ }
++}
++
++#[test]
++fn return_const() {
++ const X: u32 = 5;
++ let mut mock = MockFoo::new();
++ mock.expect_foo()
++ .return_const(&X);
++ assert_eq!(5, *mock.foo());
++}
+diff --git a/tests/mock_trait_with_static_method.rs b/tests/mock_trait_with_static_method.rs
+new file mode 100644
+index 0000000..e0d5b1c
+--- /dev/null
++++ b/tests/mock_trait_with_static_method.rs
+@@ -0,0 +1,23 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Bar {
++ fn baz(x: u32) -> u64;
++}
++
++mock!{
++ pub Foo {}
++ impl Bar for Foo {
++ fn baz(x: u32) -> u64;
++ }
++}
++
++#[test]
++fn returning() {
++ let ctx = MockFoo::baz_context();
++ ctx.expect()
++ .returning(|x| u64::from(x + 1));
++ assert_eq!(42, MockFoo::baz(41));
++}
+diff --git a/tests/mock_unsafe_trait.rs b/tests/mock_unsafe_trait.rs
+new file mode 100644
+index 0000000..8368338
+--- /dev/null
++++ b/tests/mock_unsafe_trait.rs
+@@ -0,0 +1,25 @@
++// vim: ts=80
++#![deny(warnings)]
++
++use mockall::*;
++
++#[allow(clippy::missing_safety_doc)]
++pub unsafe trait Bar {
++ fn bar(&self) -> i32;
++}
++
++mock! {
++ pub Foo{}
++ unsafe impl Bar for Foo {
++ fn bar(&self) -> i32;
++ }
++}
++
++#[test]
++fn return_const() {
++ let mut mock = MockFoo::new();
++ mock.expect_bar()
++ .return_const(42);
++
++ assert_eq!(42, mock.bar());
++}
+diff --git a/tests/mock_unsized.rs b/tests/mock_unsized.rs
+new file mode 100644
+index 0000000..5753510
+--- /dev/null
++++ b/tests/mock_unsized.rs
+@@ -0,0 +1,52 @@
++// vim: tw=80
++//! All types of predicate should work for methods with unsized arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++ Foo {
++ fn foo(&self, arg: &str);
++ }
++}
++
++#[test]
++fn with_always() {
++ let mut foo = MockFoo::new();
++ foo.expect_foo()
++ .with(predicate::always())
++ .return_const(());
++
++ foo.foo("xxx");
++}
++
++#[test]
++fn with_eq() {
++ let mut foo = MockFoo::new();
++ foo.expect_foo()
++ .with(predicate::eq("xxx"))
++ .return_const(());
++
++ foo.foo("xxx");
++}
++
++#[test]
++#[should_panic(expected = "MockFoo::foo(\"xxx\"): No matching expectation found")]
++fn with_never() {
++ let mut foo = MockFoo::new();
++ foo.expect_foo()
++ .with(predicate::never())
++ .return_const(());
++
++ foo.foo("xxx");
++}
++
++#[test]
++fn withf() {
++ let mut foo = MockFoo::new();
++ foo.expect_foo()
++ .withf(|a| a == "xxx")
++ .return_const(());
++
++ foo.foo("xxx");
++}
+diff --git a/tests/raw_identifier.rs b/tests/raw_identifier.rs
+new file mode 100644
+index 0000000..2d56e37
+--- /dev/null
++++ b/tests/raw_identifier.rs
+@@ -0,0 +1,72 @@
++// vim: tw=80
++//! It should be possible to mock things that use raw identifiers
++#![deny(warnings)]
++#![allow(non_camel_case_types)]
++
++use mockall::*;
++
++#[automock]
++trait r#while {
++ fn r#match(&self);
++ fn r#loop();
++}
++
++#[automock]
++pub mod r#break {
++ pub fn r#if() {unimplemented!() }
++}
++
++mock! {
++ r#do {}
++ impl r#while for r#do {
++ fn r#match(&self);
++ fn r#loop();
++ }
++}
++
++struct r#else {}
++#[automock]
++impl r#while for r#else {
++ fn r#match(&self) {unimplemented!()}
++ fn r#loop() {unimplemented!()}
++}
++
++#[test]
++fn by_ref() {
++ let mut foo = Mockwhile::new();
++ foo.expect_match()
++ .return_const(());
++ foo.r#match();
++}
++
++#[test]
++fn static_method() {
++ let ctx = Mockwhile::loop_context();
++ ctx.expect()
++ .returning(|| ());
++ Mockwhile::r#loop();
++}
++
++#[test]
++fn manual_mock() {
++ let mut foo = Mockdo::new();
++ foo.expect_match()
++ .return_const(());
++ foo.r#match();
++}
++
++#[test]
++fn module() {
++ let ctx = mock_break::if_context();
++ ctx.expect()
++ .returning(|| ());
++ mock_break::r#if();
++}
++
++#[test]
++fn trait_impl() {
++ let mut mock = Mockelse::new();
++ mock.expect_match()
++ .returning(|| ());
++ mock.r#match();
++}
+diff --git a/tests/specific_impl.rs b/tests/specific_impl.rs
+new file mode 100644
+index 0000000..e16a48e
+--- /dev/null
++++ b/tests/specific_impl.rs
+@@ -0,0 +1,74 @@
++// vim: ts=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Bar {
++ fn bar(&self);
++}
++//trait Baz {
++ //fn baz<Y: 'static>(&self, y: Y);
++//}
++
++mock! {
++ pub Foo<T: 'static> {
++ }
++ impl Bar for Foo<u32> {
++ fn bar(&self);
++ }
++ impl Bar for Foo<i32> {
++ fn bar(&self);
++ }
++ // TODO: support specific impls with generic methods, like this
++ //impl Baz for Foo<u32> {
++ //fn baz<Y: 'static>(&self, y: Y);
++ //}
++}
++
++#[test]
++fn specific_impl() {
++ let mut mocku = MockFoo::<u32>::new();
++ mocku.expect_bar()
++ .return_const(());
++ let mut mocki = MockFoo::<i32>::new();
++ mocki.expect_bar()
++ .return_const(());
++
++ mocku.bar();
++ mocki.bar();
++}
++
++///// Make sure generic methods work with specific impls, too
++//#[test]
++//fn withf() {
++ //let mut mocku = MockFoo::<u32>::new();
++ //mocku.expect_baz::<f32>()
++ //.withf(|y| y == 3.14159)
++ //.return_const(());
++ //mocku.baz::<f32>(3.14159);
++//}
++
++// Here's a partially specific impl: Bar is implemented for Bean where one of
++// the generic types is concrete, but the other isn't.
++mock! {
++ pub Bean<X: 'static, Y: 'static> {}
++ impl<Y: 'static> Bar for Bean<u32, Y> {
++ fn bar(&self);
++ }
++ impl<Y: 'static> Bar for Bean<i32, Y> {
++ fn bar(&self);
++ }
++}
++
++#[test]
++fn partially_specific_impl() {
++ let mut mocku = MockBean::<u32, f32>::new();
++ mocku.expect_bar()
++ .return_const(());
++ let mut mocki = MockBean::<i32, f32>::new();
++ mocki.expect_bar()
++ .return_const(());
++
++ mocku.bar();
++ mocki.bar();
++}
base-commit: aec00d246ecc12846560d15eae2c9fc9c6e6cc74
--
2.41.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10
2024-03-17 15:59 [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10 Aaron Covrig via Guix-patches via
@ 2024-03-19 10:45 ` Efraim Flashner
2024-03-20 14:52 ` Aaron Covrig via Guix-patches via
0 siblings, 1 reply; 4+ messages in thread
From: Efraim Flashner @ 2024-03-19 10:45 UTC (permalink / raw)
To: Aaron Covrig; +Cc: 69859
[-- Attachment #1: Type: text/plain, Size: 2287 bytes --]
On Sun, Mar 17, 2024 at 11:59:17AM -0400, Aaron Covrig wrote:
> * gnu/packages/crates-io.scm (rust-pcap-1): New variable
> * gnu/packages/crates-io.scm (rust-pcap-0.11): New variable
> * gnu/packages/crates-io.scm (rust-pcap-0.10): New variable
> * gnu/packages/crates-io.scm (rust-gat-std-0.1): New variable
> * gnu/packages/crates-io.scm (rust-gat-std-proc-0.1): New variable
> * gnu/packages/crates-io.scm (rust-etherparse-0.14): New variable
> * gnu/packages/crates-io.scm (rust-etherparse-0.9): New variable
> * gnu/packages/crates-io.scm (rust-eui48-1): New variable
> * gnu/packages/crates-io.scm (rust-tun-tap-0.1): New variable
> * gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch:
> New file (provides tests and examples rust-mockall)
> * gnu/packages/crates-io.scm (rust-mockall-0.12): New variable
> * gnu/packages/crates-io.scm (rust-mockall-derive-0.12): New variable
> * gnu/packages/crates-io.scm (rust-mockall-0.11): Bumps to 0.11.4
> * gnu/packages/crates-io.scm (rust-mockall-derive-0.11): Bumps to 0.11.4
> * gnu/packages/crates-io.scm (rust-mockall-double-0.3): Bumps to 0.3.1
> * gnu/packages/crates-io.scm (rust-fragile-2): New variable
> * gnu/packages/crates-io.scm (rust-fragile-1): Bumps to 1.2.2
> * gnu/packages/crates-io.scm (rust-slab-0.4): Bumps to 0.4.9
> ---
> gnu/packages/crates-io.scm | 453 +-
> ...t-mockall-restore-examples-and-tests.patch | 7611 +++++++++++++++++
> 2 files changed, 7976 insertions(+), 88 deletions(-)
> create mode 100644 gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch
I want to thank you for all your work on these patches and on the other
ones too. Unfortunately with some of these ones I had already done a
bunch of them on the rust-team branch which I've finally pushed back
upstream.
Also, in order to keep with the standard practices of Guix each commit
should only have 1 change at a time, in this case adding or updating a
package. If you can split them into individual patches I'll be happy to
apply them.
--
Efraim Flashner <efraim@flashner.co.il> רנשלפ םירפא
GPG key = A28B F40C 3E55 1372 662D 14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10
2024-03-19 10:45 ` Efraim Flashner
@ 2024-03-20 14:52 ` Aaron Covrig via Guix-patches via
2024-03-25 7:17 ` Efraim Flashner
0 siblings, 1 reply; 4+ messages in thread
From: Aaron Covrig via Guix-patches via @ 2024-03-20 14:52 UTC (permalink / raw)
To: Efraim Flashner; +Cc: 69859
[-- Attachment #1: Type: text/plain, Size: 2710 bytes --]
On Tue, 19 Mar 2024 12:45:55 +0200
Efraim Flashner <efraim@flashner.co.il> wrote:
> On Sun, Mar 17, 2024 at 11:59:17AM -0400, Aaron Covrig wrote:
> > * gnu/packages/crates-io.scm (rust-pcap-1): New variable
> > * gnu/packages/crates-io.scm (rust-pcap-0.11): New variable
> > * gnu/packages/crates-io.scm (rust-pcap-0.10): New variable
> > * gnu/packages/crates-io.scm (rust-gat-std-0.1): New variable
> > * gnu/packages/crates-io.scm (rust-gat-std-proc-0.1): New variable
> > * gnu/packages/crates-io.scm (rust-etherparse-0.14): New variable
> > * gnu/packages/crates-io.scm (rust-etherparse-0.9): New variable
> > * gnu/packages/crates-io.scm (rust-eui48-1): New variable
> > * gnu/packages/crates-io.scm (rust-tun-tap-0.1): New variable
> > *
> > gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch:
> > New file (provides tests and examples rust-mockall)
> > * gnu/packages/crates-io.scm (rust-mockall-0.12): New variable
> > * gnu/packages/crates-io.scm (rust-mockall-derive-0.12): New
> > variable
> > * gnu/packages/crates-io.scm (rust-mockall-0.11): Bumps to 0.11.4
> > * gnu/packages/crates-io.scm (rust-mockall-derive-0.11): Bumps to
> > 0.11.4
> > * gnu/packages/crates-io.scm (rust-mockall-double-0.3): Bumps to
> > 0.3.1
> > * gnu/packages/crates-io.scm (rust-fragile-2): New variable
> > * gnu/packages/crates-io.scm (rust-fragile-1): Bumps to 1.2.2
> > * gnu/packages/crates-io.scm (rust-slab-0.4): Bumps to 0.4.9
> > ---
> > gnu/packages/crates-io.scm | 453 +-
> > ...t-mockall-restore-examples-and-tests.patch | 7611
> > +++++++++++++++++ 2 files changed, 7976 insertions(+), 88
> > deletions(-) create mode 100644
> > gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch
>
> I want to thank you for all your work on these patches and on the
> other ones too. Unfortunately with some of these ones I had already
> done a bunch of them on the rust-team branch which I've finally
> pushed back upstream.
>
> Also, in order to keep with the standard practices of Guix each commit
> should only have 1 change at a time, in this case adding or updating a
> package. If you can split them into individual patches I'll be happy
> to apply them.
>
Ok, I can rebase and resubmit them; when you say each should be a
separate commit, should I update a single package per
issue (and open a new issue for each package in this commit (and does
this apply to subversions (an issue for both fragile-1 and fragile-2 or
just one for fragile-*)) or should I resubmit this (and the others) as
a patch series where each commit is one package (but they are all under
a single issue)?
v/r,
Aaron Covrig
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10
2024-03-20 14:52 ` Aaron Covrig via Guix-patches via
@ 2024-03-25 7:17 ` Efraim Flashner
0 siblings, 0 replies; 4+ messages in thread
From: Efraim Flashner @ 2024-03-25 7:17 UTC (permalink / raw)
To: Aaron Covrig; +Cc: 69859
[-- Attachment #1: Type: text/plain, Size: 3179 bytes --]
On Wed, Mar 20, 2024 at 10:52:38AM -0400, Aaron Covrig wrote:
> On Tue, 19 Mar 2024 12:45:55 +0200
> Efraim Flashner <efraim@flashner.co.il> wrote:
>
> > On Sun, Mar 17, 2024 at 11:59:17AM -0400, Aaron Covrig wrote:
> > > * gnu/packages/crates-io.scm (rust-pcap-1): New variable
> > > * gnu/packages/crates-io.scm (rust-pcap-0.11): New variable
> > > * gnu/packages/crates-io.scm (rust-pcap-0.10): New variable
> > > * gnu/packages/crates-io.scm (rust-gat-std-0.1): New variable
> > > * gnu/packages/crates-io.scm (rust-gat-std-proc-0.1): New variable
> > > * gnu/packages/crates-io.scm (rust-etherparse-0.14): New variable
> > > * gnu/packages/crates-io.scm (rust-etherparse-0.9): New variable
> > > * gnu/packages/crates-io.scm (rust-eui48-1): New variable
> > > * gnu/packages/crates-io.scm (rust-tun-tap-0.1): New variable
> > > *
> > > gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch:
> > > New file (provides tests and examples rust-mockall)
> > > * gnu/packages/crates-io.scm (rust-mockall-0.12): New variable
> > > * gnu/packages/crates-io.scm (rust-mockall-derive-0.12): New
> > > variable
> > > * gnu/packages/crates-io.scm (rust-mockall-0.11): Bumps to 0.11.4
> > > * gnu/packages/crates-io.scm (rust-mockall-derive-0.11): Bumps to
> > > 0.11.4
> > > * gnu/packages/crates-io.scm (rust-mockall-double-0.3): Bumps to
> > > 0.3.1
> > > * gnu/packages/crates-io.scm (rust-fragile-2): New variable
> > > * gnu/packages/crates-io.scm (rust-fragile-1): Bumps to 1.2.2
> > > * gnu/packages/crates-io.scm (rust-slab-0.4): Bumps to 0.4.9
> > > ---
> > > gnu/packages/crates-io.scm | 453 +-
> > > ...t-mockall-restore-examples-and-tests.patch | 7611
> > > +++++++++++++++++ 2 files changed, 7976 insertions(+), 88
> > > deletions(-) create mode 100644
> > > gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch
> >
> > I want to thank you for all your work on these patches and on the
> > other ones too. Unfortunately with some of these ones I had already
> > done a bunch of them on the rust-team branch which I've finally
> > pushed back upstream.
> >
> > Also, in order to keep with the standard practices of Guix each commit
> > should only have 1 change at a time, in this case adding or updating a
> > package. If you can split them into individual patches I'll be happy
> > to apply them.
> >
>
> Ok, I can rebase and resubmit them; when you say each should be a
> separate commit, should I update a single package per
> issue (and open a new issue for each package in this commit (and does
> this apply to subversions (an issue for both fragile-1 and fragile-2 or
> just one for fragile-*)) or should I resubmit this (and the others) as
> a patch series where each commit is one package (but they are all under
> a single issue)?
Sorry, I meant to respond earlier.
The way you have the patches broken up in v3 of bug#69620 is perfect.
--
Efraim Flashner <efraim@flashner.co.il> רנשלפ םירפא
GPG key = A28B F40C 3E55 1372 662D 14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-03-25 7:19 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-17 15:59 [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10 Aaron Covrig via Guix-patches via
2024-03-19 10:45 ` Efraim Flashner
2024-03-20 14:52 ` Aaron Covrig via Guix-patches via
2024-03-25 7:17 ` Efraim Flashner
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.