Skip to content

Commit

Permalink
Initial checking of revision control, extracted from FitNesse core an…
Browse files Browse the repository at this point in the history
…d enhanced.
  • Loading branch information
sfred committed Mar 12, 2009
0 parents commit cb5f4f5
Show file tree
Hide file tree
Showing 52 changed files with 3,045 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/fitnesse/revisioncontrol/ActionStyle.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package fitnesse.revisioncontrol;

public enum ActionStyle {
OK("pass"),
WARNING("error"),
ALERT("fail");

private final String style;

ActionStyle(String style) {
this.style = style;
}

public String getStyle() {
return style;
}
}
13 changes: 13 additions & 0 deletions src/fitnesse/revisioncontrol/NewRevisionResults.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package fitnesse.revisioncontrol;

public class NewRevisionResults extends Results {
protected long newRevision;

public long getNewRevision() {
return newRevision;
}

public void setNewRevision(long newRevision) {
this.newRevision = newRevision;
}
}
93 changes: 93 additions & 0 deletions src/fitnesse/revisioncontrol/NullState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package fitnesse.revisioncontrol;

import static fitnesse.revisioncontrol.RevisionControlOperation.*;

public abstract class NullState implements State {
protected String state;

public static final NullState VERSIONED = new Versioned("Versioned");
public static final NullState UNKNOWN = new Unknown("Unknown");
public static final NullState DELETED = new Deleted("Deleted");
public static final NullState ADDED = new Added("Added");

protected NullState(String state) {
this.state = state;
}

public boolean isCheckedOut() {
return true;
}

}

class Versioned extends NullState {
protected Versioned(String state) {
super(state);
}

public RevisionControlOperation[] operations() {
return new RevisionControlOperation[]{CHECKOUT, DELETE, UPDATE, STATUS};
}

public boolean isUnderRevisionControl() {
return true;
}

public boolean isCheckedIn() {
return true;
}
}

class Unknown extends NullState {
protected Unknown(String state) {
super(state);
}

public RevisionControlOperation[] operations() {
return new RevisionControlOperation[]{ADD};
}

public boolean isUnderRevisionControl() {
return false;
}

public boolean isCheckedIn() {
return false;
}
}

class Deleted extends NullState {
protected Deleted(String state) {
super(state);
}

public RevisionControlOperation[] operations() {
return new RevisionControlOperation[]{CHECKIN, REVERT, STATUS};
}

public boolean isUnderRevisionControl() {
return true;
}

public boolean isCheckedIn() {
return true;
}
}

class Added extends NullState {
protected Added(String state) {
super(state);
}

public RevisionControlOperation[] operations() {
return new RevisionControlOperation[]{CHECKIN, REVERT, STATUS};
}

public boolean isUnderRevisionControl() {
return true;
}

public boolean isCheckedIn() {
return false;
}
}
7 changes: 7 additions & 0 deletions src/fitnesse/revisioncontrol/OperationStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package fitnesse.revisioncontrol;

public enum OperationStatus {
SUCCESS,
FAILURE,
NOTHING_TO_DO
}
46 changes: 46 additions & 0 deletions src/fitnesse/revisioncontrol/Results.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package fitnesse.revisioncontrol;

import fitnesse.html.HtmlElement;
import fitnesse.html.HtmlTag;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Results {
private OperationStatus status = OperationStatus.SUCCESS;
private List<RevisionControlDetail> details = new ArrayList<RevisionControlDetail>();
private List<HtmlElement> detailLabels;

public OperationStatus getStatus() {
return status;
}

public void setStatus(OperationStatus status) {
this.status = status;
}

public List<RevisionControlDetail> getDetails() {
return Collections.unmodifiableList(details);
}

public void addDetail(RevisionControlDetail detail) {
details.add(detail);
}

public List<HtmlElement> getDetailLabels() {
return detailLabels;
}

public void setDetailLabels(HtmlElement... detailLabels) {
this.detailLabels = Arrays.asList(detailLabels);
}

public void setDetailLabels(String... detailLabels) {
this.detailLabels = new ArrayList<HtmlElement>();
for (String detailLabel : detailLabels) {
this.detailLabels.add(new HtmlTag("strong", detailLabel));
}
}
}
31 changes: 31 additions & 0 deletions src/fitnesse/revisioncontrol/RevisionControlActionsBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package fitnesse.revisioncontrol;

