U E D R , A S I H C RSS

Von Neumann Airport/1002

νŽ˜μ΄μ§€λΌ μž‘μ„±ν•˜λ©΄μ„œ μž‘μ„±ν•΄ λ‚˜κ°‘λ‹ˆλ‹€. TDD μ—°μŠ΅μ€‘μ΄λ‹ˆ μ•„λ§ˆ 쀑간 μ‚½μ§ˆλ„ μ˜ˆμƒλœλ‹€λŠ”. ^^;

(5μ‹œ μ¦ˆμŒλΆ€ν„° μ‹œμž‘ν•¨)

μ–Έμ–΄λŠ” C++ 둜 ν•  것이고 쀑간에 STL 쀑 vector λΌ κ°„λ‹¨ν•˜κ²Œ μ΄μš©ν• κ²λ‹ˆλ‹€. (μžμ„Έν•œ μ΄μš©λ²•μ€ λ‚˜λ„ λͺ¨λ₯΄λŠ” κ΄€κ³„λ‘œ -_-;) 일단 μ €λŠ” 이 λ¬Έμ œλΌ ν•œλ²ˆ ν’€μ–΄λ³Έ 적이 μžˆμŠ΅λ‹ˆλ‹€. μ—°μŠ΅μ‚Όμ•„μ„œ μƒˆλ‘œ ν’€μ–΄λ΄…λ‹ˆλ‹€.

λ¬Έμ œλŠ” μ•”νŠΌ μ΄ν•΄ν–ˆκ³  (Input 에 λŒ€ν•œ Output 이 λ¨Έλ¦Ώμ†μ—μ„œ μ–΄λ–»κ²Œ ν•΄μ•Ό 할지 연결이 된 μƒνƒœ) κ°€μž₯ κ°„λ‹¨ν•˜κ²Œ ν…ŒμŠ€νŠΈν•  수 μžˆλŠ” 방법에 λŒ€ν•΄ 생각해야 ν•˜κ² κ΅°μš”.

Sample Input 을 λ³΄λ‹ˆ λ’€μ˜ 것이 간단해 λ³΄μ΄λŠ”κ΅°μš”.
~cpp 
2
1 1 2 100
2 1 1 200
1
1 2
1 2
2
1 2 
2 1
0
0
μ΄λΌ Target으둜 μž‘μœΌλ €λ‹ˆ, 더 컀보이고, μ΄λΌ μž‘μ€ Test 둜 λ‚˜λˆ λ΄…λ‹ˆλ‹€.
~cpp 
1
1 1 1 1
1
1 
1

μ—¬κΈ°μ„œ μž μ‹œ CppUnit μ…‹νŒ…μ„ λ§žμΆ°λ†“κ³ .
~cpp 
#include <cppunit/TestCase.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/Ui/Text/TestRunner.h>

class TestOne : public CppUnit::TestCase {
public:
	CPPUNIT_TEST_SUITE (TestOne);
	CPPUNIT_TEST_SUITE_END();
};

int main ()
{
	CppUnit::TextUi::TestRunner runner;

	runner.run("", false);

	return 0;
}

λ‹€μ‹œ ꢁ리λͺ¨λ“œ λŒμž….
~cpp 
1
1 1 1 1
1
1 
1
μ—μ„œ ν…ŒμŠ€νŠΈ μ½”λ“œμ—μ„  인풋 νŒŒμ‹±μ€ 일단 λΈλ¦¬ 생각할 ν•„μš”κ°€ μ—†μœΌλ‹ˆ.
~cpp 
configuration 1,1 둜 μ…‹νŒ…
1->1 둜 1λͺ… κ°€κΈ°
이럴 λ•Œ, traffic 을 κ΅¬ν•˜λ©΄ 1λͺ…이 λ‚˜μ˜¨λ‹€.

ν—‰. 30λΆ„λ™μ•ˆ ν”„λ¦°νŠΈ ν•˜μ‹ λ‹€κ³  μžλ¦¬ν•„μš”ν•˜μ‹  λΆ„ λ•Œλ¬Έμ— 지연. -_-; λ‹€μ‹œ μ‹œμž‘;

~cpp 
class TestOne : public CppUnit::TestCase {
public:
	CPPUNIT_TEST_SUITE (TestOne);
	CPPUNIT_TEST (test1);
	CPPUNIT_TEST_SUITE_END();

	void test1 () {
		Configuration* conf = new Configuration (1,1);
		conf->movePeople (1,1,1);
		CPPUNIT_ASSERT_EQUAL (1, conf->getTraffic ());
	}
};
이에 λŒ€ν•œ μ½”λ“œ μž‘μ„±
~cpp 
class Configuration {
	int startCity;
	int endCity;
public:
	Configuration (int startCity, int endCity) {
		this->startCity = startCity;
		this->endCity = endCity;
	}

	void movePeople (int startCity, int endCity, int people) {
		
	}

	int getTraffic () {
		return 1;
	}
};
~cpp 
	void test1 () {
		Configuration* conf = new Configuration (1,1);
		conf->movePeople(1,1,1);
		CPPUNIT_ASSERT_EQUAL (1, conf->getTraffic ());
		conf->movePeople(1,1,1);
		CPPUNIT_ASSERT_EQUAL (2, conf->getTraffic ());
	}
