Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test organization #253

Merged
merged 3 commits into from Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -25,6 +25,7 @@ compiler_builtins = { version = '0.1.2', optional = true }
[dev-dependencies]
trybuild = "1.0"
rustversion = "1.0"
walkdir = "2.3"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
Expand Down
68 changes: 68 additions & 0 deletions src/lib.rs
Expand Up @@ -924,6 +924,7 @@ mod tests {
#[doc = "> you are the easiest person to fool."]
#[doc = "> "]
#[doc = "> - Richard Feynman"]
#[derive(Default)]
struct Flags: u32 {
const A = 0b00000001;
#[doc = "<pcwalton> macros are way better at generating code than trans is"]
Expand Down Expand Up @@ -1460,6 +1461,11 @@ mod tests {
assert_eq!(hash(&x), hash(&y));
}

#[test]
fn test_default() {
assert_eq!(Flags::empty(), Flags::default());
}

#[test]
fn test_debug() {
assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B");
Expand Down Expand Up @@ -1638,4 +1644,66 @@ mod tests {
fn test_empty_bitflags() {
bitflags! {}
}

#[test]
fn test_u128_bitflags() {
bitflags! {
struct Flags128: u128 {
const A = 0x0000_0000_0000_0000_0000_0000_0000_0001;
const B = 0x0000_0000_0000_1000_0000_0000_0000_0000;
const C = 0x8000_0000_0000_0000_0000_0000_0000_0000;
const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
}
}

assert_eq!(Flags128::ABC, Flags128::A | Flags128::B | Flags128::C);
assert_eq!(Flags128::A.bits, 0x0000_0000_0000_0000_0000_0000_0000_0001);
assert_eq!(Flags128::B.bits, 0x0000_0000_0000_1000_0000_0000_0000_0000);
assert_eq!(Flags128::C.bits, 0x8000_0000_0000_0000_0000_0000_0000_0000);
assert_eq!(
Flags128::ABC.bits,
0x8000_0000_0000_1000_0000_0000_0000_0001
);
assert_eq!(format!("{:?}", Flags128::A), "A");
assert_eq!(format!("{:?}", Flags128::B), "B");
assert_eq!(format!("{:?}", Flags128::C), "C");
assert_eq!(format!("{:?}", Flags128::ABC), "A | B | C | ABC");
}

#[test]
fn test_serde_bitflags_serialize() {
let flags = SerdeFlags::A | SerdeFlags::B;

let serialized = serde_json::to_string(&flags).unwrap();

assert_eq!(serialized, r#"{"bits":3}"#);
}

#[test]
fn test_serde_bitflags_deserialize() {
let deserialized: SerdeFlags = serde_json::from_str(r#"{"bits":12}"#).unwrap();

let expected = SerdeFlags::C | SerdeFlags::D;

assert_eq!(deserialized.bits, expected.bits);
}

#[test]
fn test_serde_bitflags_roundtrip() {
let flags = SerdeFlags::A | SerdeFlags::B;

let deserialized: SerdeFlags = serde_json::from_str(&serde_json::to_string(&flags).unwrap()).unwrap();

assert_eq!(deserialized.bits, flags.bits);
}

bitflags! {
#[derive(serde::Serialize, serde::Deserialize)]
struct SerdeFlags: u32 {
const A = 1;
const B = 2;
const C = 4;
const D = 8;
}
}
}
2 changes: 1 addition & 1 deletion tests/external_no_std.rs → tests/basic.rs
Expand Up @@ -15,6 +15,6 @@ bitflags! {
}

#[test]
fn smoke() {
fn basic() {
assert_eq!(Flags::ABC, Flags::A | Flags::B | Flags::C);
}
@@ -1,16 +1,10 @@
#![no_std]

#[allow(unused_imports)]
use core::fmt::Display;

use bitflags::bitflags;

bitflags! {
/// baz
#[derive(Clone, Copy)]
struct Flags: u32 {
const A = 0b00000001;
}
}

#[test]
fn main() {}
27 changes: 27 additions & 0 deletions tests/compile-fail/derive/copy.stderr.beta
@@ -0,0 +1,27 @@
error[E0119]: conflicting implementations of trait `std::clone::Clone` for type `Flags`
--> $DIR/copy.rs:3:1
|
3 | / bitflags! {
4 | | #[derive(Clone, Copy)]
| | ----- first implementation here
5 | | struct Flags: u32 {
6 | | const A = 0b00000001;
7 | | }
8 | | }
| |_^ conflicting implementation for `Flags`
|
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `Flags`
--> $DIR/copy.rs:3:1
|
3 | / bitflags! {
4 | | #[derive(Clone, Copy)]
| | ---- first implementation here
5 | | struct Flags: u32 {
6 | | const A = 0b00000001;
7 | | }
8 | | }
| |_^ conflicting implementation for `Flags`
|
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
10 changes: 10 additions & 0 deletions tests/compile-fail/derive/eq.rs
@@ -0,0 +1,10 @@
use bitflags::bitflags;

bitflags! {
#[derive(PartialEq, Eq)]
struct Flags: u32 {
const A = 0b00000001;
}
}

fn main() {}
55 changes: 55 additions & 0 deletions tests/compile-fail/derive/eq.stderr.beta
@@ -0,0 +1,55 @@
error[E0119]: conflicting implementations of trait `std::cmp::PartialEq` for type `Flags`
--> $DIR/eq.rs:3:1
|
3 | / bitflags! {
4 | | #[derive(PartialEq, Eq)]
| | --------- first implementation here
5 | | struct Flags: u32 {
6 | | const A = 0b00000001;
7 | | }
8 | | }
| |_^ conflicting implementation for `Flags`
|
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0119]: conflicting implementations of trait `std::cmp::Eq` for type `Flags`
--> $DIR/eq.rs:3:1
|
3 | / bitflags! {
4 | | #[derive(PartialEq, Eq)]
| | -- first implementation here
5 | | struct Flags: u32 {
6 | | const A = 0b00000001;
7 | | }
8 | | }
| |_^ conflicting implementation for `Flags`
|
= note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0119]: conflicting implementations of trait `std::marker::StructuralPartialEq` for type `Flags`
--> $DIR/eq.rs:3:1
|
3 | / bitflags! {
4 | | #[derive(PartialEq, Eq)]
| | --------- first implementation here
5 | | struct Flags: u32 {
6 | | const A = 0b00000001;
7 | | }
8 | | }
| |_^ conflicting implementation for `Flags`
|
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0119]: conflicting implementations of trait `std::marker::StructuralEq` for type `Flags`
--> $DIR/eq.rs:3:1
|
3 | / bitflags! {
4 | | #[derive(PartialEq, Eq)]
| | -- first implementation here
5 | | struct Flags: u32 {
6 | | const A = 0b00000001;
7 | | }
8 | | }
| |_^ conflicting implementation for `Flags`
|
= note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
123 changes: 123 additions & 0 deletions tests/compile-fail/non_integer_base/all_defined.rs
@@ -0,0 +1,123 @@
use std::{
fmt::{
self,
Debug,
Display,
LowerHex,
UpperHex,
Octal,
Binary,
},
ops::{
BitAnd,
BitOr,
BitXor,
BitAndAssign,
BitOrAssign,
BitXorAssign,
Not,
},
};

use bitflags::bitflags;

// Ideally we'd actually want this to work, but currently need something like `num`'s `Zero`
// With some design work it could be made possible
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct MyInt(u8);

impl BitAnd for MyInt {
type Output = Self;

fn bitand(self, other: Self) -> Self {
MyInt(self.0 & other.0)
}
}

impl BitOr for MyInt {
type Output = Self;

fn bitor(self, other: Self) -> Self {
MyInt(self.0 | other.0)
}
}

impl BitXor for MyInt {
type Output = Self;

fn bitxor(self, other: Self) -> Self {
MyInt(self.0 ^ other.0)
}
}

impl BitAndAssign for MyInt {
fn bitand_assign(&mut self, other: Self) {
self.0 &= other.0
}
}

impl BitOrAssign for MyInt {
fn bitor_assign(&mut self, other: Self) {
self.0 |= other.0
}
}

impl BitXorAssign for MyInt {
fn bitxor_assign(&mut self, other: Self) {
self.0 ^= other.0
}
}

impl Debug for MyInt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.0, f)
}
}

