diff options
Diffstat (limited to 'xpcom/rust/nsstring/gtest')
-rw-r--r-- | xpcom/rust/nsstring/gtest/Cargo.toml | 12 | ||||
-rw-r--r-- | xpcom/rust/nsstring/gtest/Test.cpp | 131 | ||||
-rw-r--r-- | xpcom/rust/nsstring/gtest/moz.build | 12 | ||||
-rw-r--r-- | xpcom/rust/nsstring/gtest/test.rs | 112 |
4 files changed, 267 insertions, 0 deletions
diff --git a/xpcom/rust/nsstring/gtest/Cargo.toml b/xpcom/rust/nsstring/gtest/Cargo.toml new file mode 100644 index 000000000..44897ec98 --- /dev/null +++ b/xpcom/rust/nsstring/gtest/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "nsstring-gtest" +version = "0.1.0" +authors = ["nobody@mozilla.com"] +license = "MPL-2.0" +description = "Tests for rust bindings to xpcom string types" + +[dependencies] +nsstring = { path = "../" } + +[lib] +path = "test.rs" diff --git a/xpcom/rust/nsstring/gtest/Test.cpp b/xpcom/rust/nsstring/gtest/Test.cpp new file mode 100644 index 000000000..93d2ee1d7 --- /dev/null +++ b/xpcom/rust/nsstring/gtest/Test.cpp @@ -0,0 +1,131 @@ +#include "gtest/gtest.h" +#include <stdint.h> +#include "nsString.h" + +extern "C" { + // This function is called by the rust code in test.rs if a non-fatal test + // failure occurs. + void GTest_ExpectFailure(const char* aMessage) { + EXPECT_STREQ(aMessage, ""); + } +} + +#define SIZE_ALIGN_CHECK(Clazz) \ + extern "C" void Rust_Test_ReprSizeAlign_##Clazz(size_t* size, size_t* align); \ + TEST(RustNsString, ReprSizeAlign_##Clazz) { \ + size_t size, align; \ + Rust_Test_ReprSizeAlign_##Clazz(&size, &align); \ + EXPECT_EQ(size, sizeof(Clazz)); \ + EXPECT_EQ(align, alignof(Clazz)); \ + } + +SIZE_ALIGN_CHECK(nsString) +SIZE_ALIGN_CHECK(nsCString) +SIZE_ALIGN_CHECK(nsFixedString) +SIZE_ALIGN_CHECK(nsFixedCString) + +#define MEMBER_CHECK(Clazz, Member) \ + extern "C" void Rust_Test_Member_##Clazz##_##Member(size_t* size, \ + size_t* align, \ + size_t* offset); \ + TEST(RustNsString, ReprMember_##Clazz##_##Member) { \ + class Hack : public Clazz { \ + public: \ + static void RunTest() { \ + size_t size, align, offset; \ + Rust_Test_Member_##Clazz##_##Member(&size, &align, &offset); \ + EXPECT_EQ(size, sizeof(mozilla::DeclVal<Hack>().Member)); \ + EXPECT_EQ(size, alignof(decltype(mozilla::DeclVal<Hack>().Member))); \ + EXPECT_EQ(offset, offsetof(Hack, Member)); \ + } \ + }; \ + static_assert(sizeof(Clazz) == sizeof(Hack), "Hack matches class"); \ + Hack::RunTest(); \ + } + +MEMBER_CHECK(nsString, mData) +MEMBER_CHECK(nsString, mLength) +MEMBER_CHECK(nsString, mFlags) +MEMBER_CHECK(nsCString, mData) +MEMBER_CHECK(nsCString, mLength) +MEMBER_CHECK(nsCString, mFlags) +MEMBER_CHECK(nsFixedString, mFixedCapacity) +MEMBER_CHECK(nsFixedString, mFixedBuf) +MEMBER_CHECK(nsFixedCString, mFixedCapacity) +MEMBER_CHECK(nsFixedCString, mFixedBuf) + +extern "C" void Rust_Test_NsStringFlags(uint32_t* f_none, + uint32_t* f_terminated, + uint32_t* f_voided, + uint32_t* f_shared, + uint32_t* f_owned, + uint32_t* f_fixed, + uint32_t* f_literal, + uint32_t* f_class_fixed); +TEST(RustNsString, NsStringFlags) { + uint32_t f_none, f_terminated, f_voided, f_shared, f_owned, f_fixed, f_literal, f_class_fixed; + Rust_Test_NsStringFlags(&f_none, &f_terminated, + &f_voided, &f_shared, + &f_owned, &f_fixed, + &f_literal, &f_class_fixed); + EXPECT_EQ(f_none, nsAString::F_NONE); + EXPECT_EQ(f_none, nsACString::F_NONE); + EXPECT_EQ(f_terminated, nsAString::F_TERMINATED); + EXPECT_EQ(f_terminated, nsACString::F_TERMINATED); + EXPECT_EQ(f_voided, nsAString::F_VOIDED); + EXPECT_EQ(f_voided, nsACString::F_VOIDED); + EXPECT_EQ(f_shared, nsAString::F_SHARED); + EXPECT_EQ(f_shared, nsACString::F_SHARED); + EXPECT_EQ(f_owned, nsAString::F_OWNED); + EXPECT_EQ(f_owned, nsACString::F_OWNED); + EXPECT_EQ(f_fixed, nsAString::F_FIXED); + EXPECT_EQ(f_fixed, nsACString::F_FIXED); + EXPECT_EQ(f_literal, nsAString::F_LITERAL); + EXPECT_EQ(f_literal, nsACString::F_LITERAL); + EXPECT_EQ(f_class_fixed, nsAString::F_CLASS_FIXED); + EXPECT_EQ(f_class_fixed, nsACString::F_CLASS_FIXED); +} + +extern "C" void Rust_StringFromCpp(const nsACString* aCStr, const nsAString* aStr); +TEST(RustNsString, StringFromCpp) { + nsAutoCString foo; + foo.AssignASCII("Hello, World!"); + + nsAutoString bar; + bar.AssignASCII("Hello, World!"); + + Rust_StringFromCpp(&foo, &bar); +} + +extern "C" void Rust_AssignFromRust(nsACString* aCStr, nsAString* aStr); +TEST(RustNsString, AssignFromRust) { + nsAutoCString cs; + nsAutoString s; + Rust_AssignFromRust(&cs, &s); + EXPECT_TRUE(cs.EqualsASCII("Hello, World!")); + EXPECT_TRUE(s.EqualsASCII("Hello, World!")); +} + +extern "C" { + void Cpp_AssignFromCpp(nsACString* aCStr, nsAString* aStr) { + aCStr->AssignASCII("Hello, World!"); + aStr->AssignASCII("Hello, World!"); + } +} +extern "C" void Rust_AssignFromCpp(); +TEST(RustNsString, AssignFromCpp) { + Rust_AssignFromCpp(); +} +extern "C" void Rust_FixedAssignFromCpp(); +TEST(RustNsString, FixedAssignFromCpp) { + Rust_FixedAssignFromCpp(); +} +extern "C" void Rust_AutoAssignFromCpp(); +TEST(RustNsString, AutoAssignFromCpp) { + Rust_AutoAssignFromCpp(); +} + +extern "C" void Rust_StringWrite(); +TEST(RustNsString, StringWrite) { + Rust_StringWrite(); +} diff --git a/xpcom/rust/nsstring/gtest/moz.build b/xpcom/rust/nsstring/gtest/moz.build new file mode 100644 index 000000000..5bed9e57e --- /dev/null +++ b/xpcom/rust/nsstring/gtest/moz.build @@ -0,0 +1,12 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +if CONFIG['MOZ_RUST']: + UNIFIED_SOURCES += [ + 'Test.cpp' + ] + +FINAL_LIBRARY = 'xul-gtest' diff --git a/xpcom/rust/nsstring/gtest/test.rs b/xpcom/rust/nsstring/gtest/test.rs new file mode 100644 index 000000000..2968a1be7 --- /dev/null +++ b/xpcom/rust/nsstring/gtest/test.rs @@ -0,0 +1,112 @@ +#![allow(non_snake_case)] + +#[macro_use] +extern crate nsstring; + +use std::fmt::Write; +use std::ffi::CString; +use std::os::raw::c_char; +use nsstring::*; + +fn nonfatal_fail(msg: String) { + extern "C" { + fn GTest_ExpectFailure(message: *const c_char); + } + unsafe { + GTest_ExpectFailure(CString::new(msg).unwrap().as_ptr()); + } +} + +/// This macro checks if the two arguments are equal, and causes a non-fatal +/// GTest test failure if they are not. +macro_rules! expect_eq { + ($x:expr, $y:expr) => { + match (&$x, &$y) { + (x, y) => if *x != *y { + nonfatal_fail(format!("check failed: (`{:?}` == `{:?}`) at {}:{}", + x, y, file!(), line!())) + } + } + } +} + +#[no_mangle] +pub extern fn Rust_StringFromCpp(cs: *const nsACString, s: *const nsAString) { + unsafe { + expect_eq!(&*cs, "Hello, World!"); + expect_eq!(&*s, "Hello, World!"); + } +} + +#[no_mangle] +pub extern fn Rust_AssignFromRust(cs: *mut nsACString, s: *mut nsAString) { + unsafe { + (*cs).assign(&nsCString::from("Hello, World!")); + expect_eq!(&*cs, "Hello, World!"); + (*s).assign(&nsString::from("Hello, World!")); + expect_eq!(&*s, "Hello, World!"); + } +} + +extern "C" { + fn Cpp_AssignFromCpp(cs: *mut nsACString, s: *mut nsAString); +} + +#[no_mangle] +pub extern fn Rust_AssignFromCpp() { + let mut cs = nsCString::new(); + let mut s = nsString::new(); + unsafe { + Cpp_AssignFromCpp(&mut *cs, &mut *s); + } + expect_eq!(cs, "Hello, World!"); + expect_eq!(s, "Hello, World!"); +} + +#[no_mangle] +pub extern fn Rust_FixedAssignFromCpp() { + let mut cs_buf: [u8; 64] = [0; 64]; + let cs_buf_ptr = &cs_buf as *const _ as usize; + let mut s_buf: [u16; 64] = [0; 64]; + let s_buf_ptr = &s_buf as *const _ as usize; + let mut cs = nsFixedCString::new(&mut cs_buf); + let mut s = nsFixedString::new(&mut s_buf); + unsafe { + Cpp_AssignFromCpp(&mut *cs, &mut *s); + } + expect_eq!(cs, "Hello, World!"); + expect_eq!(s, "Hello, World!"); + expect_eq!(cs.as_ptr() as usize, cs_buf_ptr); + expect_eq!(s.as_ptr() as usize, s_buf_ptr); +} + +#[no_mangle] +pub extern fn Rust_AutoAssignFromCpp() { + ns_auto_cstring!(cs); + ns_auto_string!(s); + unsafe { + Cpp_AssignFromCpp(&mut *cs, &mut *s); + } + expect_eq!(cs, "Hello, World!"); + expect_eq!(s, "Hello, World!"); +} + +#[no_mangle] +pub extern fn Rust_StringWrite() { + ns_auto_cstring!(cs); + ns_auto_string!(s); + + write!(s, "a").unwrap(); + write!(cs, "a").unwrap(); + expect_eq!(s, "a"); + expect_eq!(cs, "a"); + write!(s, "bc").unwrap(); + write!(cs, "bc").unwrap(); + expect_eq!(s, "abc"); + expect_eq!(cs, "abc"); + write!(s, "{}", 123).unwrap(); + write!(cs, "{}", 123).unwrap(); + expect_eq!(s, "abc123"); + expect_eq!(cs, "abc123"); +} + |