~cpp 
	void movePeople (int startCity, int endCity, int people) {
		traffic += people;		
	}

	int getTraffic () {
		return traffic;		
	}
~cpp 
		conf->movePeople(1,1,100);
		CPPUNIT_ASSERT_EQUAL (102, conf->getTraffic ());
μ—¬κΈ°κΉŒμ§„ 톡과..~ test code λΌ Refactoring ν•΄λ΄…λ‹ˆλ‹€.
~cpp 
	void testOneToOneMove () {
		int dataset [3][3] = {{1,1,1}, {1,1,1}, {1,1,100}};
		int expectedSet[3] = {1,2,102};

		Configuration* conf = new Configuration (1,1);

		for (int i=0;i<3;i++) {
			conf->movePeople(dataset[i][0],dataset[i][1],dataset[i][2]);
			CPPUNIT_ASSERT_EQUAL (expectedSet[i], conf->getTraffic ());
		}
		delete conf;
	}
ν†΅κ³Όν•œ ν…ŒμŠ€νŠΈ
~cpp 
configuration 1,1 둜 μ…‹νŒ…
1->1 둜 1λͺ… κ°€κΈ° : traffic 1.
1->1 둜 1λͺ… 더 κ°€κΈ° : traffic 2.
1->1 둜 100λͺ… 더 κ°€κΈ° : traffic 102.
λ‹€μŒ ν…ŒμŠ€νŠΈμ˜ 생각
~cpp 
configuration {1,2},{1,2} 둜 μ…‹νŒ…
1->2 둜 1λͺ… κ°€κΈ° : traffic 2.
~cpp 
	void testOneToTwoMove () {
		int arrivalCitys[] = {1,2};
		int departureCitys[] = {1,2};

		Configuration* conf = new Configuration (arrivalCitys, departureCitys);
		
		conf->movePeople(1,2,1);
		CPPUNIT_ASSERT_EQUAL(2, conf->getTraffic());

		delete conf;
	}
μ—λŸ¬κ°€ λ‚œλ‹€. C++ μ—μ„œλŠ” ν„°ν”Œμ΄ μ—†μœΌλ€λ‘œ.. -_- 배열을 λ„˜κΈ°λŠ” 방법이 있고, vector λΌ μ΄μš©ν•˜λŠ” 방법이 μžˆμŠ΅λ‹ˆλ‹€. μ €λ²ˆμ—λŠ” λ°°μ—΄λ‘œ ν–ˆκΈ° λ•Œλ¬Έμ— μ΄λ²ˆμ—” vector 둜 ν•΄λ³Έλ‹€λŠ”. ^^;
~cpp 
	void testOneToTwoMove () {
		vector <int> arrivalCitys;
		vector <int> departureCitys;
	
		arrivalCitys.push_back(1);
		arrivalCitys.push_back(2);
		departureCitys.push_back(1);
		departureCitys.push_back(2);

		Configuration* conf = new Configuration (arrivalCitys, departureCitys);
		
		conf->movePeople(1,2,1);
		CPPUNIT_ASSERT_EQUAL(2, conf->getTraffic());

		delete conf;
	}
컴파일 μ—λŸ¬.
~cpp 
--------------------Configuration: AirportSec - Win32 Debug--------------------
Compiling...
main.cpp
C:\User\reset\AirportSec\main.cpp(57) : error C2664: '__thiscall Configuration::Configuration(int,int)' : cannot convert parameter 1 from 'class std::vector<int,class std::allocator<int> >' to 'int'
        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
Error executing cl.exe.

AirportSec.exe - 1 error(s), 0 warning(s)
μ—­μ‹œ, 메인 μ½”λ“œλ„ μˆ˜μ • ν•„μš”λΌ μ•Œλ €μ€λ‹€.
~cpp 
	Configuration (vector<int> startCity, vector<int> endCity) {
		this->startCity = startCity;
		this->endCity = endCity;
		this->traffic = 0;
	}

	void movePeople (int startCity, int endCity, int people) {
		traffic += people;		
	}

	int getTraffic () {
		return traffic;		
	}
이 경우 testOneToOneMove κ°€ κΉ¨μ§€κ²Œ λœλ‹€. λ°μ΄ν„°ν˜•μ΄ λ‹€λ₯΄κΈ° λ•Œλ¬Έμ΄λ‹€. testOneToOneMove μͺ½ ν…ŒμŠ€νŠΈ ν˜•μ„ λ˜‘κ°™μ΄ μž‘μ„±ν•΄μ€λ‹€.
~cpp 
	void testOneToOneMove () {
		int dataset [3][3] = {{1,1,1}, {1,1,1}, {1,1,100}};
		int expectedSet[3] = {1,2,102};

		vector<int> arrivalCitys;
		vector<int> depatureCitys;

		arrivalCitys.push_back(1);
		depatureCitys.push_back(1);

		Configuration* conf = new Configuration (arrivalCitys,depatureCitys);
κ²°κ³Ό :

~cpp 
1) test: TestOne::testOneToTwoMove (F) line: 66 C:\User\reset\AirportSec\main.c
p
equality assertion failed
- Expected: 2
- Actual  : 1


Press any key to continue
λ’€μ˜ ν…ŒμŠ€νŠΈκ°€ 깨진닀.

movePeople 의 μž¬μ •μ˜.
~cpp 
	void movePeople (int startCity, int endCity, int people) {
		traffic += getDistance () * people;		
	}
