package com.karateca.ddescriber.model;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.intellij.mock.Mock;
import com.intellij.openapi.vfs.VirtualFile;

import org.junit.Before;
import org.junit.Test;

/**
 * @author andresdom@google.com (Andres Dominguez)
 */
public class JasmineTreeTest {

  private JasmineTree jasmineTree;

  @Before
  public void setUp() throws Exception {
    jasmineTree = new JasmineTree();
  }

  private JasmineFile createJasmineFile(boolean hasTestsMarkedToRun) {
    return createJasmineFile(hasTestsMarkedToRun, null);
  }

  private JasmineFile createJasmineFile(boolean hasTestsMarkedToRun, VirtualFile virtualFile) {
    TreeNode describe = createDescribe();

    describe.setVirtualFile(virtualFile);

    JasmineFile jasmineFile = mock(JasmineFile.class);

    when(jasmineFile.hasTestsMarkedToRun()).thenReturn(hasTestsMarkedToRun);
    when(jasmineFile.getTreeNode()).thenReturn(describe);
    when(jasmineFile.getVirtualFile()).thenReturn(virtualFile);

    return jasmineFile;
  }

  private TreeNode createDescribe() {
    TestFindResult descFindResult = MockFindResult.buildDescribe("d1");

    TreeNode describeNode = new TreeNode(descFindResult);
    describeNode.add(buildIt("it1"));
    describeNode.add(buildIt("it2"));

    return describeNode;
  }

  private TreeNode buildIt(String testText) {
    return new TreeNode(MockFindResult.buildIt(testText));
  }

  @Test
  public void shouldDeclareEmptyRoot() {
    assertEquals("Root node", jasmineTree.getRootNode().getUserObject());
    assertFalse(jasmineTree.isRootVisible());
  }

  @Test
  public void shouldAddTestsToEmptyTree() {
    // Given a describe with two its.
    JasmineFile jasmineFile = createJasmineFile(false);

    // When you add the jasmine file.
    jasmineTree.addFile(jasmineFile);

    // Then ensure the tree has the new nodes.
    TreeNode rootNode = jasmineTree.getRootNode();
    assertEquals(1, rootNode.getChildCount());

    // Ensure the describe node was added.
    TreeNode describeNode = (TreeNode) rootNode.getFirstChild();
    assertEquals("d1", describeNode.getNodeValue().getTestText());

    // Ensure the describe has two children.
    assertEquals(2, describeNode.getChildCount());
  }

  @Test
  public void shouldAddJasmineFileWhenItHasResultsMarkedToRun() {
    // Given a describe with tests marked to run.
    JasmineFile jasmineFile = createJasmineFile(true);

    // When you update the jasmine file.
    jasmineTree.updateFile(jasmineFile);

    // Then ensure the file was added.
    expectRootNodeContainsDescribeWithName("d1");
  }

  @Test
  public void shouldNotAddJasmineFileWhenItHasNoTestsMarkedToRun() {
    // Given a test file without marked tests.
    JasmineFile jasmineFile = createJasmineFile(false);

    // When you update the file.
    jasmineTree.updateFile(jasmineFile);

    // Then ensure the file was not added.
    assertEquals(0, jasmineTree.getRootNode().getChildCount());
  }

  @Test
  public void shouldRemoveExistingTestFileWhenThereAreNoTestsMarked() {
    VirtualFile virtualFile = new Mock.MyVirtualFile();

    // Given that you are showing a jasmine file.
    jasmineTree.updateFile(createJasmineFile(true, virtualFile));
    assertEquals(1, jasmineTree.getRootNode().getChildCount());

    // When you update the same file
    jasmineTree.updateFile(createJasmineFile(false, virtualFile));

    // Then ensure the node was removed.
    assertEquals(0, jasmineTree.getRootNode().getChildCount());
  }

  @Test
  public void shouldUpdateExistingTest() {
    VirtualFile virtualFile = new Mock.MyVirtualFile();

    // Given that you are showing a jasmine file.
    jasmineTree.updateFile(createJasmineFile(true, virtualFile));
    assertEquals(1, jasmineTree.getRootNode().getChildCount());

    // When you update the file.
    TestFindResult descFindResult = MockFindResult.buildDescribe("new name");

    JasmineFile jasmineFile = mock(JasmineFile.class);
    when(jasmineFile.getTreeNode()).thenReturn(new TreeNode(descFindResult));
    when(jasmineFile.getVirtualFile()).thenReturn(virtualFile);
    when(jasmineFile.hasTestsMarkedToRun()).thenReturn(true);

    // Then ensure the node was updated.
    expectRootNodeContainsDescribeWithName("new name");
  }

  private void expectRootNodeContainsDescribeWithName(String expectedName) {
    TreeNode rootNode = jasmineTree.getRootNode();
    TreeNode firstChild = (TreeNode) rootNode.getFirstChild();

    assertEquals(1, rootNode.getChildCount());
    assertEquals(expectedName, firstChild.getNodeValue().getTestText());
  }
}

@@ -37,109 +37,8 @@
 l;%0A%0A
-import static junit.framework.Assert.assertEquals;%0Aimport static junit.framework.Assert.assertFalse;%0A
 impo
@@ -194,56 +194,53 @@
 le;%0A
-%0A
 import 
-org.junit.Before;%0Aimport org.junit.Test;
+com.karateca.ddescriber.BaseTestCase;%0A
 %0A%0A/*
@@ -325,16 +325,37 @@
 reeTest 
+extends BaseTestCase 
 %7B%0A%0A  pri
@@ -389,18 +389,8 @@
 e;%0A%0A
-  @Before%0A
   pu
@@ -426,16 +426,35 @@
 ption %7B%0A
+    super.setUp();%0A
     jasm
@@ -1469,32 +1469,24 @@
 ext));%0A  %7D%0A%0A
-  @Test%0A
   public voi
@@ -1483,25 +1483,29 @@
 public void 
-s
+testS
 houldDeclare
@@ -1639,32 +1639,24 @@
 le());%0A  %7D%0A%0A
-  @Test%0A
   public voi
@@ -1649,33 +1649,37 @@
 %0A%0A  public void 
-s
+testS
 houldAddTestsToE
@@ -2282,32 +2282,24 @@
 nt());%0A  %7D%0A%0A
-  @Test%0A
   public voi
@@ -2296,25 +2296,29 @@
 public void 
-s
+testS
 houldAddJasm
@@ -2635,32 +2635,24 @@
 %22d1%22);%0A  %7D%0A%0A
-  @Test%0A
   public voi
@@ -2649,25 +2649,29 @@
 public void 
-s
+testS
 houldNotAddJ
@@ -2999,32 +2999,24 @@
 nt());%0A  %7D%0A%0A
-  @Test%0A
   public voi
@@ -3013,25 +3013,29 @@
 public void 
-s
+testS
 houldRemoveE
@@ -3536,16 +3536,8 @@
  %7D%0A%0A
-  @Test%0A
   pu
@@ -3546,17 +3546,21 @@
 ic void 
-s
+testS
 houldUpd

extend from the base test