/**
   * RUL 012
   *
   * <p>Class: SuperTypeRule Unit: processRuleOnNode(Declaration d, ArrayList<Declaration>
   * allDecls);
   *
   * <p>Tests that the unit scores correctly for this class by evaluating three different instances.
   */
  @Test
  public void superTwo() {
    ArrayList<Declaration> allDecls = new ArrayList<Declaration>();

    Declaration a = new ClassDeclaration("Class A", false);
    Declaration b = new ClassDeclaration("Class B", false);
    Declaration c = new ClassDeclaration("Class C", false);
    Declaration d = new ClassDeclaration("Class D", false);

    allDecls.add(a);
    allDecls.add(b);
    allDecls.add(c);
    allDecls.add(d);

    // B and D used as super types here.
    c.addSuperClass(b.getName());
    a.addSuperClass(d.getName());

    SuperTypeRule rule = new SuperTypeRule();

    rule.processRuleOnNode(b, allDecls);
    assertEquals(1, rule.getScore());

    rule.processRuleOnNode(d, allDecls);
    assertEquals(1, rule.getScore());
  }
  /**
   * RUL 011
   *
   * <p>Class: SuperTypeRule Unit: processRuleOnNode(Declaration d, ArrayList<Declaration>
   * allDecls);
   *
   * <p>Tests that the unit scores correctly for this class by evaluating three different instances.
   */
  @Test
  public void superOne() {
    ArrayList<Declaration> allDecls = new ArrayList<Declaration>();

    Declaration a = new InterfaceDeclaration("Interface A");
    Declaration b = new InterfaceDeclaration("Interface B");
    Declaration c = new InterfaceDeclaration("Interface C");
    Declaration d = new InterfaceDeclaration("Interface D");

    allDecls.add(a);
    allDecls.add(b);
    allDecls.add(c);
    allDecls.add(d);

    // C and A used as super types here.
    d.addSuperClass(c.getName());
    c.addSuperClass(a.getName());

    // A used as super type here.
    b.addSuperClass(a.getName());

    SuperTypeRule rule = new SuperTypeRule();

    rule.processRuleOnNode(a, allDecls);
    assertEquals(2, rule.getScore());

    rule.processRuleOnNode(b, allDecls);
    assertEquals(0, rule.getScore());

    rule.processRuleOnNode(c, allDecls);
    assertEquals(1, rule.getScore());
  }
  /**
   * RUL 003
   *
   * <p>Unit: processRuleOnNode(Declaration beingScored, ArrayList<Declaration> allDecls);
   *
   * <p>This unit tests the unit to handle a null value. This cannot happen as by this stage of
   * executing rules the model will have already filtered these.
   */
  @Test
  public void consecThree() {
    ArrayList<Declaration> allDecls = new ArrayList<Declaration>();

    Declaration a = new ClassDeclaration("Class one", false);
    Declaration b = new ClassDeclaration("Class two", false);
    Declaration c = new ClassDeclaration("Class three", false);
    Declaration d = new ClassDeclaration("Class four", false);
    Declaration e = new ClassDeclaration("Class five", false);
    Declaration f = new ClassDeclaration("Class six", false);

    // Create one long hierarchy
    f.addSuperClass(e.getName());
    e.addSuperClass(d.getName());
    d.addSuperClass(c.getName());
    c.addSuperClass(b.getName());
    b.addSuperClass(a.getName());

    // Add all to list
    allDecls.add(f);
    allDecls.add(e);
    allDecls.add(d);
    allDecls.add(c);
    allDecls.add(b);
    allDecls.add(a);

    ConsecutiveExtendRule rule = new ConsecutiveExtendRule();

    rule.processRuleOnNode(null, allDecls);

    assertEquals(0, rule.getScore());
  }
  /**
   * RUL 001
   *
   * <p>Unit: processRuleOnNode (ConsecutiveExtendRule class)
   *
   * <p>Test checks The score of every declaration made.
   */
  @Test
  public void consecOne() {
    ArrayList<Declaration> allDecls = new ArrayList<Declaration>();

    Declaration a = new ClassDeclaration("Sub class one", false);
    Declaration b = new ClassDeclaration("Sub class two", false);
    Declaration c = new ClassDeclaration("Abstract class one", true);
    a.addSuperClass(c.getName());
    b.addSuperClass(c.getName());
    // C is a super class to A and B

    Declaration d = new ClassDeclaration("Abstract class two", true);
    Declaration e = new ClassDeclaration("Sub class three", false);
    e.addSuperClass(d.getName());
    // D is a super class to E

    Declaration f = new InterfaceDeclaration("Interface One");
    Declaration g = new InterfaceDeclaration("Interface Two");
    Declaration h = new InterfaceDeclaration("Interface Three");

    h.addSuperClass(g.getName());
    g.addSuperClass(f.getName());
    // F is super to G and G is super to H

    allDecls.add(a);
    allDecls.add(b);
    allDecls.add(c);
    allDecls.add(d);
    allDecls.add(e);
    allDecls.add(f);
    allDecls.add(g);
    allDecls.add(h);

    ConsecutiveExtendRule rule = new ConsecutiveExtendRule();

    // A's score
    rule.processRuleOnNode(a, allDecls);
    assertEquals(-1, rule.getScore());

    // B's score
    rule.processRuleOnNode(b, allDecls);
    assertEquals(-1, rule.getScore());

    rule.processRuleOnNode(c, allDecls);
    assertEquals(0, rule.getScore());

    rule.processRuleOnNode(d, allDecls);
    assertEquals(0, rule.getScore());

    rule.processRuleOnNode(e, allDecls);
    assertEquals(-1, rule.getScore());

    rule.processRuleOnNode(f, allDecls);
    assertEquals(0, rule.getScore());

    rule.processRuleOnNode(g, allDecls);
    assertEquals(-1, rule.getScore());

    rule.processRuleOnNode(h, allDecls);
    assertEquals(-2, rule.getScore());
  }