6:46 λ°₯먹으러 감;

7:50 λ‹€μ‹œ μ‹œμž‘ μ˜ˆμ •. ^^;

getDistance ()의 경우 두 city gate κ°„μ˜ 거리이닀. 일단 μŠ€ν… μ½”λ“œλΌ μž‘μ„±ν•΄λ‘κ³ ,
~cpp 
	int getDistance () {
		return 0;
	}
λ‹€μŒκ³Ό 같이 ν…ŒμŠ€νŠΈλΌ λ‹€μ‹œ μž‘μ„±ν•  수 μžˆλ‹€.
~cpp 
	void testGetDistance () {
		vector <int> arrivalCitys;
		vector <int> departureCitys;
	
		arrivalCitys.push_back(1);
		departureCitys.push_back(1);

		Configuration* conf = new Configuration (arrivalCitys, departureCitys);
		CPPUNIT_ASSERT_EQUAL(1, conf->getDistance(1,1));
	}
~cpp 
-------------------Configuration: AirportSec - Win32 Debug--------------------
Compiling...
main.cpp
C:\User\reset\AirportSec\main.cpp(84) : error C2660: 'getDistance' : function does not take 2 parameters
Error executing cl.exe.

AirportSec.exe - 1 error(s), 0 warning(s)
μ»΄νŒŒμΌλŸ¬κ°€ 인자 2개짜리 Interface μ΄κΈ°λΌ μš”μ²­ν•œλ‹€. μš”μ²­λŒ€λ‘œ ν•΄μ£Όμž.
~cpp 
	int getDistance (int startCity, int endCity) {
		return 0;
	}

그에 따라 λ‹€μŒκ³Ό 같은 μ—λŸ¬κ°€ λ‚œλ‹€.
~cpp 
--------------------Configuration: AirportSec - Win32 Debug--------------------
Compiling...
main.cpp
C:\User\reset\AirportSec\main.cpp(24) : error C2660: 'getDistance' : function does not take 0 parameters
Error executing cl.exe.

AirportSec.exe - 1 error(s), 0 warning(s)
24 라인은 movePeople.
~cpp 
	void movePeople (int startCity, int endCity, int people) {
		traffic += getDistance () * people;		
	}
이 μΈν„°νŽ˜μ΄μŠ€λ„ μˆ˜μ •ν•˜κΈΈ μ»΄νŒŒμΌλŸ¬κ°€ 바라고 μžˆλ‹€. μ›ν•˜λŠ”λŒ€λ‘œ ν•΄μ£Όμž.
~cpp 
	void movePeople (int startCity, int endCity, int people) {
		traffic += getDistance (startCity, endCity) * people;		
	}
~cpp 
1) test: TestOne::testOneToOneMove (F) line: 54 C:\User\reset\AirportSec\main.cpp equality assertion failed
- Expected: 1
- Actual  : 0


2) test: TestOne::testOneToTwoMove (F) line: 71 C:\User\reset\AirportSec\main.cpp equality assertion failed
- Expected: 2
- Actual  : 0


3) test: TestOne::testGetDistance (F) line: 84 C:\User\reset\AirportSec\main.cpp equality assertion failed
- Expected: 1
- Actual  : 0
기쑴의 ν…ŒμŠ€νŠΈλ“€μ΄ μ „λΆ€ κΉ¨μ‘Œλ‹€. 기쑴의 ν…ŒμŠ€νŠΈλŠ” getTraffic 와 κ΄€λ ¨ν•œ 뢀뢄이고, μš°λ¦¬κ°€ μˆ˜μ •ν•œ 뢀뢄은 getDistance 이닀. getDistance 에 촛점을 λ§žμΆ”μž.
~cpp 
	int getDistance (int startCity, int endCity) {
		return 0;
	}
일단은 λ‹€μŒκ³Ό 같이. 촛점을 λ§žμΆ°μ•Ό ν•  뢀뢄은 testGetDistance.
~cpp 
	int getDistance (int startCity, int endCity) {
		return 1;
	}
~cpp 
	void testGetDistance2() {
		vector <int> arrivalCitys;
		vector <int> departureCitys;
	
		arrivalCitys.push_back(1);
		arrivalCitys.push_back(2);
		departureCitys.push_back(1);
		departureCitys.push_back(2);

		Configuration* conf = new Configuration (arrivalCitys, departureCitys);
		CPPUNIT_ASSERT_EQUAL(2, conf->getDistance(1,2));
		delete conf;
	}
getDistance 에 λŒ€ν•΄ refinement ν•΄μ£Όμž.
~cpp 
	int getDistance (int startCity, int endCity) {
		return abs (getStartGateIndex(startCity) - getEndGateIndex(endCity)) + 1;
	}

	int getStartGateIndex (int startCity) {
		for (int cityIndex=0; cityIndex < this->startCity.size(); cityIndex++) {
			if (this->startCity[cityIndex] == startCity) {
				return cityIndex;
			}
		}
		return -1;
	}

	int getEndGateIndex (int endCity) {
		for (int cityIndex=0; cityIndex < this->endCity.size(); cityIndex++) {
			if (this->endCity[cityIndex] == endCity) {
				return cityIndex;
			}
		}
		return -1;
	}
