1//===- InputTreeTest.cpp --------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include "InputTreeTest.h"
10
11#include <vector>
12#include <iostream>
13
14#include <mcld/InputTree.h>
15#include <mcld/MC/InputFactory.h>
16#include <mcld/LinkerConfig.h>
17#include <mcld/MC/InputBuilder.h>
18#include <mcld/MC/FileAction.h>
19#include <mcld/MC/CommandAction.h>
20
21using namespace mcld;
22using namespace mcld::test;
23
24
25// Constructor can do set-up work for all test here.
26InputTreeTest::InputTreeTest()
27  : m_MemFactory(10), m_ContextFactory(4) {
28
29  // create testee. modify it if need
30  m_pConfig = new mcld::LinkerConfig("arm-none-linux-gnueabi");
31  m_pAlloc  = new mcld::InputFactory(10, *m_pConfig);
32  m_pBuilder = new mcld::InputBuilder(*m_pConfig,
33                                      *m_pAlloc,
34                                      m_ContextFactory,
35                                      m_MemFactory,
36                                      false);
37  m_pTestee = new mcld::InputTree();
38  m_pBuilder->setCurrentTree(*m_pTestee);
39}
40
41// Destructor can do clean-up work that doesn't throw exceptions here.
42InputTreeTest::~InputTreeTest()
43{
44  delete m_pTestee;
45  delete m_pAlloc;
46  delete m_pBuilder;
47  delete m_pConfig;
48}
49
50// SetUp() will be called immediately before each test.
51void InputTreeTest::SetUp()
52{
53}
54
55// TearDown() will be called immediately after each test.
56void InputTreeTest::TearDown()
57{
58}
59
60//===----------------------------------------------------------------------===//
61// Testcases
62//
63TEST_F( InputTreeTest, Basic_operation ) {
64
65  std::vector<InputAction*> actions;
66
67  size_t position = 0;
68  actions.push_back(new StartGroupAction(position++));
69  actions.push_back(new InputFileAction(position++, "path1"));
70  actions.push_back(new EndGroupAction(position++));
71
72  std::vector<InputAction*>::iterator action;
73  for (action = actions.begin(); action != actions.end(); ++action) {
74    (*action)->activate(*m_pBuilder);
75    delete *action;
76  }
77
78  InputTree::iterator node = m_pTestee->root();
79  InputTree::const_iterator const_node = node;
80  --node;
81  --const_node;
82
83  ASSERT_TRUE(isGroup(node));
84  ASSERT_TRUE(isGroup(const_node));
85  ASSERT_FALSE(m_pAlloc->empty());
86  ASSERT_TRUE(1 == m_pAlloc->size());
87
88  --node;
89
90  m_pTestee->enterGroup(node, InputTree::Downward);
91
92  InputTree::const_iterator const_node2 = node;
93
94  ASSERT_FALSE(node.isRoot());
95
96  ASSERT_FALSE(isGroup(node));
97  ASSERT_FALSE(isGroup(const_node2));
98  ASSERT_FALSE(m_pAlloc->empty());
99  ASSERT_FALSE(m_pAlloc->size()==0);
100
101  ASSERT_TRUE(m_pTestee->size()==3);
102}
103
104TEST_F( InputTreeTest, forLoop_TEST ) {
105  InputTree::iterator node = m_pTestee->root();
106
107
108  Input* input = m_pAlloc->produce("FileSpec", "path1");
109  m_pTestee->insert<InputTree::Inclusive>(node, *input);
110  InputTree::const_iterator const_node = node;
111  --node;
112
113  for(int i=0 ; i<100 ; ++i)
114  {
115    Input* input = m_pAlloc->produce("FileSpec", "path1");
116    m_pTestee->insert<InputTree::Inclusive>(node, *input);
117    ++node;
118  }
119
120  m_pTestee->enterGroup(node, InputTree::Downward);
121  --node;
122
123  ASSERT_FALSE(node.isRoot());
124  ASSERT_TRUE(isGroup(node));
125  ASSERT_FALSE(m_pAlloc->empty());
126  ASSERT_FALSE(m_pAlloc->size()==100);
127
128  ASSERT_TRUE(m_pTestee->size()==102);
129}
130
131TEST_F( InputTreeTest, Nesting_Case ) {
132  InputTree::iterator node = m_pTestee->root();
133
134  for(int i=0 ; i<50 ; ++i)
135  {
136    m_pTestee->enterGroup(node, InputTree::Downward);
137    --node;
138
139    Input* input = m_pAlloc->produce("FileSpec", "path1");
140    m_pTestee->insert(node, InputTree::Afterward, *input);
141    ++node;
142  }
143
144  ASSERT_FALSE(node.isRoot());
145  ASSERT_FALSE(isGroup(node));
146  ASSERT_FALSE(m_pAlloc->empty());
147  ASSERT_TRUE(m_pAlloc->size()==50);
148  ASSERT_TRUE(m_pTestee->size()==100);
149}
150
151TEST_F( InputTreeTest, DFSIterator_BasicTraversal)
152{
153
154  InputTree::iterator node = m_pTestee->root();
155  Input* input = m_pAlloc->produce("111", "/");
156  m_pTestee->insert<InputTree::Inclusive>(node, *input);
157  node.move<InputTree::Inclusive>();
158
159  input = m_pAlloc->produce("10", "/");
160  m_pTestee->insert<InputTree::Positional>(node, *input);
161  m_pTestee->enterGroup<InputTree::Inclusive>(node);
162  node.move<InputTree::Inclusive>();
163
164  input = m_pAlloc->produce("7", "/");
165  m_pTestee->insert<InputTree::Inclusive>(node, *input);
166  input = m_pAlloc->produce("8", "/");
167  m_pTestee->insert<InputTree::Positional>(node, *input);
168
169  InputTree::dfs_iterator dfs_it = m_pTestee->dfs_begin();
170  InputTree::dfs_iterator dfs_end = m_pTestee->dfs_end();
171  ASSERT_STREQ("111", (*dfs_it)->name().c_str());
172  ++dfs_it;
173  ASSERT_STREQ("7", (**dfs_it).name().c_str());
174  ++dfs_it;
175  ASSERT_STREQ("8", (**dfs_it).name().c_str());
176  ++dfs_it;
177  ASSERT_STREQ("10", (**dfs_it).name().c_str());
178  ++dfs_it;
179  ASSERT_TRUE(dfs_it ==  dfs_end);
180}
181
182