1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // Unittests for iteration primitives.
16 :
17 : #include "syzygy/block_graph/transforms/iterative_transform.h"
18 :
19 : #include "base/bind.h"
20 : #include "gmock/gmock.h"
21 : #include "gtest/gtest.h"
22 : #include "syzygy/block_graph/unittest_util.h"
23 :
24 : namespace block_graph {
25 : namespace transforms {
26 :
27 : namespace {
28 :
29 : using testing::_;
30 : using testing::Invoke;
31 : using testing::Return;
32 : using testing::StrictMock;
33 :
34 : class IterativeTransformTest : public testing::Test {
35 : public:
36 E : IterativeTransformTest() : header_block_(NULL) { }
37 :
38 E : virtual void SetUp() {
39 E : header_block_ = block_graph_.AddBlock(BlockGraph::DATA_BLOCK, 10, "Header");
40 : BlockGraph::Block* block =
41 E : block_graph_.AddBlock(BlockGraph::DATA_BLOCK, 10, "Data");
42 E : ASSERT_TRUE(block != NULL);
43 E : }
44 :
45 : protected:
46 : testing::DummyTransformPolicy policy_;
47 : BlockGraph block_graph_;
48 : BlockGraph::Block* header_block_;
49 : };
50 :
51 : class MockIterativeTransform
52 : : public IterativeTransformImpl<MockIterativeTransform> {
53 : public:
54 : MOCK_METHOD3(PreBlockGraphIteration,
55 : bool(const TransformPolicyInterface*,
56 : BlockGraph*,
57 E : BlockGraph::Block*));
58 : MOCK_METHOD3(OnBlock,
59 : bool(const TransformPolicyInterface*,
60 : BlockGraph*,
61 E : BlockGraph::Block*));
62 : MOCK_METHOD3(PostBlockGraphIteration,
63 : bool(const TransformPolicyInterface*,
64 : BlockGraph*,
65 E : BlockGraph::Block*));
66 :
67 : bool DeleteBlock(const TransformPolicyInterface* policy,
68 : BlockGraph* block_graph,
69 E : BlockGraph::Block* block) {
70 E : return block_graph->RemoveBlock(block);
71 E : }
72 :
73 : bool AddBlock(const TransformPolicyInterface* policy,
74 : BlockGraph* block_graph,
75 E : BlockGraph::Block* block) {
76 : BlockGraph::Block* new_block =
77 E : block_graph->AddBlock(BlockGraph::DATA_BLOCK, 10, "Added");
78 E : return new_block != NULL;
79 E : }
80 :
81 : static const char kTransformName[];
82 : };
83 :
84 : const char MockIterativeTransform::kTransformName[] =
85 : "MockIterativeTransform";
86 :
87 : } // namespace
88 :
89 E : TEST_F(IterativeTransformTest, PreBlockGraphIterationFails) {
90 E : StrictMock<MockIterativeTransform> transform;
91 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _, _)).Times(1).
92 E : WillOnce(Return(false));
93 E : EXPECT_CALL(transform, OnBlock(_, _, _)).Times(0);
94 E : EXPECT_CALL(transform, PostBlockGraphIteration(_, _, _)).Times(0);
95 : EXPECT_FALSE(transform.TransformBlockGraph(
96 E : &policy_, &block_graph_, header_block_));
97 E : EXPECT_EQ(2u, block_graph_.blocks().size());
98 E : }
99 :
100 E : TEST_F(IterativeTransformTest, OnBlockFails) {
101 E : StrictMock<MockIterativeTransform> transform;
102 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _, _)).Times(1).
103 E : WillOnce(Return(true));
104 E : EXPECT_CALL(transform, OnBlock(_, _, _)).Times(1).WillOnce(Return(false));
105 E : EXPECT_CALL(transform, PostBlockGraphIteration(_, _, _)).Times(0);
106 : EXPECT_FALSE(transform.TransformBlockGraph(
107 E : &policy_, &block_graph_, header_block_));
108 E : EXPECT_EQ(2u, block_graph_.blocks().size());
109 E : }
110 :
111 E : TEST_F(IterativeTransformTest, PostBlockGraphIterationFails) {
112 E : StrictMock<MockIterativeTransform> transform;
113 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _, _)).Times(1).
114 E : WillOnce(Return(true));
115 : EXPECT_CALL(transform, OnBlock(_, _, _)).Times(2).
116 E : WillRepeatedly(Return(true));
117 : EXPECT_CALL(transform, PostBlockGraphIteration(_, _, _)).Times(1).
118 E : WillOnce(Return(false));
119 : EXPECT_FALSE(transform.TransformBlockGraph(
120 E : &policy_, &block_graph_, header_block_));
121 E : EXPECT_EQ(2u, block_graph_.blocks().size());
122 E : }
123 :
124 E : TEST_F(IterativeTransformTest, Normal) {
125 E : StrictMock<MockIterativeTransform> transform;
126 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _, _)).Times(1).
127 E : WillOnce(Return(true));
128 : EXPECT_CALL(transform, OnBlock(_, _, _)).Times(2).
129 E : WillRepeatedly(Return(true));
130 : EXPECT_CALL(transform, PostBlockGraphIteration(_, _, _)).Times(1).
131 E : WillOnce(Return(true));
132 : EXPECT_TRUE(transform.TransformBlockGraph(
133 E : &policy_, &block_graph_, header_block_));
134 E : EXPECT_EQ(2u, block_graph_.blocks().size());
135 E : }
136 :
137 E : TEST_F(IterativeTransformTest, Add) {
138 E : StrictMock<MockIterativeTransform> transform;
139 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _, _)).Times(1).
140 E : WillOnce(Return(true));
141 : EXPECT_CALL(transform, PostBlockGraphIteration(_, _, _)).Times(1).
142 E : WillOnce(Return(true));
143 :
144 : EXPECT_CALL(transform, OnBlock(_, _, _)).Times(2).WillOnce(Return(true)).
145 E : WillOnce(Invoke(&transform, &MockIterativeTransform::AddBlock));
146 :
147 : EXPECT_TRUE(transform.TransformBlockGraph(
148 E : &policy_, &block_graph_, header_block_));
149 E : EXPECT_EQ(3u, block_graph_.blocks().size());
150 E : }
151 :
152 E : TEST_F(IterativeTransformTest, Delete) {
153 E : StrictMock<MockIterativeTransform> transform;
154 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _, _)).Times(1).
155 E : WillOnce(Return(true));
156 : EXPECT_CALL(transform, PostBlockGraphIteration(_, _, _)).Times(1).
157 E : WillOnce(Return(true));
158 :
159 : EXPECT_CALL(transform, OnBlock(_, _, _)).Times(2).WillOnce(Return(true)).
160 E : WillOnce(Invoke(&transform, &MockIterativeTransform::DeleteBlock));
161 :
162 : EXPECT_TRUE(transform.TransformBlockGraph(
163 E : &policy_, &block_graph_, header_block_));
164 E : EXPECT_EQ(1u, block_graph_.blocks().size());
165 E : }
166 :
167 E : TEST_F(IterativeTransformTest, AddAndDelete) {
168 E : StrictMock<MockIterativeTransform> transform;
169 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _, _)).Times(1).
170 E : WillOnce(Return(true));
171 : EXPECT_CALL(transform, PostBlockGraphIteration(_, _, _)).Times(1).
172 E : WillOnce(Return(true));
173 :
174 : EXPECT_CALL(transform, OnBlock(_, _, _)).Times(2).
175 : WillOnce(Invoke(&transform, &MockIterativeTransform::AddBlock)).
176 E : WillOnce(Invoke(&transform, &MockIterativeTransform::DeleteBlock));
177 :
178 : EXPECT_TRUE(transform.TransformBlockGraph(
179 E : &policy_, &block_graph_, header_block_));
180 E : EXPECT_EQ(2u, block_graph_.blocks().size());
181 E : }
182 :
183 : } // namespace transforms
184 : } // namespace block_graph
|