μ—¬κΈ°μ„œ Test - Code 의 μ‹œκ°„μ΄ κ½€ κΈΈμ—ˆλ‹€. (9λΆ„) ν•¨μˆ˜ refinement λΆ€λΆ„μ—μ„œ STL 에 μžˆλŠ” find ν•¨μˆ˜λΌ ν•¨ 써먹어 보렀고 ν–ˆλ‹€κ°€;; 결ꡭ은 ν‰μ†Œ ν•˜λ˜λ°λ‘œ ν–ˆλ‹€. ^^;

Refactoring - 쀑볡없애기.
~cpp 
	int find (vector<int>& cities, int city) {
		for (int cityIndex=0; cityIndex < cities.size(); cityIndex++) {
			if (cities[cityIndex] == city) {
				return cityIndex;
			}
		}
		return -1;
	}
μ—¬κΈ°μ„œ μ§€κΈˆκΉŒμ§€ μƒκ°ν•œ test 듀을 μ „λΆ€ pass ν–ˆλ‹€. μ•žμœΌλ‘œ 더 ν•΄μ•Ό ν•  일이 μƒκ°λ‚˜μ§€ μ•Šμ•„μ„œ, ν•œλ²ˆ μ‹€μ œ λ©”μΈν…ŒμŠ€νŠΈμ— μ€ν•˜λŠ” ν…ŒμŠ€νŠΈλΌ ν•΄ λ³΄μ•˜λ‹€. 즉,
~cpp 
2 
1 1 2 100 
2 1 1 200
1 
1 2 
1 2 
0 
0 
에 λŒ€ν•΄μ„œ traffic 이 600 이 λ‚˜μ˜€λŠ” 것을 ν™•μΈν•˜λŠ” ν…ŒμŠ€νŠΈ.
~cpp 
	void testRealOne () {
		vector<int> arrivalCitys;
		vector<int> departureCitys;

		arrivalCitys.push_back(1);
		arrivalCitys.push_back(2);
		departureCitys.push_back(1);
		departureCitys.push_back(2);

		Configuration* conf = new Configuration (arrivalCitys, departureCitys);
		conf->movePeople(1,2, 100);
		conf->movePeople(2,1, 200);
		CPPUNIT_ASSERT_EQUAL(600, conf->getTraffic());
		delete conf;
	}
κ²°κ³Ό : ok. Configuration은 μ‹€μ§ˆμ μΈ λ°μ΄ν„°κΉŒμ§€λ„ νŠΈλ ˆν”½μ„ 계산할 수 μžˆλŠ” 수μ€κΉŒμ§€ λ˜μ—ˆλ‹€. ν…ŒμŠ€νŠΈλΌ μ€ λ” λΆ™μ—¬λ³΄μž. μ€ λ” μ–΄λ €μš΄ 경우인 μ•žλ‹¨κ³„μ˜ 데이터에 λŒ€ν•΄ ν•΄λ³΄μž.
~cpp 
1 2 2 10 3 15
2 1 3 10
3 2 1 12 2 20
1
1 2 3
2 3 1
0
0
μΌλ•Œ traffic 122 κ°€ λ‚˜μ™€μ•Ό ν•œλ‹€.
~cpp 
	void testRealTwo () {
		vector<int> arrivalCitys;
		vector<int> departureCitys;

		arrivalCitys.push_back(1);
		arrivalCitys.push_back(2);
		arrivalCitys.push_back(3);
		departureCitys.push_back(2);
		departureCitys.push_back(3);
		departureCitys.push_back(1);

		Configuration* conf = new Configuration (arrivalCitys, departureCitys);
		conf->movePeople(1,2,10);
		conf->movePeople(1,3,15);
		conf->movePeople(2,3,10);
		conf->movePeople(3,1,12);
		conf->movePeople(3,2,20);

		CPPUNIT_ASSERT_EQUAL(122, conf->getTraffic());
		delete conf;
	}
pass λ˜μ—ˆλ‹€. μ•„λ¬΄λž˜λ„ ν•œλ²ˆ λΈλ¦¬ 짜본 ν”„λ‘œκ·Έλž¨μ΄μ—¬μ„œ κ·ΈλŸ°μ§€ μ΄ˆλ°˜μ— μΌλ°˜ν™”λœ 것이 μ•„λ‹κΉŒ ν•˜λŠ” 생각이 λ“ λ‹€.

Refactoring ν•˜κΈ° μ „ ν˜„μž¬ μ†ŒμŠ€.
~cpp 
#include <cppunit/TestCase.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/Ui/Text/TestRunner.h>

#include <vector>
#include <algorithm>

using namespace std;

class Configuration {
	vector<int> startCity;
	vector<int> endCity;
	int traffic;
public:
	Configuration (vector<int> startCity, vector<int> endCity) {
		this->startCity = startCity;
		this->endCity = endCity;
		this->traffic = 0;
	}

	int find (vector<int>& cities, int city) {
		for (int cityIndex=0; cityIndex < cities.size(); cityIndex++) {
			if (cities[cityIndex] == city) {
				return cityIndex;
			}
		}
		return -1;
	}

	int getStartGateIndex (int startCity) {
		return find (this->startCity, startCity);
	}

	int getEndGateIndex (int endCity) {
		return find (this->endCity, endCity);
	}