impl Display for MyInt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.0, f)
}
}

impl LowerHex for MyInt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
LowerHex::fmt(&self.0, f)
}
}

impl UpperHex for MyInt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
UpperHex::fmt(&self.0, f)
}
}

impl Octal for MyInt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Octal::fmt(&self.0, f)
}
}

impl Binary for MyInt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Binary::fmt(&self.0, f)
}
}

impl Not for MyInt {
type Output = MyInt;

fn not(self) -> Self {
MyInt(!self.0)
}
}

bitflags! {
struct Flags128: MyInt {
const A = MyInt(0b0000_0001u8);
const B = MyInt(0b0000_0010u8);
const C = MyInt(0b0000_0100u8);
}
}

fn main() {}
27 changes: 27 additions & 0 deletions tests/compile-fail/non_integer_base/all_defined.stderr.beta
@@ -0,0 +1,27 @@
error[E0308]: mismatched types
--> $DIR/all_defined.rs:115:1
|
115 | / bitflags! {
116 | | struct Flags128: MyInt {
117 | | const A = MyInt(0b0000_0001u8);
118 | | const B = MyInt(0b0000_0010u8);
119 | | const C = MyInt(0b0000_0100u8);
120 | | }
121 | | }
| |_^ expected struct `MyInt`, found integer
|
= note: this error originates in the macro `__impl_all_bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
--> $DIR/all_defined.rs:115:1
|
115 | / bitflags! {
116 | | struct Flags128: MyInt {
117 | | const A = MyInt(0b0000_0001u8);
118 | | const B = MyInt(0b0000_0010u8);
119 | | const C = MyInt(0b0000_0100u8);
120 | | }
121 | | }
| |_^ expected struct `MyInt`, found integer
|
= note: this error originates in the macro `__impl_bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
14 changes: 14 additions & 0 deletions tests/compile-fail/non_integer_base/missing_bitops.rs
@@ -0,0 +1,14 @@
use bitflags::bitflags;

#[derive(Clone, Copy)]
struct MyInt(u8);

bitflags! {
struct Flags128: MyInt {
const A = MyInt(0b0000_0001);
const B = MyInt(0b0000_0010);
const C = MyInt(0b0000_0100);
}
}

fn main() {}