一,需求
迭代1
1,实现一个长度(Length)计算系统
用户既可以使用Mile为单位来记录一个长度,也可以用Yard为单位来记录
2,用户可以对比两个用不同单位表示的长度的相等关系
1 Mile = 1760 Yard
迭代2
1,加入一个新的单位:Feet
1 Yard = 3Feet
2,可以对比任意单位所表示的长度之间的相等关系
1 Yard = 3 Feet
1 Mile = 5280 Feet
迭代3
1,再加入一个新的单位:Inch
1 Feet = 12 Inch
2,能够对比任意单位表示的长度之间的相等关系
1 Feet = 12 Inch
1 Yard = 36 Inch
1 Mile = 63360 Inch
迭代4
1,增加一个容量(Volume)计算系统
包含三个计量单位TSP(茶匙)、TBSP(汤匙)、OZ(盎司)
1 TBSP = 3 TSP
1 OZ = 2 TBSP
迭代5
1、 增加对于长度和容量的加法
12 Inch + 2 Feet = 3 Feet
2 TBSP + 1 OZ = 12 TSP
迭代6
1、 为了调试的需要,现需要将一个长度或者容量输出到屏幕,格式如下(以长度为例):
长度对象的最小精度为1 Inch
单位按照从大到小的顺序,如果一个长度在某个单位上为非0值,则应该给出其数值和单位
Length(35, INCH) -> 2 FEET 11 INCH
Length(38, INCH) -> 1 YARD 2 INCH
Length(48, INCH) -> 1 YARD 1 FEET
Length(5, FEET) -> 1 YARD 2 FEET
Length(1781, YARD) -> 1 MILE 21 YARD
迭代7
1、 增加一种新的打印方式(以长度为例)
长度对象的最小精度为1 Inch
所有的长度对象都以Inch为单位进行打印
Length(2, INCH) -> 2 INCH
Length(2, FEET) -> 24 INCH
Length(3, YARD) -> 108 INCH
Length(2, MILE) -> 126720 INCH
二,实现
头文件
#ifndef HELLO_WORLD_H__
#define HELLO_WORLD_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned char VOS_UINT8;
typedef unsigned short VOS_UINT16;
typedef unsigned int VOS_UINT32;
typedef signed char VOS_INT8;
typedef signed short VOS_INT16;
typedef signed int VOS_INT32;
typedef void VOS_VOID;
#define VOS_NULL 0
#define VOS_NULL_PTR 0L
#define VOS_NULL_BYTE 0xFF
#define VOS_NULL_WORD 0xFFFF
#define VOS_NULL_DWORD 0xFFFFFFFF
#define VOS_NULL_LONG VOS_NULL_DWORD
#define ARF_SUCCESS 0
#define ARF_FAIL (-1)
typedef enum Length {
MILE,
YARD,
FEET,
INCH,
LENGTH_BUF
} Length;
typedef enum Volume {
TSP = LENGTH_BUF+1,
TBSP,
OZ
} Volume;
typedef enum Type {
LENGTH,
VOLUME
} Type;
typedef struct Node {
int value;
int type;
} Node;
#define M 100
typedef struct NodeList {
Node node[M];
int num;
} NodeList;
typedef enum COM {
SMALLER,
EQUAL,
BIGGER
} COM;
void init();
int input(int value, int type);
Node getLengthNode(int id);
Node getVolumeNode(int id);
int compare(Node n1, Node n2);
Node added(Node a, Node b);
void displayWithMax(Node a);
void displayWithMin(Node a);
#ifdef __cplusplus
}
#endif
#endif /* _HELLO_WORLD_H_ */
源代码
#include "unitest.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
NodeList lengthList, volumeList;
void init()
{
lengthList.num = 0;
volumeList.num = 0;
}
static int getDimenType(int type)
{
if (type < LENGTH_BUF) {
return LENGTH;
} else {
return VOLUME;
}
}
static NodeList *getList(int dimenType)
{
if (dimenType == LENGTH) {
return &lengthList;
} else if (dimenType == VOLUME) {
return &volumeList;
}
return NULL;
}
// 输入并返回存储的id
int input(int value, int type)
{
NodeList *pnode = getList(getDimenType(type));
if (!pnode || pnode->num >= M) {
return -1;
}
pnode->node[pnode->num].value = value, pnode->node[pnode->num].type = type;
pnode->num++;
return pnode->num - 1;
}
static Node getNode(int dimenType, int id)
{
Node defau = { 0, 0 };
NodeList *pnode = getList(dimenType);
if (!pnode) {
return defau;
}
if (id < 0 || id >= pnode->num) {
return defau;
}
return pnode->node[id];
}
Node getLengthNode(int id)
{
return getNode(LENGTH, id);
}
Node getVolumeNode(int id)
{
return getNode(VOLUME, id);
}
int g_type[] = {INCH, FEET, YARD, MILE, LENGTH_BUF,TSP, TBSP, OZ};
int g_dimen[] = {1, 12, 36, 63360, 1, 1, 3, 6};
static int getDimension(int type)
{
int size = sizeof(g_type) / sizeof(g_type[0]);
for(int i = size-1; i>=0; i--){
if(type == g_type[i]){
return g_dimen[i];
}
}
return 0;
}
static int getValue(Node node)
{
return node.value * getDimension(node.type);
}
int compare(Node n1, Node n2)
{
if (getValue(n1) > getValue(n2)) {
return BIGGER;
} else if (getValue(n1) < getValue(n2)) {
return SMALLER;
} else {
return EQUAL;
}
}
static int getBaseType(Node a)
{
if (getDimenType(a.type) == LENGTH) {
return INCH;
}
if (getDimenType(a.type) == VOLUME) {
return TSP;
}
return -1;
}
Node added(Node a, Node b)
{
int sumValue = getValue(a) + getValue(b);
int type = getBaseType(a);
Node ans = { sumValue, type };
return ans;
}
static int getMaxId(int type)
{
if(getDimenType(type)==LENGTH){
return 3;
}
if(getDimenType(type)==VOLUME){
return 7;
}
}
static int getMinId(int type)
{
if(getDimenType(type)==LENGTH){
return 0;
}
if(getDimenType(type)==VOLUME){
return 5;
}
}
#define dispalyIfEqual(type,x) if(type==x){printf("%s",#x);return;}
static void displayType(int type)
{
dispalyIfEqual(type,INCH);
dispalyIfEqual(type,FEET);
dispalyIfEqual(type,YARD);
dispalyIfEqual(type,MILE);
dispalyIfEqual(type,TSP);
dispalyIfEqual(type,TBSP);
dispalyIfEqual(type,OZ);
}
void displayFromId(Node a, int id)
{
int value = getValue(a);
int maxId = id;
for(int i = maxId; i>=0; i--){
if(value >= g_dimen[i]){
printf("%d",value/g_dimen[i]);
displayType(g_type[i]);
printf(" ");
value%=g_dimen[i];
}
}
printf("\n");
}
void displayWithMax(Node a)
{
displayFromId(a, getMaxId(a.type));
}
void displayWithMin(Node a)
{
displayFromId(a, getMinId(a.type));
}
三,测试用例
#include "gtest/gtest.h"
#include "mockcpp/include/mockcpp/mokc.h"
#include "unitest.h"
/* 这个文件是个验证工程集成 mockcpp 与 gtest 的测试工程示例文件,请根据自己的需求增加测试用例文件 */
class MockCppTest : public ::testing::Test {
protected:
void SetUp()
{
init();
}
void TearDown() {}
};
#ifdef __cplusplus
extern "C" {
#endif
int helloworld()
{
printf("hello world !\n");
return 0;
}
int MockCppFuncTest(int a, int b)
{
return a + b;
}
#ifdef __cplusplus
}
#endif
// 不依赖于测试套的单个函数的测试用例,可以用 TEST
TEST(ArfTest, should_return_helloworld) {}
// 基于带测试套初始化的测试用例,可以用 TEST_F
TEST_F(MockCppTest, should_mockcpp_work)
{
// 函数打桩,可以用这个接口
MOCKER(MockCppFuncTest).stubs().will(returnValue(100));
int ret = MockCppFuncTest(1, 2);
}
// ----------------开始迭代1----------------
TEST_F(MockCppTest, input_one_node)
{
printf("begin test --------------------- input_one_node \n");
int ret = input(1, MILE);
ASSERT_EQ(0, ret);
printf("success\n");
}
TEST_F(MockCppTest, input_and_compare_bigger)
{
printf("begin test --------------------- input_and_compare_bigger \n");
int ret1 = input(1, MILE);
ASSERT_EQ(0, ret1);
int ret2 = input(1759, YARD);
ASSERT_EQ(1, ret2);
Node n1 = getLengthNode(ret1);
Node n2 = getLengthNode(ret2);
int ret3 = compare(n1, n2);
ASSERT_EQ(BIGGER, ret3);
printf("success\n");
}
TEST_F(MockCppTest, input_and_compare_smaller)
{
printf("begin test --------------------- input_and_compare_smaller \n");
int ret1 = input(1, MILE);
ASSERT_EQ(0, ret1);
int ret2 = input(1761, YARD);
ASSERT_EQ(1, ret2);
Node n1 = getLengthNode(ret1);
Node n2 = getLengthNode(ret2);
int ret3 = compare(n1, n2);
ASSERT_EQ(SMALLER, ret3);
printf("success\n");
}
TEST_F(MockCppTest, input_and_compare_equal)
{
printf("begin test --------------------- input_and_compare_equal \n");
int ret1 = input(1, MILE);
ASSERT_EQ(0, ret1);
int ret2 = input(1760, YARD);
ASSERT_EQ(1, ret2);
Node n1 = getLengthNode(ret1);
Node n2 = getLengthNode(ret2);
int ret3 = compare(n1, n2);
ASSERT_EQ(EQUAL, ret3);
printf("success\n");
}
// ----------------开始迭代2----------------
TEST_F(MockCppTest, input_and_compare_bigger2)
{
printf("begin test --------------------- input_and_compare_bigger2 \n");
int ret1 = input(1, MILE);
ASSERT_EQ(0, ret1);
int ret2 = input(5279, FEET);
ASSERT_EQ(1, ret2);
Node n1 = getLengthNode(ret1);
Node n2 = getLengthNode(ret2);
int ret3 = compare(n1, n2);
ASSERT_EQ(BIGGER, ret3);
printf("success\n");
}
TEST_F(MockCppTest, input_and_compare_smaller2)
{
printf("begin test --------------------- input_and_compare_smaller2 \n");
int ret1 = input(1, MILE);
ASSERT_EQ(0, ret1);
int ret2 = input(5281, FEET);
ASSERT_EQ(1, ret2);
Node n1 = getLengthNode(ret1);
Node n2 = getLengthNode(ret2);
int ret3 = compare(n1, n2);
ASSERT_EQ(SMALLER, ret3);
printf("success\n");
}
TEST_F(MockCppTest, input_and_compare_equal2)
{
printf("begin test --------------------- input_and_compare_equal2 \n");
int ret1 = input(1, MILE);
ASSERT_EQ(0, ret1);
int ret2 = input(5280, FEET);
ASSERT_EQ(1, ret2);
Node n1 = getLengthNode(ret1);
Node n2 = getLengthNode(ret2);
int ret3 = compare(n1, n2);
ASSERT_EQ(EQUAL, ret3);
printf("success\n");
}
// ----------------开始迭代3----------------
TEST_F(MockCppTest, input_and_compare_bigger3)
{
printf("begin test --------------------- input_and_compare_bigger3 \n");
int ret1 = input(1, MILE);
ASSERT_EQ(0, ret1);
int ret2 = input(63359, INCH);
ASSERT_EQ(1, ret2);
Node n1 = getLengthNode(ret1);
Node n2 = getLengthNode(ret2);
int ret3 = compare(n1, n2);
ASSERT_EQ(BIGGER, ret3);
printf("success\n");
}
TEST_F(MockCppTest, input_and_compare_smaller3)
{
printf("begin test --------------------- input_and_compare_smaller3 \n");
int ret1 = input(1, MILE);
ASSERT_EQ(0, ret1);
int ret2 = input(63361, INCH);
ASSERT_EQ(1, ret2);
Node n1 = getLengthNode(ret1);
Node n2 = getLengthNode(ret2);
int ret3 = compare(n1, n2);
ASSERT_EQ(SMALLER, ret3);
printf("success\n");
}
TEST_F(MockCppTest, input_and_compare_equal3)
{
printf("begin test --------------------- input_and_compare_equal3 \n");
int ret1 = input(1, MILE);
ASSERT_EQ(0, ret1);
int ret2 = input(63360, INCH);
ASSERT_EQ(1, ret2);
Node n1 = getLengthNode(ret1);
Node n2 = getLengthNode(ret2);
int ret3 = compare(n1, n2);
ASSERT_EQ(EQUAL, ret3);
printf("success\n");
}
// ----------------开始迭代4----------------
TEST_F(MockCppTest, input_and_compare_bigger4)
{
printf("begin test --------------------- input_and_compare_bigger4 \n");
int ret1 = input(1, TBSP);
ASSERT_EQ(0, ret1);
int ret2 = input(2, TSP);
ASSERT_EQ(1, ret2);
Node n1 = getVolumeNode(ret1);
Node n2 = getVolumeNode(ret2);
int ret3 = compare(n1, n2);
ASSERT_EQ(BIGGER, ret3);
printf("success\n");
}
TEST_F(MockCppTest, input_and_compare_smaller4)
{
printf("begin test --------------------- input_and_compare_smaller4 \n");
int ret1 = input(1, TBSP);
ASSERT_EQ(0, ret1);
int ret2 = input(4, TSP);
ASSERT_EQ(1, ret2);
Node n1 = getVolumeNode(ret1);
Node n2 = getVolumeNode(ret2);
int ret3 = compare(n1, n2);
ASSERT_EQ(SMALLER, ret3);
printf("success\n");
}
TEST_F(MockCppTest, input_and_compare_equal4)
{
printf("begin test --------------------- input_and_compare_equal4 \n");
int ret1 = input(1, TBSP);
ASSERT_EQ(0, ret1);
int ret2 = input(3, TSP);
ASSERT_EQ(1, ret2);
Node n1 = getVolumeNode(ret1);
Node n2 = getVolumeNode(ret2);
int ret3 = compare(n1, n2);
ASSERT_EQ(EQUAL, ret3);
printf("success\n");
}
// ----------------开始迭代5----------------
TEST_F(MockCppTest, length_added)
{
printf("begin test --------------------- length_added \n");
int ret1 = input(12, INCH);
ASSERT_EQ(0, ret1);
int ret2 = input(2, FEET);
ASSERT_EQ(1, ret2);
Node n1 = getLengthNode(ret1);
Node n2 = getLengthNode(ret2);
Node sumNode = added(n1, n2);
Node rightAns = { 3, FEET };
int ret3 = compare(sumNode, rightAns);
ASSERT_EQ(EQUAL, ret3);
printf("success\n");
}
TEST_F(MockCppTest, volume_added)
{
printf("begin test --------------------- volume_added \n");
int ret1 = input(2, TBSP);
ASSERT_EQ(0, ret1);
int ret2 = input(1, OZ);
ASSERT_EQ(1, ret2);
Node n1 = getVolumeNode(ret1);
Node n2 = getVolumeNode(ret2);
Node sumNode = added(n1, n2);
Node rightAns = { 12, TSP };
int ret3 = compare(sumNode, rightAns);
ASSERT_EQ(EQUAL, ret3);
printf("success\n");
}
// ----------------开始迭代6----------------
TEST_F(MockCppTest, displaylength1)
{
printf("begin test --------------------- displaylength1 \n");
int ret = input(35, INCH);
ASSERT_EQ(0, ret);
Node n = getLengthNode(ret);
displayWithMax(n); // 2FEET 11INCH
printf("success\n");
}
// ----------------开始迭代7----------------
TEST_F(MockCppTest, displaylength2)
{
printf("begin test --------------------- displaylength2 \n");
int ret = input(35, INCH);
ASSERT_EQ(0, ret);
Node n = getLengthNode(ret);
displayWithMin(n); // 35INCH
printf("success\n");
}