	int getDistance (int startCity, int endCity) {
		return abs (getStartGateIndex(startCity) - getEndGateIndex(endCity)) + 1;
	}

	void movePeople (int startCity, int endCity, int people) {
		this->traffic += getDistance (startCity, endCity) * people;		
	}

	int getTraffic () {
		return this->traffic;		
	}
};

class TestOne : public CppUnit::TestCase {
public:
	CPPUNIT_TEST_SUITE (TestOne);
	CPPUNIT_TEST (testOneToOneMove);
	CPPUNIT_TEST (testOneToTwoMove);
	CPPUNIT_TEST (testGetDistance);
	CPPUNIT_TEST (testGetDistance2);
	CPPUNIT_TEST (testRealOne);
	CPPUNIT_TEST (testRealTwo);

	CPPUNIT_TEST_SUITE_END();

	void testOneToOneMove () {
		int dataset [3][3] = {{1,1,1}, {1,1,1}, {1,1,100}};
		int expectedSet[3] = {1,2,102};

		vector<int> arrivalCitys;
		vector<int> depatureCitys;

		arrivalCitys.push_back(1);
		depatureCitys.push_back(1);

		Configuration* conf = new Configuration (arrivalCitys,depatureCitys);

		for (int i=0;i<3;i++) {
			conf->movePeople(dataset[i][0],dataset[i][1],dataset[i][2]);
			CPPUNIT_ASSERT_EQUAL (expectedSet[i], conf->getTraffic ());
		}
		delete conf;
	}

	void testOneToTwoMove () {
		vector <int> arrivalCitys;
		vector <int> departureCitys;
	
		arrivalCitys.push_back(1);
		arrivalCitys.push_back(2);
		departureCitys.push_back(1);
		departureCitys.push_back(2);

		Configuration* conf = new Configuration (arrivalCitys, departureCitys);
		
		conf->movePeople(1,2,1);
		CPPUNIT_ASSERT_EQUAL(2, conf->getTraffic());

		delete conf;
	}

	void testGetDistance () {
		vector <int> arrivalCitys;
		vector <int> departureCitys;
	
		arrivalCitys.push_back(1);
		departureCitys.push_back(1);

		Configuration* conf = new Configuration (arrivalCitys, departureCitys);
		CPPUNIT_ASSERT_EQUAL(1, conf->getDistance(1,1));
		delete conf;
	}
	void testGetDistance2() {
		vector <int> arrivalCitys;
		vector <int> departureCitys;
	
		arrivalCitys.push_back(1);
		arrivalCitys.push_back(2);
		departureCitys.push_back(1);
		departureCitys.push_back(2);

		Configuration* conf = new Configuration (arrivalCitys, departureCitys);
		CPPUNIT_ASSERT_EQUAL(2, conf->getDistance(1,2));
		delete conf;
	}
	void testRealOne () {
		vector<int> arrivalCitys;
		vector<int> departureCitys;

		arrivalCitys.push_back(1);
		arrivalCitys.push_back(2);
		departureCitys.push_back(1);
		departureCitys.push_back(2);

		Configuration* conf = new Configuration (arrivalCitys, departureCitys);
		conf->movePeople(1,2, 100);
		conf->movePeople(2,1, 200);
		CPPUNIT_ASSERT_EQUAL(600, conf->getTraffic());
		delete conf;
	}
	void testRealTwo () {
		vector<int> arrivalCitys;
		vector<int> departureCitys;

		arrivalCitys.push_back(1);
		arrivalCitys.push_back(2);
		arrivalCitys.push_back(3);
		departureCitys.push_back(2);
		departureCitys.push_back(3);
		departureCitys.push_back(1);

		Configuration* conf = new Configuration (arrivalCitys, departureCitys);
		conf->movePeople(1,2,10);
		conf->movePeople(1,3,15);
		conf->movePeople(2,3,10);
		conf->movePeople(3,1,12);
		conf->movePeople(3,2,20);

		CPPUNIT_ASSERT_EQUAL(122, conf->getTraffic());
		delete conf;
	}
};


int main ()
{
	CppUnit::TextUi::TestRunner runner;

	runner.addTest (TestOne::suite());
	runner.run("", false);

	return 0;
}

ν…ŒμŠ€νŠΈ μ½”λ”© Refactoring - 으.. μ—¬μ „νžˆ μ‹œκ°„μ΄ 많이 κ±Έλ¦°λ‹€. 주둜 쀑볡을 μ—†μ• λŠ” λ°©ν–₯으둜 μ ‘κ·Ό.
~cpp 
#ifndef _CONFIGURATION_H_
#define _CONFIGURATION_H_

#include <vector>
using namespace std;

class Configuration {
	vector<int> startCity;
	vector<int> endCity;
	int traffic;
public:
	Configuration (vector<int> startCity, vector<int> endCity) {
		this->startCity = startCity;
		this->endCity = endCity;
		this->traffic = 0;
	}

	int find (vector<int>& cities, int city) {
		for (int cityIndex=0; cityIndex < cities.size(); cityIndex++) {
			if (cities[cityIndex] == city) {
				return cityIndex;
			}
		}
		return -1;
	}

	int getStartGateIndex (int startCity) {
		return find (this->startCity, startCity);
	}

	int getEndGateIndex (int endCity) {
		return find (this->endCity, endCity);
	}


