Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented features found in issues #6 #18

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from

Conversation

Janacek
Copy link

@Janacek Janacek commented May 21, 2018

I've added both the Get and GetNeighbours methods from the class Area, with the unit tests.
The GetNeighbours method actually returns up to 8 neighbours (top-left, top, top-right, left, right, bottom-left, bottom, bottom-right)
I've assumed that since the Area position uses IPosition2D, the same goes for the Tiles added to that area.

@nullorvoid
Copy link
Contributor

Hi @Janacek I got asked to take a look at this PR. Firstly thanks for picking this.

I have a few small issues, the first is Spaces vs Tabs. If you could correctly format your PR in the same style as the original repository that would be great. The others I will point out in comments.

Assert.Fail();
}
Area area = new Area();
var mockLevel = new Mock<ILevel>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? I don't think to perform this test you need to use the SetPosition(level, pos) on the area. This is used when we have multiple areas, and do not think it should affect any methods that are looking inside the area directly such as get neighbours.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, this is not useful for this test, and neither for PositionGetNeighbours test.

}
}
Area area = new Area();
var mockLevel = new Mock<ILevel>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above

Assert.IsTrue(area.GetNeighbours(mockTile.Object).Count == 2);
mockNotANeighbourTile.Object.SetPosition(area, notANeighbourTilePosition);
area.Add(mockNotANeighbourTile.Object);
Assert.IsTrue(area.GetNeighbours(mockTile.Object).Count == 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think this is an adequate test? For instance is someone is making this change and it happens that the new change actually returns two wrong tiles rather than the two tiles you are expecting.

I'd like to hear your opinions on this because Unit Tests are quite a hot potato topic in the company, it's nice to hear other peoples views on how verbose Unit Tests should be.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test would be irrelevant if someone were to change the test, or if the GetNeighbours method would change to return only the direct neighbours (left, top, right, bottom).

One way to fix this would be to check if the tiles we know are neighbours to the tested tile are present in the list returned by the method.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One way to fix this would be to check if the tiles we know are neighbours to the tested tile are present in the list returned by the method.

This is exactly what I was getting at. Do you believe this is better or worse in this case?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the method may change, I believe the actual test is not reliable and should be rewriten.

throw new ArgumentException("Tile not in Area", "tile");
}

List<ITile> neigbourTiles = tiles.FindAll(t =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find it more readable for the delegate passed in to functions like this to be separately declared as an action, however this is quite short. What is your opinion on this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the function would need to return a boolean, an action is not possible (Maybe I'm misunderstood on this point).

I came up with this solution : (the indentation is broken here)

Func<ITile, Predicate<ITile>> ArePositionsNeighbours = lhs => (rhs => Math.Abs(((Position2D)lhs.Position).X - ((Position2D)rhs.Position).X) == 1 || Math.Abs(((Position2D)lhs.Position).Y - ((Position2D)rhs.Position).Y) == 1);

Which can be used like this :

List<ITile> neigbourTiles = tiles.FindAll(ArePositionsNeighbours(tile));

This method uses a Predicate, which is what List.FindAll needs, and allows the code to be separated. However, the code may be even less readable using this solution. On the other hand, using this, we gain re-usability, which in my opinion is really important.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, in this case knowing it's not going to be reused it's safe to leave it as is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants