this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include "mro.h"
3
4#include "gtest/gtest.h"
5
6#include "test-utils.h"
7
8namespace py {
9namespace testing {
10
11using MroTest = RuntimeFixture;
12
13TEST_F(MroTest, ComputeMroReturnsList) {
14 HandleScope scope(thread_);
15 ASSERT_FALSE(runFromCStr(runtime_, R"(
16class A: pass
17)")
18 .isError());
19 Object a_obj(&scope, mainModuleAt(runtime_, "A"));
20 Type a(&scope, *a_obj);
21 a.setBases(runtime_->implicitBases());
22 Object result_obj(&scope, computeMro(thread_, a));
23 ASSERT_TRUE(result_obj.isTuple());
24 Tuple result(&scope, *result_obj);
25 ASSERT_EQ(result.length(), 2);
26 EXPECT_EQ(result.at(0), a);
27 EXPECT_EQ(result.at(1), runtime_->typeAt(LayoutId::kObject));
28}
29
30TEST_F(MroTest, ComputeMroWithTypeSubclassReturnsList) {
31 HandleScope scope(thread_);
32 ASSERT_FALSE(runFromCStr(runtime_, R"(
33class Meta(type): pass
34class A(metaclass=Meta): pass
35class B(A): pass
36)")
37 .isError());
38 Object a_obj(&scope, mainModuleAt(runtime_, "A"));
39 Type b(&scope, mainModuleAt(runtime_, "B"));
40 b.setBases(runtime_->newTupleWith1(a_obj));
41 Object result_obj(&scope, computeMro(thread_, b));
42 Tuple result(&scope, *result_obj);
43 ASSERT_EQ(result.length(), 3);
44 EXPECT_EQ(result.at(0), b);
45 EXPECT_EQ(result.at(1), a_obj);
46 EXPECT_EQ(result.at(2), runtime_->typeAt(LayoutId::kObject));
47}
48
49TEST_F(MroTest, ComputeMroWithMultipleTypeSubclassesReturnsList) {
50 HandleScope scope(thread_);
51 ASSERT_FALSE(runFromCStr(runtime_, R"(
52class Meta(type): pass
53class A(metaclass=Meta): pass
54class B(metaclass=Meta): pass
55class C(A, B): pass
56)")
57 .isError());
58 Object a_obj(&scope, mainModuleAt(runtime_, "A"));
59 Object b_obj(&scope, mainModuleAt(runtime_, "B"));
60 Type c(&scope, mainModuleAt(runtime_, "C"));
61 c.setBases(runtime_->newTupleWith2(a_obj, b_obj));
62 Object result_obj(&scope, computeMro(thread_, c));
63 Tuple result(&scope, *result_obj);
64 ASSERT_EQ(result.length(), 4);
65 EXPECT_EQ(result.at(0), c);
66 EXPECT_EQ(result.at(1), a_obj);
67 EXPECT_EQ(result.at(2), b_obj);
68 EXPECT_EQ(result.at(3), runtime_->typeAt(LayoutId::kObject));
69}
70
71TEST_F(MroTest, ComputeMroWithIncompatibleBasesRaisesTypeError) {
72 HandleScope scope(thread_);
73 ASSERT_FALSE(runFromCStr(runtime_, R"(
74class A: pass
75class B(A): pass
76)")
77 .isError());
78 Object a_obj(&scope, mainModuleAt(runtime_, "A"));
79 Object b_obj(&scope, mainModuleAt(runtime_, "B"));
80 Type c(&scope, runtime_->newType());
81 c.setBases(runtime_->newTupleWith2(a_obj, b_obj));
82 EXPECT_TRUE(raisedWithStr(computeMro(thread_, c), LayoutId::kTypeError,
83 "Cannot create a consistent method resolution "
84 "order (MRO) for bases A, B"));
85}
86
87} // namespace testing
88} // namespace py