	int getDistance (int startCity, int endCity) {
		return abs (getStartGateIndex(startCity) - getEndGateIndex(endCity)) + 1;
	}

	void movePeople (int startCity, int endCity, int people) {
		this->traffic += getDistance (startCity, endCity) * people;		
	}

	int getTraffic () {
		return this->traffic;		
	}
};

#endif
history λΌ λ³΄λ‹ˆ 30뢄정도 κ±Έλ Έκ΅°μš”. 흠..

κ·ΈλŸ¬λ‹€κ°€ λ³΄λ‹ˆ, ν…ŒμŠ€νŠΈ μ½”λ“œμ—μ„œ 자주 쀑볡이 λ‚˜νƒ€λ‚˜λŠ” 뢀뢄이 λˆˆμ— 띀닀.
~cpp 
		int arrivalData[] = {1,2};
		int departureData[] = {1,2};
		conf = new Configuration (arrivalCitys, departureCitys);
μ‹μœΌλ‘œ μ„μ •λ˜λŠ” Configuration λΆ€λΆ„.

setUp λΆ€λΆ„ λ¬Άμ–΄μ„œ Configuration 에 λŒ€ν•œ ν…ŒμŠ€νŠΈλΌ λ‘κ°œλ‘œ 묢기둜 ν–ˆλ‹€.
~cpp 
#ifndef _TEST_CONFIGURATION_H_
#define _TEST_CONFIGURATION_H_

#include <cppunit/TestCase.h>
#include <cppunit/extensions/HelperMacros.h>
#include <vector>
using namespace std;

void intVectorInit (vector<int>& vec, int* intList, int count) {
	for (int i=0;i<count;i++) {
		vec.push_back(intList[i]);
	}
}

void movePeople (Configuration* conf, int moveDataSet[][3], int moveCount) {
	for (int i=0;i<moveCount;i++) {
		conf->movePeople(moveDataSet[i][0], moveDataSet[i][1], moveDataSet[i][2]);
	}
}

class TestConfigurationBasic : public CppUnit::TestCase {
	CPPUNIT_TEST_SUITE (TestConfigurationBasic);
	CPPUNIT_TEST (testOneToOneMove);
	CPPUNIT_TEST (testGetDistance);
	CPPUNIT_TEST_SUITE_END();

public:
	Configuration* conf;
	vector<int> arrivalCitys;
	vector<int> departureCitys;

	void setUp () {
		conf = NULL;

	}
	void tearDown () {
		if (conf) delete conf;
		arrivalCitys.clear();
		departureCitys.clear();
	}

	void testOneToOneMove () {
		int moveDataSet [3][3] = {{1,1,1}, {1,1,1}, {1,1,100}};
		int expectedSet[3] = {1,2,102};
		
		arrivalCitys.push_back(1);
		departureCitys.push_back(1);
		
		conf = new Configuration (arrivalCitys,departureCitys);
		
		for (int i=0;i<3;i++) {
			conf->movePeople(moveDataSet[i][0],moveDataSet[i][1],moveDataSet[i][2]);
			CPPUNIT_ASSERT_EQUAL (expectedSet[i], conf->getTraffic ());
		}
	}

	void testGetDistance () {
		vector <int> arrivalCitys;
		vector <int> departureCitys;
		
		arrivalCitys.push_back(1);
		departureCitys.push_back(1);
		
		conf = new Configuration (arrivalCitys, departureCitys);
		CPPUNIT_ASSERT_EQUAL(1, conf->getDistance(1,1));
	}

};

class TestConfigurationCityTwo : public CppUnit::TestCase {
	CPPUNIT_TEST_SUITE (TestConfigurationCityTwo);
	CPPUNIT_TEST (testOneToTwoMove);
	CPPUNIT_TEST (testGetDistance2);
	CPPUNIT_TEST (testRealOne);
	
	CPPUNIT_TEST_SUITE_END();
	
public:
	Configuration* conf;
	vector<int> arrivalCitys;
	vector<int> departureCitys;
	
	void setUp () {
		conf = NULL;
		int arrivalData[] = {1,2};
		int departureData[] = {1,2};
		intVectorInit (arrivalCitys, arrivalData, 2);
		intVectorInit (departureCitys, departureData, 2);

	}
	
	void tearDown() {
		if (conf) delete conf;
		arrivalCitys.clear();
		departureCitys.clear();
	}
	
	void testOneToTwoMove () {
		conf = new Configuration (arrivalCitys, departureCitys);
		conf->movePeople(1,2,1);
		
		CPPUNIT_ASSERT_EQUAL(2, conf->getTraffic());
	}
	
	void testGetDistance2() {
		conf = new Configuration (arrivalCitys, departureCitys);
		CPPUNIT_ASSERT_EQUAL(2, conf->getDistance(1,2));
	}

	void testRealOne () {
		int moveDataSet[2][3] = {{1,2,100}, {2,1,200}};
		
		conf = new Configuration (arrivalCitys, departureCitys);
		movePeople (conf, moveDataSet, 2);
		CPPUNIT_ASSERT_EQUAL(600, conf->getTraffic());
	}
};

class TestConfigurationCityThree : public CppUnit::TestCase {
	CPPUNIT_TEST_SUITE(TestConfigurationCityThree);
	CPPUNIT_TEST (testRealTwo);
	CPPUNIT_TEST_SUITE_END();
	
public:
	Configuration* conf;
	vector<int> arrivalCitys;
	vector<int> departureCitys;

