#![feature(unicode)]
use std::char;
use std::str::{self,FromStr};
use std::hash::{Hash,SipHasher};
extern crate encode_unicode;
use encode_unicode::*;
#[test]
fn equal_defaults() {
assert_eq!(Utf8Char::default().to_char(), char::default());
assert_eq!(Utf16Char::default().to_char(), char::default());
}
#[test]
fn same_size_as_char() {
use std::mem::size_of;
assert_eq!(size_of::<Utf8Char>(), size_of::<char>());
assert_eq!(size_of::<Utf16Char>(), size_of::<char>());
}
const EDGES_AND_BETWEEN: [u32;13] = [
0x0, 0x3b, 0x7f, 0x80, 0x111, 0x7ff, 0x800, 0xd7ff, 0xe000, 0xffff, 0x10000, 0xabcde, 0x10ffff,];
fn test(c: u32) {
let c = char::from_u32(c).expect(&format!("{:x} is not a valid char", c));
assert_eq!(char::from_u32_detailed(c as u32), Ok(c));
let sh = &mut SipHasher::new();
let uc = c.to_utf8();
assert_eq!(uc.to_char(), c);
assert_eq!(uc.hash(sh), c.hash(sh));
let mut reference_dst = [0;4];
let mut len = None;
for i in 0..5 {
let mut test_dst = [0;4];
len = c.encode_utf8(&mut reference_dst[..i]);
assert_eq!(c.to_utf8_slice(&mut test_dst[..i]), len);
assert_eq!(test_dst, reference_dst);
assert_eq!(uc.to_slice(&mut test_dst[..i]), len);
assert_eq!(test_dst, reference_dst);
}
let len = len.expect(&format!("encode_utf8 never succeded: c={}={:x}, utf8={:?}", c, c as u32, reference_dst));
let str_ = str::from_utf8(&reference_dst[..len]).unwrap();
let ustr = Utf8Char::from_str(str_).unwrap();
assert_eq!(ustr.to_array().0, uc.to_array().0);
assert_eq!(reference_dst[0].extra_utf8_bytes(), Ok(len-1));
assert_eq!(reference_dst[0].extra_utf8_bytes_unchecked(), len-1);
assert_eq!(c.to_utf8_array(), (reference_dst, len));
assert_eq!(char::from_utf8_array(reference_dst), Ok(c));
assert_eq!(char::from_utf8_slice(&reference_dst[..len]), Ok((c,len)));
for other in &EDGES_AND_BETWEEN {
let other = unsafe{ char::from_u32_unchecked(*other) };
let uother = other.to_utf8();
assert_eq!(uc == uother, c == other);
assert_eq!(uc.hash(sh)==other.hash(sh), c.hash(sh)==uother.hash(sh));
assert_eq!(uc.cmp(&uother), c.cmp(&other));
}
assert_eq!(uc.to_array(), (reference_dst, len));
assert_eq!(Utf8Char::from_array(reference_dst), Ok(uc));
assert_eq!(Utf8Char::from_slice_start(&reference_dst[..len]), Ok((uc,len)));
assert_eq!(c.iter_utf8_bytes().len(), len);
let iterated: Vec<_> = c.iter_utf8_bytes().collect();
assert_eq!(iterated[..], reference_dst[..len]);
assert_eq!(<AsRef<[u8]>>::as_ref(&uc), &iterated[..]);
let uc = c.to_utf16();
assert_eq!(uc.to_char(), c);
assert_eq!(uc.hash(sh), c.hash(sh));
let mut reference_dst = [0;2];
let mut len = None;
for i in 0..3 {
let mut test_dst = [0;2];
len = c.encode_utf16(&mut reference_dst[..i]);
assert_eq!(c.to_utf16_slice(&mut test_dst[..i]), len);
assert_eq!(test_dst, reference_dst);
assert_eq!(uc.to_slice(&mut test_dst[..i]), len);
assert_eq!(test_dst, reference_dst);
}
let len = len.unwrap();
assert_eq!(reference_dst[0].utf16_needs_extra_unit(), Some(len==2));
assert_eq!(reference_dst[0].utf16_is_leading_surrogate(), len==2);
assert_eq!(char::from_utf16_slice(&reference_dst[..len]), Ok((c,len)));
for other in &EDGES_AND_BETWEEN {
let other = unsafe{ char::from_u32_unchecked(*other) };
let uother = other.to_utf16();
assert_eq!(uc == uother, c == other);
assert_eq!(uc.hash(sh)==other.hash(sh), c.hash(sh)==uother.hash(sh));
assert_eq!(uc.cmp(&uother), c.cmp(&other));
}
let tuple = c.to_utf16_tuple();
assert_eq!([tuple.0, tuple.1.unwrap_or(0)], reference_dst);
assert_eq!(char::from_utf16_tuple(tuple), Ok(c));
assert_eq!(c.to_utf16().to_char(), c);
assert_eq!(c.iter_utf16_units().len(), len);
let iterated: Vec<_> = c.iter_utf16_units().collect();
assert_eq!(*iterated, reference_dst[0..len]);
assert_eq!(<AsRef<[u16]>>::as_ref(&uc), &iterated[..]);
}
#[test]
fn edges_middle() {
for c in &EDGES_AND_BETWEEN {
test(*c);
}
}
#[test]
#[ignore]
fn all() {
for c in std::iter::Iterator::chain(0..0xd800, 0xe000..0x110000) {
test(c);
}
}