package net.bitpot.railways.parser; import net.bitpot.railways.models.RailsEngine; import net.bitpot.railways.models.Route; import net.bitpot.railways.models.RouteList; import net.bitpot.railways.models.requestMethods.RequestMethod; import net.bitpot.railways.models.routes.RedirectRoute; import net.bitpot.railways.models.routes.SimpleRoute; import net.bitpot.railways.utils.TestUtils; import org.junit.Before; import org.junit.Test; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.List; import static org.junit.Assert.*; /** * Tests for RailsRoutesParser. */ public class RailsRoutesParserTest { RailsRoutesParser parser = null; @Before public void setUp() throws Exception { parser = new RailsRoutesParser(); } @Test public void testParse() throws Exception { RouteList routes = parser.parseFile("test/data/parserTest_1.txt"); assertNotNull(routes); assertEquals(routes.size(), 6); } @Test public void testStrErrorParsing() throws IOException { String stdErr = readFile("test/data/sample_stderr.txt"); parser.parseErrors(stdErr); String stack = parser.getErrorStacktrace(); assertTrue(stack.length() > 0); assertEquals(RailsRoutesParser.ERROR_GENERAL, parser.getErrorCode()); assertTrue(parser.isErrorReported()); assertFalse("Rake error wasn't cleaned from unnecessary text.", stack.contains("rake aborted!")); } @Test public void testStdErrorParserRemovesRakeMessages() { String s = "** Invoke routes (first_time)\n" + "** Invoke environment (first_time)"; parser.parseErrors(s); String stack = parser.getErrorStacktrace(); assertEquals(stack.length(), 0); assertFalse(parser.isErrorReported()); assertEquals(RailsRoutesParser.NO_ERRORS, parser.getErrorCode()); } @Test public void testWrongRakeTaskCall() { String s = "rake aborted!\n" + " Don't know how to build task 'xroutes'"; parser.parse("", s); assertEquals(RailsRoutesParser.ERROR_RAKE_TASK_NOT_FOUND, parser.getErrorCode()); assertTrue(parser.isErrorReported()); } @Test public void testConstraintsParsing() { String rails3routeConstraints = " GET /users/:id(.:format) users#show {:id=>/[A-Za-z]{3,}/}"; // Test constraints parsing List<Route> routeList = parser.parseLine(rails3routeConstraints); Route route = routeList.get(0); assertEquals(route.getActionTitle(), "users#show"); } @Test public void testIsInvalidRouteLine() { String rails4routeHeader = " Prefix Verb URI Pattern Controller#Action"; String rails4routeLine = "edit_user GET /users/:id/edit(.:format) users#edit"; assertTrue(parser.parseSpecialLine(rails4routeHeader)); assertFalse(parser.parseSpecialLine(rails4routeLine)); } @Test public void testParsingMultipleRouteTypesInASingleLine() { String line = " test GET|POST /test(.:format) clients#show "; List<Route> routes = parser.parseLine(line); assertEquals("Resulting routes count", 2, routes.size()); // Test first route Route expected = new SimpleRoute(null, RequestMethod.GET, "/test(.:format)", "test", "clients", "show"); Route actual = routes.get(0); TestUtils.assertRouteEquals(expected, actual); // Test second route expected = new SimpleRoute(null, RequestMethod.POST, "/test(.:format)", "test", "clients", "show"); actual = routes.get(1); TestUtils.assertRouteEquals(expected, actual); } @Test public void testParsingEngineRoutes() throws Exception { parser.parseFile("test/data/engine_routes_parsing.data.txt"); List<RailsEngine> enginesList = parser.getMountedEngines(); assertEquals(2, enginesList.size()); RailsEngine engine = enginesList.get(0); assertEquals("RailsAdmin::Engine", engine.getRubyClassName()); assertEquals("/admin", engine.getRootPath()); engine = enginesList.get(1); assertEquals("RailsSettingsUi::Engine", engine.getRubyClassName()); assertEquals("/settings", engine.getRootPath()); } @Test public void testParsingEngineRoutesOrderAndContents() throws Exception { RouteList routes = parser.parseFile("test/data/engine_routes_parsing.data.txt"); // Engine routes should follow parent engine route which mounts them Route route = routes.get(0); assertEquals("RailsAdmin::Engine", route.getActionTitle()); route = routes.get(1); assertEquals("rails_admin/main#dashboard", route.getActionTitle()); assertEquals("/admin", route.getPath()); route = routes.get(2); assertEquals("rails_admin/main#index", route.getActionTitle()); assertEquals("/admin/:model_name(.:format)", route.getPath()); route = routes.get(3); assertEquals("RailsSettingsUi::Engine", route.getActionTitle()); route = routes.get(4); assertEquals("rails_settings_ui/settings#index", route.getActionTitle()); assertEquals("/settings", route.getPath()); route = routes.get(5); assertEquals("rails_settings_ui/settings#update_all", route.getActionTitle()); assertEquals("/settings/update_all(.:format)", route.getPath()); } @Test public void testParsingEngineRoutesComputedProperties() throws Exception { RouteList routes = parser.parseFile("test/data/engine_routes_parsing.data.txt"); // Engine routes should follow parent engine route which mounts them Route route = routes.get(1); assertEquals("RailsAdmin::MainController#dashboard", route.getQualifiedActionTitle()); assertEquals("rails_admin.dashboard", route.getRouteName()); } @Test public void testParsingRedirectToConstant() { List<Route> routes = parser.parseLine( " redirect_301 GET /redirect_301(.:format) redirect(301, /books)"); Route actual = routes.get(0); assertEquals(RedirectRoute.class, actual.getClass()); assertEquals("/books", actual.getActionTitle()); } @Test public void testParsingProcRedirect() { String line = " redirect_proc GET /redirect_proc(.:format) redirect(301)"; List<Route> routes = parser.parseLine(line); Route actual = routes.get(0); assertEquals(RedirectRoute.class, actual.getClass()); assertEquals("[redirect]", actual.getActionTitle()); assertEquals("[runtime defined redirect]", actual.getQualifiedActionTitle()); } private String readFile( String file ) throws IOException { BufferedReader reader = new BufferedReader( new FileReader (file)); StringBuilder stringBuilder = new StringBuilder(); String ls = System.getProperty("line.separator"); String line; while( ( line = reader.readLine() ) != null ) { stringBuilder.append( line ); stringBuilder.append( ls ); } return stringBuilder.toString(); } }