import fitnesse.revisioncontrol.wiki.RevisionControlledFileSystemPage;
import fitnesse.wiki.PageData;
import fitnesse.wiki.WikiPage;
import fitnesse.wiki.WikiPageAction;

import java.util.ArrayList;
import java.util.List;

public class RevisionControlActionsBuilder {
public static List<WikiPageAction> getRevisionControlActions(String pageName, PageData pageData) throws Exception {
List<WikiPageAction> actions = new ArrayList<WikiPageAction>();
if (pageData.hasAttribute("Edit") || pageData.hasAttribute("WikiImport")) {
final WikiPage wikiPage = pageData.getWikiPage();
if (shouldDisplayRevisionControlActions(wikiPage)) {
actions.add(new WikiPageAction(null, "Revision Control"));
final State state = ((RevisionControllable) wikiPage).getState();
final RevisionControlOperation[] operations = state.operations();
for (final RevisionControlOperation operation : operations)
actions.add(operation.makeAction(pageName));
}
}
return actions;
}

private static boolean shouldDisplayRevisionControlActions(WikiPage wikiPage) throws Exception {
return wikiPage instanceof RevisionControlledFileSystemPage &&
((RevisionControllable) wikiPage).isExternallyRevisionControlled();
}
}
131 changes: 131 additions & 0 deletions src/fitnesse/revisioncontrol/RevisionControlActionsBuilderTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package fitnesse.revisioncontrol;

import static fitnesse.revisioncontrol.NullState.UNKNOWN;
import static fitnesse.revisioncontrol.NullState.VERSIONED;
import fitnesse.revisioncontrol.wiki.RevisionControlledFileSystemPage;
import fitnesse.util.FileUtil;
import fitnesse.wiki.PageData;
import fitnesse.wiki.WikiPage;
import fitnesse.wiki.WikiPageAction;
import junit.framework.TestCase;
import static org.easymock.EasyMock.*;

import java.io.File;
import java.util.List;

public class RevisionControlActionsBuilderTest extends TestCase {
private static final String ROOT = "testDir";
private WikiPage root;
private final RevisionController revisionController = createMock(RevisionController.class);

@Override
protected void setUp() throws Exception {
FileUtil.createDir(ROOT);
expect(revisionController.getState((String) anyObject())).andStubReturn(VERSIONED);
expect(revisionController.add((String) anyObject())).andStubReturn(new Results());
}

@Override
protected void tearDown() throws Exception {
FileUtil.deleteFileSystemDirectory(ROOT);
verify(revisionController);
}

public void testShouldNotMakeRevisionControlActionsIfWikiIsNotUnderRevisionControl() throws Exception {
expect(revisionController.isExternalRevisionControlEnabled()).andReturn(false);
replay(revisionController);

final String pageName = "EditablePage";
List<WikiPageAction> actions = getActions(pageName);
assertRevisionControlItemsNotDisplayed(pageName, actions);
}

public void testShouldNotMakeRevisionControlActionsIfPageIsNotEditableNorImported() throws Exception {
replay(revisionController);

final String pageName = "NonEditablePage";
createRoot();
final WikiPage testPage = root.addChildPage(pageName);
final PageData pageData = testPage.getData();
pageData.removeAttribute("Edit");
testPage.commit(pageData);

List<WikiPageAction> actions = testPage.getActions();
assertRevisionControlItemsNotDisplayed(pageName, actions);
}

public void testShouldMakeAddToRevisionControlActionForPages() throws Exception {
final String pageName = "NotUnderVersionControlPage";
expect(revisionController.isExternalRevisionControlEnabled()).andReturn(true);
expect(revisionController.getState(contentAndPropertiesFilePath(ROOT + "/ExternalRoot/" + pageName))).andReturn(UNKNOWN);
replay(revisionController);

List<WikiPageAction> actions = getActions(pageName);
assertActionIsPresent(pageName, actions, RevisionControlOperation.ADD);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.CHECKIN);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.CHECKIN);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.REVERT);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.DELETE);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.STATUS);
}

