nothing explains programming problems than code, so I decided to submit my assignment as code.
all the code below is written in typescript (a super set of javascript)
the language of choice has considerable implications on TDD. for example in javascript, there is no difference between float and integer types, they both considered as number.
first lets, define our function:
according to Triangle Inequality Theorem: that the sum of two sides of a triangle must be greater than the third side, this theorem is implemented in isTriangle function below.
after that, we need to choose the longest side (hypotenuse, if exists) of the triangle (findHypotenuse function).
if we don’t have a hypotenuse, then all sides are equal and it is an equilateral triangle.
if we have a hypotenuse, we proceed to check the other 2 sides of the triangle. (findOther2Sides function).
if the 2 sides of the triangle are equal then it is an IsoSceles triangle, otherwise it is a Scalene triangle.
functionisTriangle(a:number,b:number,c:number){// Triangle Inequality Theoremreturna+b>c&&a+c>b&&b+c>a;}functionisThreeNumbersEqual(a:number,b:number,c:number){returna===b&&b===c&&a===c;}functionisTwoOfThreeNumbersEqual(a:number,b:number,c:number){returna===b||a===c||b===c;}functionfindHypotenuse(a:number,b:number,c:number){if(isThreeNumbersEqual(a,b,c))returnundefined;if(a>b&&a>c)return"a";if(b>a&&b>c)return"b";if(c>a&&c>b)return"c";returnundefined;}functionfindOther2Sides(hypotenuse:string,a:number,b:number,c:number){if(hypotenuse==="a")return[b,c];if(hypotenuse==="b")return[a,c];if(hypotenuse==="c")return[a,b];return[];}functionmyreTriangle(a:number,b:number,c:number){if(!isTriangle(a,b,c))return"Not a triangle";consthypotenuse=findHypotenuse(a,b,c);if(!hypotenuse&&isThreeNumbersEqual(a,b,c))return"Equilateral";if(hypotenuse){const[side1,side2]=findOther2Sides(hypotenuse,a,b,c);if(side1===side2)return"Isosceles";if(side1!==side2)return"Scalene";}if(isTwoOfThreeNumbersEqual(a,b,c))return"Isosceles";return"Unknown triangle type";}myreTriangle(1,2,2);
now we think we did a great job with the above implantation, lets proceed with unit tests.
test case 1:
input: 1,2,2.
expected output: ‘Isosceles’
actual output: ‘Isosceles’
result: PASS
test case 2:
input: 7,2,2
expected output: ‘Not a triangle’
actual output: ‘Not a triangle’
result: PASS
test case 3:
input: 1,2,0
expected output: ‘Not a triangle’
actual output: ‘Not a triangle’
result: PASS.
test case 4:
input: 1,2,‘2’
expected output: ‘Isosceles’
actual output: ‘Unknown triangle type’
Result: FAIL, maybe the string should be converted to a number.
test case 5:
input: ‘2’, ‘2’, ‘2’
expected output: according to the previous case, we do not convert strings, so we expect this to be ‘Unknown triangle type’ or ‘Not a triangle’
actual output: ‘Equilateral’
result: FAIL. function output should be consistent, if it does not convert strings to numbers, it should fails whenever a string is passed as an argument. but we found a different result here.
test case 6:
input: 3,3,3
expected output: ‘Equilateral’
actual output: ‘Equilateral’
result: PASS.
test case 7:
input 0,0,0
expected output: error, eg. ‘Unknown triangle type’ or ‘Not a triangle’
we thought that we did a great job in the first place.
with test we find out some issues.
if this was submitted without unit tests, it will generate a runtime hard-to-find bugs, but using TTD, it is easier to detect those kind of bugs at an early stages of the product.