summaryrefslogtreecommitdiffstats
path: root/xpcom/rust/nsstring/gtest
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/rust/nsstring/gtest')
-rw-r--r--xpcom/rust/nsstring/gtest/Cargo.toml12
-rw-r--r--xpcom/rust/nsstring/gtest/Test.cpp131
-rw-r--r--xpcom/rust/nsstring/gtest/moz.build12
-rw-r--r--xpcom/rust/nsstring/gtest/test.rs112
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");
+}
+