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 :
23 : namespace block_graph {
24 : namespace transforms {
25 :
26 : namespace {
27 :
28 : using testing::_;
29 : using testing::Invoke;
30 : using testing::Return;
31 : using testing::StrictMock;
32 :
33 : class IterativeTransformTest : public testing::Test {
34 : public:
35 E : IterativeTransformTest() : header_block_(NULL) { }
36 :
37 E : virtual void SetUp() {
38 E : header_block_ = block_graph_.AddBlock(BlockGraph::DATA_BLOCK, 10, "Header");
39 : BlockGraph::Block* block =
40 E : block_graph_.AddBlock(BlockGraph::DATA_BLOCK, 10, "Data");
41 E : ASSERT_TRUE(block != NULL);
42 E : }
43 :
44 : protected:
45 : BlockGraph block_graph_;
46 : BlockGraph::Block* header_block_;
47 : };
48 :
49 : class MockIterativeTransform
50 : : public IterativeTransformImpl<MockIterativeTransform> {
51 : public:
52 E : MOCK_METHOD2(PreBlockGraphIteration, bool(BlockGraph*, BlockGraph::Block*));
53 E : MOCK_METHOD2(OnBlock, bool(BlockGraph*, BlockGraph::Block*));
54 E : MOCK_METHOD2(PostBlockGraphIteration, bool(BlockGraph*, BlockGraph::Block*));
55 :
56 : bool DeleteBlock(BlockGraph* block_graph,
57 E : BlockGraph::Block* block) {
58 E : return block_graph->RemoveBlock(block);
59 E : }
60 :
61 : bool AddBlock(BlockGraph* block_graph,
62 E : BlockGraph::Block* block) {
63 : BlockGraph::Block* new_block =
64 E : block_graph->AddBlock(BlockGraph::DATA_BLOCK, 10, "Added");
65 E : return new_block != NULL;
66 E : }
67 :
68 : static const char kTransformName[];
69 : };
70 :
71 : const char MockIterativeTransform::kTransformName[] =
72 : "MockIterativeTransform";
73 :
74 : } // namespace
75 :
76 E : TEST_F(IterativeTransformTest, PreBlockGraphIterationFails) {
77 E : StrictMock<MockIterativeTransform> transform;
78 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _)).Times(1).
79 E : WillOnce(Return(false));
80 E : EXPECT_CALL(transform, OnBlock(_, _)).Times(0);
81 E : EXPECT_CALL(transform, PostBlockGraphIteration(_, _)).Times(0);
82 E : EXPECT_FALSE(transform.TransformBlockGraph(&block_graph_, header_block_));
83 E : EXPECT_EQ(2u, block_graph_.blocks().size());
84 E : }
85 :
86 E : TEST_F(IterativeTransformTest, OnBlockFails) {
87 E : StrictMock<MockIterativeTransform> transform;
88 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _)).Times(1).
89 E : WillOnce(Return(true));
90 E : EXPECT_CALL(transform, OnBlock(_, _)).Times(1).WillOnce(Return(false));
91 E : EXPECT_CALL(transform, PostBlockGraphIteration(_, _)).Times(0);
92 E : EXPECT_FALSE(transform.TransformBlockGraph(&block_graph_, header_block_));
93 E : EXPECT_EQ(2u, block_graph_.blocks().size());
94 E : }
95 :
96 E : TEST_F(IterativeTransformTest, PostBlockGraphIterationFails) {
97 E : StrictMock<MockIterativeTransform> transform;
98 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _)).Times(1).
99 E : WillOnce(Return(true));
100 E : EXPECT_CALL(transform, OnBlock(_, _)).Times(2).WillRepeatedly(Return(true));
101 : EXPECT_CALL(transform, PostBlockGraphIteration(_, _)).Times(1).
102 E : WillOnce(Return(false));
103 E : EXPECT_FALSE(transform.TransformBlockGraph(&block_graph_, header_block_));
104 E : EXPECT_EQ(2u, block_graph_.blocks().size());
105 E : }
106 :
107 E : TEST_F(IterativeTransformTest, Normal) {
108 E : StrictMock<MockIterativeTransform> transform;
109 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _)).Times(1).
110 E : WillOnce(Return(true));
111 E : EXPECT_CALL(transform, OnBlock(_, _)).Times(2).WillRepeatedly(Return(true));
112 : EXPECT_CALL(transform, PostBlockGraphIteration(_, _)).Times(1).
113 E : WillOnce(Return(true));
114 E : EXPECT_TRUE(transform.TransformBlockGraph(&block_graph_, header_block_));
115 E : EXPECT_EQ(2u, block_graph_.blocks().size());
116 E : }
117 :
118 E : TEST_F(IterativeTransformTest, Add) {
119 E : StrictMock<MockIterativeTransform> transform;
120 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _)).Times(1).
121 E : WillOnce(Return(true));
122 : EXPECT_CALL(transform, PostBlockGraphIteration(_, _)).Times(1).
123 E : WillOnce(Return(true));
124 :
125 : EXPECT_CALL(transform, OnBlock(_, _)).Times(2).WillOnce(Return(true)).
126 E : WillOnce(Invoke(&transform, &MockIterativeTransform::AddBlock));
127 :
128 E : EXPECT_TRUE(transform.TransformBlockGraph(&block_graph_, header_block_));
129 E : EXPECT_EQ(3u, block_graph_.blocks().size());
130 E : }
131 :
132 E : TEST_F(IterativeTransformTest, Delete) {
133 E : StrictMock<MockIterativeTransform> transform;
134 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _)).Times(1).
135 E : WillOnce(Return(true));
136 : EXPECT_CALL(transform, PostBlockGraphIteration(_, _)).Times(1).
137 E : WillOnce(Return(true));
138 :
139 : EXPECT_CALL(transform, OnBlock(_, _)).Times(2).WillOnce(Return(true)).
140 E : WillOnce(Invoke(&transform, &MockIterativeTransform::DeleteBlock));
141 :
142 E : EXPECT_TRUE(transform.TransformBlockGraph(&block_graph_, header_block_));
143 E : EXPECT_EQ(1u, block_graph_.blocks().size());
144 E : }
145 :
146 E : TEST_F(IterativeTransformTest, AddAndDelete) {
147 E : StrictMock<MockIterativeTransform> transform;
148 : EXPECT_CALL(transform, PreBlockGraphIteration(_, _)).Times(1).
149 E : WillOnce(Return(true));
150 : EXPECT_CALL(transform, PostBlockGraphIteration(_, _)).Times(1).
151 E : WillOnce(Return(true));
152 :
153 : EXPECT_CALL(transform, OnBlock(_, _)).Times(2).
154 : WillOnce(Invoke(&transform, &MockIterativeTransform::AddBlock)).
155 E : WillOnce(Invoke(&transform, &MockIterativeTransform::DeleteBlock));
156 :
157 E : EXPECT_TRUE(transform.TransformBlockGraph(&block_graph_, header_block_));
158 E : EXPECT_EQ(2u, block_graph_.blocks().size());
159 E : }
160 :
161 : } // namespace transforms
162 : } // namespace block_graph
|