tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestResultExtensions.cpp (17783B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "gtest/gtest.h"
      8 
      9 #include "mozilla/ResultExtensions.h"
     10 #include "nsLocalFile.h"
     11 
     12 #include <functional>
     13 
     14 using namespace mozilla;
     15 
     16 namespace {
     17 class TestClass {
     18 public:
     19  static constexpr int kTestValue = 42;
     20 
     21  nsresult NonOverloadedNoInput(int* aOut) {
     22    *aOut = kTestValue;
     23    return NS_OK;
     24  }
     25  nsresult NonOverloadedNoInputFails(int* aOut) { return NS_ERROR_FAILURE; }
     26 
     27  nsresult NonOverloadedNoInputConst(int* aOut) const {
     28    *aOut = kTestValue;
     29    return NS_OK;
     30  }
     31  nsresult NonOverloadedNoInputFailsConst(int* aOut) const {
     32    return NS_ERROR_FAILURE;
     33  }
     34 
     35  nsresult NonOverloadedNoInputRef(int& aOut) {
     36    aOut = kTestValue;
     37    return NS_OK;
     38  }
     39  nsresult NonOverloadedNoInputFailsRef(int& aOut) { return NS_ERROR_FAILURE; }
     40 
     41  nsresult NonOverloadedNoInputComplex(std::pair<int, int>* aOut) {
     42    *aOut = std::pair{kTestValue, kTestValue};
     43    return NS_OK;
     44  }
     45  nsresult NonOverloadedNoInputFailsComplex(std::pair<int, int>* aOut) {
     46    return NS_ERROR_FAILURE;
     47  }
     48 
     49  nsresult NonOverloadedWithInput(int aIn, int* aOut) {
     50    *aOut = aIn;
     51    return NS_OK;
     52  }
     53  nsresult NonOverloadedWithInputFails(int aIn, int* aOut) {
     54    return NS_ERROR_FAILURE;
     55  }
     56 
     57  nsresult NonOverloadedNoOutput(int aIn) { return NS_OK; }
     58  nsresult NonOverloadedNoOutputFails(int aIn) { return NS_ERROR_FAILURE; }
     59 
     60  nsresult PolymorphicNoInput(nsIFile** aOut) {
     61    *aOut = MakeAndAddRef<nsLocalFile>().take();
     62    return NS_OK;
     63  }
     64  nsresult PolymorphicNoInputFails(nsIFile** aOut) { return NS_ERROR_FAILURE; }
     65 };
     66 
     67 class RefCountedTestClass {
     68 public:
     69  NS_INLINE_DECL_REFCOUNTING(RefCountedTestClass);
     70 
     71  static constexpr int kTestValue = 42;
     72 
     73  nsresult NonOverloadedNoInput(int* aOut) {
     74    *aOut = kTestValue;
     75    return NS_OK;
     76  }
     77  nsresult NonOverloadedNoInputFails(int* aOut) { return NS_ERROR_FAILURE; }
     78 
     79 private:
     80  ~RefCountedTestClass() = default;
     81 };
     82 
     83 // Check that DerefedType deduces the types as expected
     84 static_assert(std::is_same_v<mozilla::detail::DerefedType<RefCountedTestClass&>,
     85                             RefCountedTestClass>);
     86 static_assert(std::is_same_v<mozilla::detail::DerefedType<RefCountedTestClass*>,
     87                             RefCountedTestClass>);
     88 static_assert(
     89    std::is_same_v<mozilla::detail::DerefedType<RefPtr<RefCountedTestClass>>,
     90                   RefCountedTestClass>);
     91 
     92 static_assert(std::is_same_v<mozilla::detail::DerefedType<nsIFile&>, nsIFile>);
     93 static_assert(std::is_same_v<mozilla::detail::DerefedType<nsIFile*>, nsIFile>);
     94 static_assert(
     95    std::is_same_v<mozilla::detail::DerefedType<nsCOMPtr<nsIFile>>, nsIFile>);
     96 }  // namespace
     97 
     98 TEST(ResultExtensions_ToResultInvoke, Lambda_NoInput)
     99 {
    100  TestClass foo;
    101 
    102  // success
    103  {
    104    auto valOrErr = ToResultInvoke<int>(
    105        [&foo](int* out) { return foo.NonOverloadedNoInput(out); });
    106    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    107    ASSERT_TRUE(valOrErr.isOk());
    108    ASSERT_EQ(TestClass::kTestValue, valOrErr.unwrap());
    109  }
    110 
    111  // failure
    112  {
    113    auto valOrErr = ToResultInvoke<int>(
    114        [&foo](int* out) { return foo.NonOverloadedNoInputFails(out); });
    115    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    116    ASSERT_TRUE(valOrErr.isErr());
    117    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    118  }
    119 }
    120 
    121 TEST(ResultExtensions_ToResultInvoke, MemFn_NoInput)
    122 {
    123  TestClass foo;
    124 
    125  // success
    126  {
    127    auto valOrErr =
    128        ToResultInvoke<int>(std::mem_fn(&TestClass::NonOverloadedNoInput), foo);
    129    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    130    ASSERT_TRUE(valOrErr.isOk());
    131    ASSERT_EQ(TestClass::kTestValue, valOrErr.unwrap());
    132  }
    133 
    134  // failure
    135  {
    136    auto valOrErr = ToResultInvoke<int>(
    137        std::mem_fn(&TestClass::NonOverloadedNoInputFails), foo);
    138    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    139    ASSERT_TRUE(valOrErr.isErr());
    140    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    141  }
    142 }
    143 
    144 TEST(ResultExtensions_ToResultInvoke, MemFn_Polymorphic_NoInput)
    145 {
    146  TestClass foo;
    147 
    148  // success
    149  {
    150    auto valOrErr = ToResultInvoke<nsCOMPtr<nsIFile>>(
    151        std::mem_fn(&TestClass::PolymorphicNoInput), foo);
    152    static_assert(std::is_same_v<decltype(valOrErr),
    153                                 Result<nsCOMPtr<nsIFile>, nsresult>>);
    154    ASSERT_TRUE(valOrErr.isOk());
    155    ASSERT_NE(nullptr, valOrErr.inspect());
    156 
    157    ASSERT_EQ(ToResultInvoke<nsString>(std::mem_fn(&nsIFile::GetPath),
    158                                       *MakeRefPtr<nsLocalFile>())
    159                  .inspect(),
    160              ToResultInvoke<nsString>(std::mem_fn(&nsIFile::GetPath),
    161                                       valOrErr.inspect())
    162                  .inspect());
    163  }
    164 
    165  // failure
    166  {
    167    auto valOrErr = ToResultInvoke<nsCOMPtr<nsIFile>>(
    168        std::mem_fn(&TestClass::PolymorphicNoInputFails), foo);
    169    static_assert(std::is_same_v<decltype(valOrErr),
    170                                 Result<nsCOMPtr<nsIFile>, nsresult>>);
    171    ASSERT_TRUE(valOrErr.isErr());
    172    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    173  }
    174 }
    175 
    176 TEST(ResultExtensions_ToResultInvokeMember, NoInput)
    177 {
    178  TestClass foo;
    179 
    180  // success
    181  {
    182    auto valOrErr = ToResultInvokeMember(foo, &TestClass::NonOverloadedNoInput);
    183    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    184    ASSERT_TRUE(valOrErr.isOk());
    185    ASSERT_EQ(TestClass::kTestValue, valOrErr.unwrap());
    186  }
    187 
    188  // failure
    189  {
    190    auto valOrErr =
    191        ToResultInvokeMember(foo, &TestClass::NonOverloadedNoInputFails);
    192    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    193    ASSERT_TRUE(valOrErr.isErr());
    194    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    195  }
    196 }
    197 
    198 TEST(ResultExtensions_ToResultInvokeMember, NoInput_Const)
    199 {
    200  const TestClass foo;
    201 
    202  // success
    203  {
    204    auto valOrErr =
    205        ToResultInvokeMember(foo, &TestClass::NonOverloadedNoInputConst);
    206    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    207    ASSERT_TRUE(valOrErr.isOk());
    208    ASSERT_EQ(TestClass::kTestValue, valOrErr.unwrap());
    209  }
    210 
    211  // failure
    212  {
    213    auto valOrErr =
    214        ToResultInvokeMember(foo, &TestClass::NonOverloadedNoInputFailsConst);
    215    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    216    ASSERT_TRUE(valOrErr.isErr());
    217    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    218  }
    219 }
    220 
    221 TEST(ResultExtensions_ToResultInvokeMember, NoInput_Ref)
    222 {
    223  TestClass foo;
    224 
    225  // success
    226  {
    227    auto valOrErr =
    228        ToResultInvokeMember(foo, &TestClass::NonOverloadedNoInputRef);
    229    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    230    ASSERT_TRUE(valOrErr.isOk());
    231    ASSERT_EQ(TestClass::kTestValue, valOrErr.unwrap());
    232  }
    233 
    234  // failure
    235  {
    236    auto valOrErr =
    237        ToResultInvokeMember(foo, &TestClass::NonOverloadedNoInputFailsRef);
    238    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    239    ASSERT_TRUE(valOrErr.isErr());
    240    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    241  }
    242 }
    243 
    244 TEST(ResultExtensions_ToResultInvokeMember, NoInput_Complex)
    245 {
    246  TestClass foo;
    247 
    248  // success
    249  {
    250    auto valOrErr =
    251        ToResultInvokeMember(foo, &TestClass::NonOverloadedNoInputComplex);
    252    static_assert(std::is_same_v<decltype(valOrErr),
    253                                 Result<std::pair<int, int>, nsresult>>);
    254    ASSERT_TRUE(valOrErr.isOk());
    255    ASSERT_EQ((std::pair{TestClass::kTestValue, TestClass::kTestValue}),
    256              valOrErr.unwrap());
    257  }
    258 
    259  // failure
    260  {
    261    auto valOrErr =
    262        ToResultInvokeMember(foo, &TestClass::NonOverloadedNoInputFailsComplex);
    263    static_assert(std::is_same_v<decltype(valOrErr),
    264                                 Result<std::pair<int, int>, nsresult>>);
    265    ASSERT_TRUE(valOrErr.isErr());
    266    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    267  }
    268 }
    269 
    270 TEST(ResultExtensions_ToResultInvokeMember, WithInput)
    271 {
    272  TestClass foo;
    273 
    274  // success
    275  {
    276    auto valOrErr = ToResultInvokeMember(
    277        foo, &TestClass::NonOverloadedWithInput, -TestClass::kTestValue);
    278    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    279    ASSERT_TRUE(valOrErr.isOk());
    280    ASSERT_EQ(-TestClass::kTestValue, valOrErr.unwrap());
    281  }
    282 
    283  // failure
    284  {
    285    auto valOrErr = ToResultInvokeMember(
    286        foo, &TestClass::NonOverloadedWithInputFails, -TestClass::kTestValue);
    287    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    288    ASSERT_TRUE(valOrErr.isErr());
    289    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    290  }
    291 }
    292 
    293 TEST(ResultExtensions_ToResultInvokeMember, NoOutput)
    294 {
    295  TestClass foo;
    296 
    297  // success
    298  {
    299    auto valOrErr = ToResultInvokeMember(foo, &TestClass::NonOverloadedNoOutput,
    300                                         -TestClass::kTestValue);
    301    static_assert(std::is_same_v<decltype(valOrErr), Result<Ok, nsresult>>);
    302    ASSERT_TRUE(valOrErr.isOk());
    303  }
    304 
    305  // failure
    306  {
    307    auto valOrErr = ToResultInvokeMember(
    308        foo, &TestClass::NonOverloadedNoOutputFails, -TestClass::kTestValue);
    309    static_assert(std::is_same_v<decltype(valOrErr), Result<Ok, nsresult>>);
    310    ASSERT_TRUE(valOrErr.isErr());
    311    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    312  }
    313 }
    314 
    315 TEST(ResultExtensions_ToResultInvokeMember, NoInput_Macro)
    316 {
    317  TestClass foo;
    318 
    319  // success
    320  {
    321    auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER(foo, NonOverloadedNoInput);
    322    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    323    ASSERT_TRUE(valOrErr.isOk());
    324    ASSERT_EQ(TestClass::kTestValue, valOrErr.unwrap());
    325  }
    326 
    327  // failure
    328  {
    329    auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER(foo, NonOverloadedNoInputFails);
    330    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    331    ASSERT_TRUE(valOrErr.isErr());
    332    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    333  }
    334 }
    335 
    336 TEST(ResultExtensions_ToResultInvokeMember, NoInput_Const_Macro)
    337 {
    338  const TestClass foo;
    339 
    340  // success
    341  {
    342    auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER(foo, NonOverloadedNoInputConst);
    343    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    344    ASSERT_TRUE(valOrErr.isOk());
    345    ASSERT_EQ(TestClass::kTestValue, valOrErr.unwrap());
    346  }
    347 
    348  // failure
    349  {
    350    auto valOrErr =
    351        MOZ_TO_RESULT_INVOKE_MEMBER(foo, NonOverloadedNoInputFailsConst);
    352    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    353    ASSERT_TRUE(valOrErr.isErr());
    354    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    355  }
    356 }
    357 
    358 TEST(ResultExtensions_ToResultInvokeMember, NoInput_Ref_Macro)
    359 {
    360  TestClass foo;
    361 
    362  // success
    363  {
    364    auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER(foo, NonOverloadedNoInputRef);
    365    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    366    ASSERT_TRUE(valOrErr.isOk());
    367    ASSERT_EQ(TestClass::kTestValue, valOrErr.unwrap());
    368  }
    369 
    370  // failure
    371  {
    372    auto valOrErr =
    373        MOZ_TO_RESULT_INVOKE_MEMBER(foo, NonOverloadedNoInputFailsRef);
    374    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    375    ASSERT_TRUE(valOrErr.isErr());
    376    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    377  }
    378 }
    379 
    380 TEST(ResultExtensions_ToResultInvokeMember, NoInput_Complex_Macro)
    381 {
    382  TestClass foo;
    383 
    384  // success
    385  {
    386    auto valOrErr =
    387        MOZ_TO_RESULT_INVOKE_MEMBER(foo, NonOverloadedNoInputComplex);
    388    static_assert(std::is_same_v<decltype(valOrErr),
    389                                 Result<std::pair<int, int>, nsresult>>);
    390    ASSERT_TRUE(valOrErr.isOk());
    391    ASSERT_EQ((std::pair{TestClass::kTestValue, TestClass::kTestValue}),
    392              valOrErr.unwrap());
    393  }
    394 
    395  // failure
    396  {
    397    auto valOrErr =
    398        MOZ_TO_RESULT_INVOKE_MEMBER(foo, NonOverloadedNoInputFailsComplex);
    399 
    400    static_assert(std::is_same_v<decltype(valOrErr),
    401                                 Result<std::pair<int, int>, nsresult>>);
    402    ASSERT_TRUE(valOrErr.isErr());
    403    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    404  }
    405 }
    406 
    407 TEST(ResultExtensions_ToResultInvokeMember, WithInput_Macro)
    408 {
    409  TestClass foo;
    410 
    411  // success
    412  {
    413    auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER(foo, NonOverloadedWithInput,
    414                                                -TestClass::kTestValue);
    415    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    416    ASSERT_TRUE(valOrErr.isOk());
    417    ASSERT_EQ(-TestClass::kTestValue, valOrErr.unwrap());
    418  }
    419 
    420  // failure
    421  {
    422    auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER(
    423        foo, NonOverloadedWithInputFails, -TestClass::kTestValue);
    424    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    425    ASSERT_TRUE(valOrErr.isErr());
    426    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    427  }
    428 }
    429 
    430 TEST(ResultExtensions_ToResultInvokeMember, NoOutput_Macro)
    431 {
    432  TestClass foo;
    433 
    434  // success
    435  {
    436    auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER(foo, NonOverloadedNoOutput,
    437                                                -TestClass::kTestValue);
    438    static_assert(std::is_same_v<decltype(valOrErr), Result<Ok, nsresult>>);
    439    ASSERT_TRUE(valOrErr.isOk());
    440  }
    441 
    442  // failure
    443  {
    444    auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER(foo, NonOverloadedNoOutputFails,
    445                                                -TestClass::kTestValue);
    446    static_assert(std::is_same_v<decltype(valOrErr), Result<Ok, nsresult>>);
    447    ASSERT_TRUE(valOrErr.isErr());
    448    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    449  }
    450 }
    451 
    452 TEST(ResultExtensions_ToResultInvokeMember, NoInput_Complex_Macro_Typed)
    453 {
    454  TestClass foo;
    455 
    456  // success
    457  {
    458    auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(
    459        (std::pair<int, int>), foo, NonOverloadedNoInputComplex);
    460    static_assert(std::is_same_v<decltype(valOrErr),
    461                                 Result<std::pair<int, int>, nsresult>>);
    462    ASSERT_TRUE(valOrErr.isOk());
    463    ASSERT_EQ((std::pair{TestClass::kTestValue, TestClass::kTestValue}),
    464              valOrErr.unwrap());
    465  }
    466 
    467  // failure
    468  {
    469    auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(
    470        (std::pair<int, int>), foo, NonOverloadedNoInputFailsComplex);
    471    static_assert(std::is_same_v<decltype(valOrErr),
    472                                 Result<std::pair<int, int>, nsresult>>);
    473    ASSERT_TRUE(valOrErr.isErr());
    474    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    475  }
    476 }
    477 
    478 TEST(ResultExtensions_ToResultInvokeMember, RefPtr_NoInput)
    479 {
    480  auto foo = MakeRefPtr<RefCountedTestClass>();
    481 
    482  // success
    483  {
    484    auto valOrErr =
    485        ToResultInvokeMember(foo, &RefCountedTestClass::NonOverloadedNoInput);
    486    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    487    ASSERT_TRUE(valOrErr.isOk());
    488    ASSERT_EQ(TestClass::kTestValue, valOrErr.unwrap());
    489  }
    490 
    491  // failure
    492  {
    493    auto valOrErr = ToResultInvokeMember(
    494        foo, &RefCountedTestClass::NonOverloadedNoInputFails);
    495    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    496    ASSERT_TRUE(valOrErr.isErr());
    497    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    498  }
    499 }
    500 
    501 TEST(ResultExtensions_ToResultInvokeMember, RefPtr_NoInput_Macro)
    502 {
    503  auto foo = MakeRefPtr<RefCountedTestClass>();
    504 
    505  // success
    506  {
    507    auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER(foo, NonOverloadedNoInput);
    508    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    509    ASSERT_TRUE(valOrErr.isOk());
    510    ASSERT_EQ(TestClass::kTestValue, valOrErr.unwrap());
    511  }
    512 
    513  // failure
    514  {
    515    auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER(foo, NonOverloadedNoInputFails);
    516    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    517    ASSERT_TRUE(valOrErr.isErr());
    518    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    519  }
    520 }
    521 
    522 TEST(ResultExtensions_ToResultInvokeMember, RawPtr_NoInput_Macro)
    523 {
    524  auto foo = MakeRefPtr<RefCountedTestClass>();
    525  auto* fooPtr = foo.get();
    526 
    527  // success
    528  {
    529    auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER(fooPtr, NonOverloadedNoInput);
    530    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    531    ASSERT_TRUE(valOrErr.isOk());
    532    ASSERT_EQ(TestClass::kTestValue, valOrErr.unwrap());
    533  }
    534 
    535  // failure
    536  {
    537    auto valOrErr =
    538        MOZ_TO_RESULT_INVOKE_MEMBER(fooPtr, NonOverloadedNoInputFails);
    539    static_assert(std::is_same_v<decltype(valOrErr), Result<int, nsresult>>);
    540    ASSERT_TRUE(valOrErr.isErr());
    541    ASSERT_EQ(NS_ERROR_FAILURE, valOrErr.unwrapErr());
    542  }
    543 }
    544 
    545 TEST(ResultExtensions_ToResultInvokeMember, nsCOMPtr_AbstractClass_WithInput)
    546 {
    547  nsCOMPtr<nsIFile> file = MakeAndAddRef<nsLocalFile>();
    548 
    549  auto valOrErr = ToResultInvokeMember(file, &nsIFile::Equals, file);
    550  static_assert(std::is_same_v<decltype(valOrErr), Result<bool, nsresult>>);
    551  ASSERT_TRUE(valOrErr.isOk());
    552  ASSERT_EQ(true, valOrErr.unwrap());
    553 }
    554 
    555 TEST(ResultExtensions_ToResultInvokeMember,
    556     RawPtr_AbstractClass_WithInput_Macro)
    557 {
    558  nsCOMPtr<nsIFile> file = MakeAndAddRef<nsLocalFile>();
    559  auto* filePtr = file.get();
    560 
    561  auto valOrErr = MOZ_TO_RESULT_INVOKE_MEMBER(filePtr, Equals, file);
    562  static_assert(std::is_same_v<decltype(valOrErr), Result<bool, nsresult>>);
    563  ASSERT_TRUE(valOrErr.isOk());
    564  ASSERT_EQ(true, valOrErr.unwrap());
    565 }
    566 
    567 TEST(ResultExtensions_ToResultInvokeMember,
    568     RawPtr_AbstractClass_NoInput_Macro_Typed)
    569 {
    570  nsCOMPtr<nsIFile> file = MakeAndAddRef<nsLocalFile>();
    571  auto* filePtr = file.get();
    572 
    573  auto valOrErr =
    574      MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(nsCOMPtr<nsIFile>, filePtr, Clone);
    575  static_assert(
    576      std::is_same_v<decltype(valOrErr), Result<nsCOMPtr<nsIFile>, nsresult>>);
    577  ASSERT_TRUE(valOrErr.isOk());
    578  ASSERT_NE(nullptr, valOrErr.unwrap());
    579 }