	void setUp () {
		conf = NULL;

	}
	void tearDown () {
		if (conf) delete conf;
		arrivalCitys.clear();
		departureCitys.clear();
	}
	
	void testRealTwo () {
		int arrivalData[] = {1,2,3};
		int departureData[] = {2,3,1};
		int moveDataSet[5][3] = {{1,2,10}, {1,3,15}, {2,3,10}, {3,1,12}, {3,2,20}};
		
		intVectorInit (arrivalCitys, arrivalData, 3);
		intVectorInit (departureCitys, departureData, 3);
		
		conf = new Configuration (arrivalCitys, departureCitys);
		movePeople (conf, moveDataSet, 5);
		
		CPPUNIT_ASSERT_EQUAL(122, conf->getTraffic());
	}
};

#endif
근데, Refactoring 에 λŒ€ν•΄μ„œλ§Œ 1μ‹œκ°„μ„ μ“΄ 것 κ°™λ‹€. 그것도 메인 μ½”λ“œμΈ Configuration 클래슀 보단, Test μ½”λ“œμ— λŒ€ν•œ Refactoring 이 μ£Όκ°€ 된 것 κ°™λ‹€. μ‹€μ§ˆμ μΈ μ‹€μš©μ„±μ„ λ³Όλ•Œ, 메인 μ½”λ“œμ— λŒ€ν•œ Refactoring μœ„μ£Όλ‘œ λ‚˜κ°€λŠ” 것이 쒋을 것 κ°™λ‹€. (깨진 Test λŠ” 주둜 μ‚­μ œν•˜λŠ” μŠ€νƒ€μΌλ‘œ κ°€κ³ ..)

Configuration ν•˜λ‚˜μ— λŒ€ν•΄μ„œλŠ” 된 것 κ°™κ³ . 또 ν…ŒμŠ€νŠΈ λ“€μ–΄κ°ˆ 것이 μ—†μ„κΉŒ... μƒκ°ν•˜λ˜μ€‘, μ΄μ œλŠ” μ—¬λŸ¬κ°œμ˜ 데이터가 λ“€μ–΄κ°€μ•Όκ² λ‹€λŠ” 생각을 ν•˜κ²Œ λ˜μ—ˆλ‹€. 즉, Configuration 이 2개인 κ²½μš°μ— λŒ€ν•΄μ„œ.
Configuration 이 2개인 κ²½μš°μ— λŒ€ν•΄μ„œ. 이 Configuration 을 가지고 μžˆλŠ” 것을 Airport 라고 상정짓도둝 ν•˜κ² λ‹€. Airport λŠ” Configuration 을 등둝할 수 있으며, 각각의 Configuration κ²½μš°μ— λŒ€ν•œ Traffic 듀을 각 Configuration μ—κ²Œ λ¬Όμ–΄λ΄„μœΌλ‘œμ„œ κ³„μ‚°λœ Traffic 듀을 μ•Œ 수 μžˆλ‹€.

κ°„λ‹¨ν•œ λ‘λ²ˆμ§Έμ˜ 경우 μ˜ˆλΌ λ¨Όμ € λ“ λ‹€λ©΄.
~cpp 
1 1 2 100
2 1 1 200
1
1 2
1 2
2 
1 2
2 1
0
0
각 κ²½μš°μ— λŒ€ν•΄ 첫번째 traffic 은 600이, λ‘λ²ˆμ§Έ traffic 은 300 이 λ‚˜μ™€μ•Ό ν•œλ‹€.
~cpp 
class TestAirport : public CppUnit::TestCase {
	CPPUNIT_TEST_SUITE (TestAirport);
	CPPUNIT_TEST (testOne);
	CPPUNIT_TEST_SUITE_END();

public:
	Configuration* conf1;
	Configuration* conf2;
	vector<int> arrivalCitys;
	vector<int> departureCitys;
	vector<int> arrivalCitys2;
	vector<int> departureCitys2;

	void setUp () {
		int arrivalData[] = {1,2};
		int departureData[] = {1,2};
		intVectorInit (arrivalCitys, arrivalData, 2);
		intVectorInit (departureCitys, departureData, 2);
		conf1 = new Configuration (arrivalCitys, departureCitys);

		int arrivalData2[] = {1,2};
		int departureData2[] = {2,1};
		intVectorInit (arrivalCitys2, arrivalData, 2);
		intVectorInit (departureCitys2, departureData, 2);
		conf2 = new Configuration (arrivalCitys2, departureCitys2);
	}
	void tearDown () {
		delete conf1;
		delete conf2;
		arrivalCitys.clear();
		departureCitys.clear();
		arrivalCitys2.clear();
		departureCitys2.clear();
	}

	void testOne () {
		Airport* airport = new Airport();
		airport->registerConfiguration (conf1);
		airport->registerConfiguration (conf2);

		airport->movePeople (1,2,100);
		airport->movePeople (2,1,200);

		CPPUNIT_ASSERT_EQUAL (600, airport->getTraffic(0));
		CPPUNIT_ASSERT_EQUAL (300, airport->getTraffic(1));
	}

};

airport κ΄€λ ¨ μ½”λ“œ κ΅¬ν˜„.
~cpp 
	void movePeople (int startCity, int endCity, int people) {
		for (int i=0;i< this->configurations.size();i++) {
			this->configurations[i]->movePeople(startCity, endCity, people);
		}
	}
