File: README.md

package info (click to toggle)
qt6-webengine 6.4.2-final%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,090,536 kB
  • sloc: cpp: 17,808,031; ansic: 5,245,139; javascript: 3,178,881; python: 1,361,176; asm: 648,577; xml: 571,140; java: 196,952; sh: 96,408; objc: 88,289; perl: 70,982; cs: 39,145; fortran: 24,137; makefile: 20,242; pascal: 12,634; sql: 10,875; yacc: 9,671; tcl: 8,385; php: 6,188; lisp: 2,848; lex: 2,263; ada: 727; ruby: 623; awk: 339; sed: 37
file content (177 lines) | stat: -rw-r--r-- 5,424 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# Rust integration into C++ Gtest targets.

This directory contains the tools for writing gtest-based tests in Rust and
integrating them into Chromium's C++ gtest binaries. The tools are all
accessible through the `rust_gtest_interop` target which is automatically
included in test targets that depend on `//testing/gtest`.

## To add rust unittests to a C++ Gtest target

A typical Gtest target is defined in a BUILD.gn file, with something like this:

`BUILD.gn`:
```gn
test("some_unittests") {
  sources = [
    "a_cpp_file.cc",
    "another_cpp_file.cc",
  ]
  deps = [
    "//testing/gtest",
  ]
}
```

To add a Rust file to the test suite, simply add it to the `rs_sources`. Unlike
other Rust crates, the `crate_root` is not specified, since it is generated from
the sources list.

`BUILD.gn`:
```gn
test("some_unittests") {
  sources = [
    "a_cpp_file.cc",
    "another_cpp_file.cc",
  ]
  rs_sources = [
    "a_rust_file.rs",
  ]
  deps = [
    "//testing/gtest",
  ]
}
```

## To write a Gtest unit test in Rust

To write a unit test, you simply write a function an decorate it with the
`#[gtest]` macro. The macro takes 2 arguments, which are the test suite name and
the test name, just like the C++ `TEST()` macro.

The `#[gtest]` macro is provided by the `rust_gtest_interop_rs` crate, and is
exported in the `prelude` module. Typically a unit test file would start with
`use rust_gtest_interop_rs::prelude::*;` which includes all of the available
gtest macros. This is similar to writing `#include
"testing/gtest/include/gtest/gtest.h"` in C++.

A Rust test:
```rs
use rust_gtest_interop_rs::prelude::*;  // Provides all the gtest macros.

#[gtest(MyTestSuite, MyTestOfThing)]
fn test() {
  ...
}
```

A C++ test:
```cpp
#include "testing/gtest/include/gtest/gtest.h"  // Provides all the gtest macros.

TEST(MyTestSuite, MyTestOfThing) {
  ...
}
```

### Expectations

We have access to many of the same EXPECT macros in Rust that are familiar to
C++ Gtest users, though they are used with Rust's macro syntax.

The macros currently available are:
```rs
expect_true!(is_friday());
expect_false!(is_saturday());

expect_eq!(2, 1 + 1);  // A == B
expect_ne!(3, 1 + 2);  // A != B

expect_lt!(1 * 1, 1 * 2);  // A < B
expect_gt!(4 * 1, 1 * 2);  // A > B
expect_le!(2 * 1, 1 * 2);  // A <= B
expect_ge!(3 * 1, 2 * 3);  // A >= B
```

### Returning a Result

A C++ test always returns void and Rust tests usually do as well. But if your
test calls a function that returns `Result`, it is convenient to make use of the
[`?` operator](https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator)
instead of checking the Result value explicitly. Thus a test can either return:

1. `()` aka void.
1. `std::result::Result<(), E>` for any `E` that can be converted to a
   `std::error::Error`. (Or in Rust parlance, for any `E` for which there is
   `Into<std::error::Error>`). Common error types are `std::io::Error` or
   `String`.

If the test with a `std::result::Result` return type returns `Result::Err`, the
test will fail and display the error.

In this example, the test will fail if it can not read from `file.txt`, or if it
does not contain `"hello world"`:
```rs
#[gtest(TestingIO, ReadFile)]
fn test() -> std::io::Result {
  let s = std::fs::read_to_string("file.txt")?;
  expect_eq!(s, "hello world");
  Ok(())
}
```

### Shared helper utilities

Sometimes tests across different test files want to share helper utilities. Such
helpers should be placed in a separate GN target, typically named with a
`_test_support` suffix, such as `starship_test_support` for the
`starship_unittests`. And would also usually be found in a `test/` subdirectory.

#### Example
The `starship_unittests` test() target would include any unit test files, such as
`starship_unittest.rs`. And the `starship_test_support` static_library() target
would include the files in the `test/` subdirectory, such as
`starship_test_helper.rs` and `starship_test_things.rs`.
```
src/
  starship/
    starship_unittest.rs
    test/
      starship_test_helper.rs
      starship_test_things.rs
```

### Specifying a C++ TestSuite class

In C++, a chosen TestSuite, which subclasses `testing::Test`, can be specified
with the `TEST_F()` macro. For example `TEST_F(SomeSubclassOfTestingTest,
Gadgets)`. The same can be done in Rust, albeit with a slight bit more
indirection. The `#[gtest_suite]` macro can be specified on the test function,
after the `#[gtest]` macro, in order to chose the TestSuite class. The macro
takes an argument which is the name of a C++ function that returns the output of
`rust_gtest_interop::rust_gtest_factory_for_subclass<T>()` where `T` is the
class to use as the TestSuite. For example:

In a C++ file:
```cpp
class ChosenClass: public testing::Test {};

/// This function can be used in #[gtest_suite].
extern "C" testing::Test* chosen_class_gtest_factory(void(*f)()) {
  return rust_gtest_interop::rust_gtest_factory_for_subclass<ChosenClass>(f);
}
```

In Rust tests:
```rs
use rust_gtest_interop::*;

#[gtest(ChosenClassTest, Gadgets)]
#[gtest_suite(chosen_class_gtest_factory)]
fn test() {
  // This test uses ChosenClass as its TestSuite.
}
```

Then the `ChosenClassTest.Gadgets` test will run with `ChosenClass` as its
TestSuite class. Note that the C++ function must be marked `extern "C"` at this
time, until we can generate access to C++-mangled functions from Rust.