public void testShouldDisplayAssociatedRevisionControlActionForPages() throws Exception {
final String pageName = "CheckedInPage";
expect(revisionController.isExternalRevisionControlEnabled()).andReturn(true);
expect(revisionController.getState(contentAndPropertiesFilePath(ROOT + "/ExternalRoot/" + pageName))).andReturn(VERSIONED);
replay(revisionController);

List<WikiPageAction> actions = getActions(pageName);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.ADD);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.CHECKIN);
assertActionIsPresent(pageName, actions, RevisionControlOperation.UPDATE);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.REVERT);
assertActionIsPresent(pageName, actions, RevisionControlOperation.DELETE);
assertActionIsPresent(pageName, actions, RevisionControlOperation.STATUS);
}

public void testShouldNotDisplayRevertActionForLocalUnchangedPages() throws Exception {
final String pageName = "UnchangedPage";
expect(revisionController.isExternalRevisionControlEnabled()).andReturn(true);
expect(revisionController.getState(contentAndPropertiesFilePath(ROOT + "/ExternalRoot/" + pageName))).andReturn(VERSIONED);
replay(revisionController);

List<WikiPageAction> actions = getActions(pageName);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.CHECKIN);
assertActionIsPresent(pageName, actions, RevisionControlOperation.UPDATE);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.REVERT);
assertActionIsPresent(pageName, actions, RevisionControlOperation.DELETE);
assertActionIsPresent(pageName, actions, RevisionControlOperation.STATUS);
}

private void createRoot() throws Exception {
root = RevisionControlledFileSystemPage.makeRoot(ROOT, "ExternalRoot", revisionController);
}

private List<WikiPageAction> getActions(String pageName) throws Exception {
createRoot();
WikiPage page = root.addChildPage(pageName);
return page.getActions();
}

private void assertRevisionControlItemsNotDisplayed(String pageName, List<WikiPageAction> actions) throws Exception {
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.ADD);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.CHECKIN);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.UPDATE);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.REVERT);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.DELETE);
assertActionIsNotPresent(pageName, actions, RevisionControlOperation.STATUS);
}

private String contentAndPropertiesFilePath(String basePath) {
return new File(basePath).getAbsolutePath();
}

private void assertActionIsPresent(String pageName, List<WikiPageAction> actions, RevisionControlOperation<?> operation) {
assertTrue(actions.contains(operation.makeAction(pageName)));
}

private void assertActionIsNotPresent(String pageName, List<WikiPageAction> actions, RevisionControlOperation<?> operation) {
assertFalse(actions.contains(operation.makeAction(pageName)));
}
}
35 changes: 35 additions & 0 deletions src/fitnesse/revisioncontrol/RevisionControlDetail.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package fitnesse.revisioncontrol;

import fitnesse.html.HtmlElement;
import fitnesse.html.HtmlTag;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class RevisionControlDetail {
private String filePath;
private List<HtmlElement> actionTags;

public RevisionControlDetail(String filePath, String... actions) {
this.filePath = filePath;
this.actionTags = new ArrayList<HtmlElement>(actions.length);
for (String action : actions) {
actionTags.add(new HtmlTag(action));
}
}

public RevisionControlDetail(String filePath, HtmlElement... actionTags) {
this.filePath = filePath;
this.actionTags = Arrays.asList(actionTags);
}

public String getFilePath() {
return filePath;
}

public List<HtmlElement> getActionTags() {
return Collections.unmodifiableList(actionTags);
}
}
17 changes: 17 additions & 0 deletions src/fitnesse/revisioncontrol/RevisionControlException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package fitnesse.revisioncontrol;

public class RevisionControlException extends RuntimeException {
private static final long serialVersionUID = 1L;

public RevisionControlException(Throwable cause) {
super(cause);
}

public RevisionControlException(String errorMsg) {
super(errorMsg);
}

public RevisionControlException(String errorMsg, Exception e) {
super(errorMsg, e);
}
}
Loading

0 comments on commit cb5f4f5

Please sign in to comment.