κ²°κ³Ό :
~cpp 
1) test: TestAirport::testOne (F) line: 72 c:\user\reset\airportsec\testairport.h equality assertion failed
- Expected: 300
- Actual  : 600
μ™œ λ‘λ²ˆμ§Έ configuration 의 κ²½μš°μ— λŒ€ν•΄μ„œ μ—λŸ¬μΌκΉŒ? λ‹€μ‹œ configuration 으둜; ν…ŒμŠ€νŠΈλΌ λ” μΆ”κ°€ν•΄ λ³΄μ•˜λ‹€.
~cpp 
	void testGetDistance2to1() {
		CPPUNIT_ASSERT_EQUAL(2, conf->getDistance(2,1));
	}
λ©€μ©‘ν•˜λ‹€. κ·Έλž˜μ„œ, Configuration 에 λŒ€ν•œ ν…ŒμŠ€νŠΈλΌ λ” μž‘μ„±ν•˜μ˜€λ‹€.
~cpp 
	void testTwoToOneMove () {
		int arrivalData[] = {1,2};
		int departureData[] = {2,1};
		intVectorInit (arrivalCitys, arrivalData, 2);
		intVectorInit (departureCitys, departureData, 2);

		conf = new Configuration (arrivalCitys, departureCitys);
		conf->movePeople(1,2,100);
		CPPUNIT_ASSERT_EQUAL(100, conf->getTraffic());
	}
~cpp  // μΆ”κ°€λœ ν…ŒμŠ€νŠΈ
		conf->movePeople(2,1,200);
		CPPUNIT_ASSERT_EQUAL(300, conf->getTraffic());
μž‘λ™μ„ 잘 ν•œλ‹€; λ¬Έμ œλŠ” 이제 Airport μͺ½μœΌλ‘œ μΆ•μ†Œλ˜λŠ” λ“ ν•˜λ‹€.
~cpp  // 문제 발견! - AirportTest::setUp()
		int arrivalData2[] = {1,2};
		int departureData2[] = {2,1};
		intVectorInit (arrivalCitys2, arrivalData, 2);  // <-- arrivalData2 둜 μ΄ˆκΈ°ν™”λ˜μ–΄μ•Ό ν•œλ‹€.
		intVectorInit (departureCitys2, departureData, 2); // μ—­μ‹œ λ˜ν•œ;

~cpp 
.........


OK (9 tests)
λ‹€λ₯Έ ν…ŒμŠ€νŠΈμ— λŒ€ν•΄μ„œλ„ ν•΄λ³΄μž.
~cpp 
	void testGetTraffics2 () {
		int arrivalData[] = {1,2,3};
		int departureData[] = {2,3,1};
		intVectorInit (arrivalCitys, arrivalData, 3);
		intVectorInit (departureCitys, departureData, 3);
		conf1 = new Configuration (arrivalCitys, departureCitys);

		int arrivalData2[] = {2,3,1};
		int departureData2[] = {3,2,1};
		intVectorInit (arrivalCitys2, arrivalData2, 3);
		intVectorInit (departureCitys2, departureData2, 3);
		conf2 = new Configuration (arrivalCitys2, departureCitys2);

		Airport* airport = new Airport();
		airport->registerConfiguration (conf1);
		airport->registerConfiguration (conf2);

		airport->movePeople (1,2,10);
		airport->movePeople (1,3,15);
		airport->movePeople (2,3,10);
		airport->movePeople (3,1,12);
		airport->movePeople (3,2,20);

		CPPUNIT_ASSERT_EQUAL (122, airport->getTraffic(0));
		CPPUNIT_ASSERT_EQUAL (119, airport->getTraffic(1));

		delete airport;
	}
Sort κ²°κ³Ό ν…ŒμŠ€νŠΈ.
~cpp 
	void testSortedResult () {
		int arrivalData[] = {1,2,3};
		int departureData[] = {2,3,1};
		intVectorInit (arrivalCitys, arrivalData, 3);
		intVectorInit (departureCitys, departureData, 3);
		conf1 = new Configuration (arrivalCitys, departureCitys);

		int arrivalData2[] = {2,3,1};
		int departureData2[] = {3,2,1};
		intVectorInit (arrivalCitys2, arrivalData2, 3);
		intVectorInit (departureCitys2, departureData2, 3);
		conf2 = new Configuration (arrivalCitys2, departureCitys2);

		Airport* airport = new Airport();
		airport->registerConfiguration (conf1);
		airport->registerConfiguration (conf2);

		airport->movePeople (1,2,10);
		airport->movePeople (1,3,15);
		airport->movePeople (2,3,10);
		airport->movePeople (3,1,12);
		airport->movePeople (3,2,20);

		vector<Configuration*> configurations = airport->getSortedResult ();

		CPPUNIT_ASSERT_EQUAL (119, configurations[0]->getTraffic());
		CPPUNIT_ASSERT_EQUAL (122, configurations[1]->getTraffic());

		CPPUNIT_ASSERT_EQUAL (122, airport->getTraffic(0));
		CPPUNIT_ASSERT_EQUAL (119, airport->getTraffic(1));
		delete airport;
	}
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:28:23
Processing time 0.0365 sec