1 /******************************************************************************
2  *
3  *  Copyright (C) 2014 Google, Inc.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 // Helper macros for stubbing out functions and modules for testing.
20 
21 // Stub out a function, with call counting and mode awareness
22 #define STUB_FUNCTION(ret, name, params) \
23   UNUSED_ATTR static int name##_callcount; \
24   static ret name params { \
25     UNUSED_ATTR int _local_callcount = name##_callcount; \
26     name##_callcount++;
27 
28 // Expect a certain number of calls to the specified stub function
29 #define EXPECT_CALL_COUNT(name, count) \
30   EXPECT_EQ((count), (name##_callcount)) << "expected " #name " to be called " #count " times"
31 
32 // Reset the call count for the specificed stub function
33 #define RESET_CALL_COUNT(name) ((name##_callcount) = 0)
34 
35 // Use this in a stub function to catch unexpected calls.
36 // Prints out a nice message including the call count, the
37 // stub function name, and the mode index (sadly no mode name)
38 #define UNEXPECTED_CALL EXPECT_TRUE(false) \
39   << "unexpected call " << _local_callcount \
40   << " to " << __func__ \
41   << " during mode " << (int)_current_mode
42 
43 #define MODE_IS(mode) (_current_mode == (mode))
44 
45 // Macro selection helpers
46 #define OVERLOAD_CAT(A, B) A##B
47 #define OVERLOAD_SELECT(NAME, NUM) OVERLOAD_CAT(NAME##_, NUM)
48 #define OVERLOAD_GET_COUNT(_1, _2, _3, _4, _5, _6, COUNT, ...) COUNT
49 #define OVERLOAD_VA_SIZE(...) OVERLOAD_GET_COUNT(__VA_ARGS__, 6, 5, 4, 3, 2, 1)
50 #define OVERLOAD_OF(NAME, ...) OVERLOAD_SELECT(NAME, OVERLOAD_VA_SIZE(__VA_ARGS__))(__VA_ARGS__)
51 
52 // Use this to branch stub function execution to a specific mode or modes.
53 // Treat it like an if statement. For example:
54 //
55 // DURING(dinner) EXPECT_EQ(bread_pudding, food);
56 // DURING(midday_snack, midnight_snack) EXPECT_EQ(chocolate, food);
57 #define DURING(...) OVERLOAD_OF(DURING, __VA_ARGS__)
58 
59 #define DURING_1(mode0) \
60   if (MODE_IS(mode0))
61 #define DURING_2(mode0, mode1) \
62   if (MODE_IS(mode0) || MODE_IS(mode1))
63 #define DURING_3(mode0, mode1, mode2) \
64   if (MODE_IS(mode0) || MODE_IS(mode1) || MODE_IS(mode2))
65 #define DURING_4(mode0, mode1, mode2, mode3) \
66   if (MODE_IS(mode0) || MODE_IS(mode1) || MODE_IS(mode2) || MODE_IS(mode3))
67 #define DURING_5(mode0, mode1, mode2, mode3, mode4) \
68   if (MODE_IS(mode0) || MODE_IS(mode1) || MODE_IS(mode2) || MODE_IS(mode3) || MODE_IS(mode4))
69 #define DURING_6(mode0, mode1, mode2, mode3, mode4, mode5) \
70   if (MODE_IS(mode0) || MODE_IS(mode1) || MODE_IS(mode2) || MODE_IS(mode3) || MODE_IS(mode4) || MODE_IS(mode5))
71 
72 // Use this to branch stub function exeuction to a specific call
73 // count index (zero based). Treat it like an if statement.
74 // Usually most helpful following a DURING clause. For example:
75 //
76 // DURING (breakfast) AT_CALL(0) EXPECT_EQ(bacon, food);
77 //
78 // or
79 //
80 // DURING (three_course_meal) {
81 //   AT_CALL(0) EXPECT_EQ(shrimp_cocktail, food);
82 //   AT_CALL(1) EXPECT_EQ(bacon_wrapped_bacon, food);
83 //   AT_CALL(1) EXPECT_EQ(chocolate_covered_fake_blueberries, food);
84 // }
85 #define AT_CALL(index) \
86   if (_local_callcount == index)
87 
88 // Declare all the available test modes for the DURING clauses
89 // For example:
90 //
91 // DECLARE_TEST_MODES(breakfast, lunch, dinner);
92 #define DECLARE_TEST_MODES(...) \
93   typedef enum { __VA_ARGS__ } _test_modes_t; \
94   static _test_modes_t _current_mode;
95 
96 // Get the current test mode
97 #define CURRENT_TEST_MODE _current_mode
98 
99 #define TEST_MODES_T _test_modes_t
100