this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include "under-collections-module.h"
3
4#include "gtest/gtest.h"
5
6#include "builtins-module.h"
7#include "builtins.h"
8#include "objects.h"
9#include "runtime.h"
10#include "test-utils.h"
11
12namespace py {
13
14namespace testing {
15
16using UnderCollectionsModuleTest = RuntimeFixture;
17
18TEST_F(UnderCollectionsModuleTest, DunderNewConstructsDeque) {
19 HandleScope scope(thread_);
20 Type type(&scope, runtime_->typeAt(LayoutId::kDeque));
21 Object result(&scope, runBuiltin(METH(deque, __new__), type));
22 ASSERT_TRUE(result.isDeque());
23 Deque deque(&scope, *result);
24 EXPECT_EQ(deque.left(), 0);
25 EXPECT_EQ(deque.numItems(), 0);
26 EXPECT_EQ(deque.capacity(), 0);
27 EXPECT_EQ(deque.items(), SmallInt::fromWord(0));
28}
29
30TEST_F(UnderCollectionsModuleTest, DequeAppendInsertsElementToEnd) {
31 HandleScope scope(thread_);
32 Deque self(&scope, runtime_->newDeque());
33 // Test underlying array growth
34 for (int i = 0; i < 30; i++) {
35 Object value(&scope, SmallInt::fromWord(i));
36 Object result(&scope, runBuiltin(METH(deque, append), self, value));
37 EXPECT_EQ(*result, NoneType::object());
38 }
39
40 EXPECT_EQ(self.numItems(), 30);
41 for (int i = 0; i < 30; i++) {
42 EXPECT_TRUE(isIntEqualsWord(self.at(i), i)) << i;
43 }
44}
45
46TEST_F(UnderCollectionsModuleTest, DequeAppendAfterAppendleftResizesCorrectly) {
47 HandleScope scope(thread_);
48 Deque self(&scope, runtime_->newDeque());
49 // Test underlying array growth
50 Object value(&scope, SmallInt::fromWord(0));
51 Object result(&scope, runBuiltin(METH(deque, appendleft), self, value));
52 EXPECT_EQ(*result, NoneType::object());
53 for (int i = 1; i < 30; i++) {
54 value = SmallInt::fromWord(i);
55 result = runBuiltin(METH(deque, append), self, value);
56 EXPECT_EQ(*result, NoneType::object());
57 }
58
59 EXPECT_EQ(self.numItems(), 30);
60 for (int i = 0; i < 30; i++) {
61 EXPECT_TRUE(isIntEqualsWord(self.at(i), i)) << i;
62 }
63}
64
65TEST_F(UnderCollectionsModuleTest, DequeAppendleftInsertsElementToFront) {
66 HandleScope scope(thread_);
67 Deque self(&scope, runtime_->newDeque());
68 Object value(&scope, SmallInt::fromWord(1));
69 Object value1(&scope, SmallInt::fromWord(2));
70 runBuiltin(METH(deque, appendleft), self, value);
71 Object result(&scope, runBuiltin(METH(deque, appendleft), self, value1));
72 EXPECT_EQ(*result, NoneType::object());
73
74 EXPECT_EQ(self.numItems(), 2);
75 EXPECT_TRUE(isIntEqualsWord(self.at(self.capacity() - 1), 1));
76 EXPECT_TRUE(isIntEqualsWord(self.at(self.capacity() - 2), 2));
77}
78
79TEST_F(UnderCollectionsModuleTest, DequeClearRemovesElements) {
80 HandleScope scope(thread_);
81 Deque self(&scope, runtime_->newDeque());
82 Object value(&scope, SmallInt::fromWord(0));
83 Object value1(&scope, SmallInt::fromWord(1));
84 Object value2(&scope, SmallInt::fromWord(2));
85 runBuiltin(METH(deque, append), self, value);
86 runBuiltin(METH(deque, append), self, value1);
87 runBuiltin(METH(deque, append), self, value2);
88 Object result(&scope, runBuiltin(METH(deque, clear), self));
89
90 EXPECT_EQ(*result, NoneType::object());
91 ASSERT_EQ(self.numItems(), 0);
92 EXPECT_EQ(self.at(0), NoneType::object());
93 EXPECT_EQ(self.at(1), NoneType::object());
94 EXPECT_EQ(self.at(2), NoneType::object());
95}
96
97TEST_F(UnderCollectionsModuleTest, DequePopRemovesItemFromRight) {
98 HandleScope scope(thread_);
99 Deque deque(&scope, runtime_->newDeque());
100 for (int i = 0; i < 3; i++) {
101 Object value(&scope, SmallInt::fromWord(i));
102 runBuiltin(METH(deque, append), deque, value);
103 }
104 ASSERT_EQ(deque.numItems(), 3);
105
106 // Pop from the end
107 RawObject result = runBuiltin(METH(deque, pop), deque);
108 ASSERT_EQ(deque.numItems(), 2);
109 EXPECT_TRUE(isIntEqualsWord(deque.at(1), 1));
110 EXPECT_TRUE(isIntEqualsWord(result, 2));
111}
112
113TEST_F(UnderCollectionsModuleTest, DequePopLeftRemovesItemFromLeft) {
114 HandleScope scope(thread_);
115 Deque deque(&scope, runtime_->newDeque());
116 for (int i = 0; i < 3; i++) {
117 Object value(&scope, SmallInt::fromWord(i));
118 runBuiltin(METH(deque, append), deque, value);
119 }
120 ASSERT_EQ(deque.numItems(), 3);
121
122 // Pop from the front
123 RawObject result = runBuiltin(METH(deque, popleft), deque);
124 ASSERT_EQ(deque.numItems(), 2);
125 EXPECT_TRUE(isIntEqualsWord(deque.at(2), 2));
126 EXPECT_TRUE(isIntEqualsWord(result, 0));
127}
128
129TEST_F(UnderCollectionsModuleTest, DequePopLeftAtEndRemovesItemFromLefts) {
130 HandleScope scope(thread_);
131 Deque deque(&scope, runtime_->newDeque());
132 Object value(&scope, SmallInt::fromWord(0));
133 runBuiltin(METH(deque, appendleft), deque, value);
134 ASSERT_EQ(deque.numItems(), 1);
135
136 // Pop from the front
137 RawObject result = runBuiltin(METH(deque, popleft), deque);
138 ASSERT_EQ(deque.numItems(), 0);
139 EXPECT_EQ(deque.left(), 0);
140 EXPECT_EQ(deque.capacity(), 16);
141 EXPECT_TRUE(isIntEqualsWord(result, 0));
142}
143
144TEST_F(UnderCollectionsModuleTest, EmptyDequeInvariants) {
145 HandleScope scope(thread_);
146 Deque deque(&scope, runtime_->newDeque());
147 EXPECT_EQ(deque.left(), 0);
148 EXPECT_EQ(deque.numItems(), 0);
149 EXPECT_EQ(deque.capacity(), 0);
150 EXPECT_EQ(deque.items(), SmallInt::fromWord(0));
151}
152
153} // namespace testing
154
155} // namespace py