// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved. // Released under the terms of the CPL Common Public License version 1.0. package fitnesse.responders.run; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; import fitnesse.wiki.*; public class SuiteContentsFinder { public static final String SUITE_SETUP_NAME = "SuiteSetUp"; public static final String SUITE_TEARDOWN_NAME = "SuiteTearDown"; private final WikiPage pageToRun; private final WikiPage wikiRootPage; private final SuiteFilter suiteFilter; private LinkedList<WikiPage> testPageList; public SuiteContentsFinder(final WikiPage pageToRun, final SuiteFilter suiteFilter, WikiPage root) { this.pageToRun = pageToRun; wikiRootPage = root; this.suiteFilter = (suiteFilter != null) ? suiteFilter : SuiteFilter.MATCH_ALL; testPageList = new LinkedList<WikiPage>(); } public List<WikiPage> makePageListForSingleTest() { testPageList = new LinkedList<WikiPage>(); testPageList.add(pageToRun); return testPageList; } public List<WikiPage> makePageList() { getAllPagesToRunForThisSuite(); if (testPageList.isEmpty()) { String name = new WikiPagePath(pageToRun).toString(); WikiPageDummy dummy = new WikiPageDummy("", "|Comment|\n|No test found with " + suiteFilter.toString() + " in subwiki !-" + name + "-!!|\n" ); dummy.setParent(wikiRootPage); testPageList.add(dummy); } return testPageList; } public LinkedList<WikiPage> getAllPagesToRunForThisSuite() { String content = pageToRun.getData().getHtml(); //todo perf: all pages html parsed here? if (SuiteSpecificationRunner.isASuiteSpecificationsPage(content)) { SuiteSpecificationRunner runner = new SuiteSpecificationRunner(wikiRootPage); if (runner.getPageListFromPageContent(content)) testPageList = runner.testPageList; } else { testPageList = getAllTestPagesUnder(); List<WikiPage> referencedPages = gatherCrossReferencedTestPages(); testPageList.addAll(referencedPages); } return testPageList; } private LinkedList<WikiPage> getAllTestPagesUnder() { LinkedList<WikiPage> testPages = new LinkedList<WikiPage>(); addTestPagesToSuite(testPages, pageToRun, suiteFilter); Collections.sort(testPages, new Comparator<WikiPage>() { public int compare(WikiPage p1, WikiPage p2) { try { PageCrawler crawler = p1.getPageCrawler(); WikiPagePath path1 = crawler.getFullPath(p1); WikiPagePath path2 = crawler.getFullPath(p2); return path1.compareTo(path2); } catch (Exception e) { e.printStackTrace(); return 0; } } } ); return testPages; } private void addTestPagesToSuite(List<WikiPage> suite, WikiPage page, SuiteFilter suiteFilter) { if (suiteFilter.isMatchingTest(page)) { suite.add(page); } SuiteFilter suiteFilterForChildren = suiteFilter.getFilterForTestsInSuite(page); List<WikiPage> children = getChildren(page); for (WikiPage child : children) { addTestPagesToSuite(suite, child, suiteFilterForChildren); } } private static List<WikiPage> getChildren(WikiPage page) { List<WikiPage> children = new ArrayList<WikiPage>(); children.addAll(page.getChildren()); addVirtualChildrenIfAny(page, children); return children; } private static void addVirtualChildrenIfAny(WikiPage context, List<WikiPage> children) { if (context.hasExtension(VirtualCouplingExtension.NAME)) { VirtualCouplingExtension extension = (VirtualCouplingExtension) context.getExtension( VirtualCouplingExtension.NAME ); children.addAll(extension.getVirtualCoupling().getChildren()); } } protected List<WikiPage> gatherCrossReferencedTestPages() { List<WikiPage> pages = new LinkedList<WikiPage>(); addAllXRefs(pages, pageToRun); return pages; } private void addAllXRefs(List<WikiPage> xrefPages, WikiPage page) { List<WikiPage> children = page.getChildren(); addXrefPages(xrefPages, page); for (WikiPage child: children) addAllXRefs(xrefPages, child); } private void addXrefPages(List<WikiPage> pages, WikiPage thePage) { ReadOnlyPageData data = thePage.readOnlyData(); List<String> pageReferences = data.getXrefPages(); PageCrawler crawler = thePage.getPageCrawler(); WikiPagePath testPagePath = crawler.getFullPath(thePage); WikiPage parent = crawler.getPage(wikiRootPage, testPagePath.parentPath()); for (String pageReference : pageReferences) { WikiPagePath path = PathParser.parse(pageReference); WikiPage referencedPage = crawler.getPage(parent, path); if (referencedPage != null) pages.add(referencedPage); } } public static boolean isSuiteSetupOrTearDown(WikiPage testPage) { String name = testPage.getName(); return (SUITE_SETUP_NAME.equals(name) || SUITE_TEARDOWN_NAME.equals(name)); } }