/* LanguageTool, a natural language style checker
 * Copyright (C) 2011 Daniel Naber (http://www.danielnaber.de)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */
package org.languagetool.rules;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import junit.framework.TestCase;

import org.languagetool.JLanguageTool;
import org.languagetool.Language;
import org.languagetool.rules.patterns.PatternRule;

public class RuleTest extends TestCase {

  public void testJavaRuleIds() throws IOException {
    final Set<String> ids = new HashSet<>();
    final Set<Class> ruleClasses = new HashSet<>();
    if (Language.LANGUAGES.length <= 1) {
      System.err.println("***************************************************************************");
      System.err.println("WARNING: found only these languages - the tests might not be complete:");
      System.err.println(Arrays.toString(Language.LANGUAGES));
      System.err.println("***************************************************************************");
    }
    for (Language language : Language.LANGUAGES) {
      final JLanguageTool lt = new JLanguageTool(language);
      final List<Rule> allRules = lt.getAllRules();
      for (Rule rule : allRules) {
        assertIdUniqueness(ids, ruleClasses, language, rule);
        assertIdValidity(language, rule);
        if (rule instanceof PatternRule) {
          // doesn't make sense, but that's the way it works for PatternRules
          // and it's documented that it always returns false:
          assertFalse(rule.supportsLanguage(language));
        } else {
          assertTrue(rule.supportsLanguage(language));
        }
      }
    }
  }

  private void assertIdUniqueness(Set<String> ids, Set<Class> ruleClasses, Language language, Rule rule) {
    final String ruleId = rule.getId();
    if (ids.contains(ruleId) && !ruleClasses.contains(rule.getClass())) {
      throw new RuntimeException("Rule id occurs more than once: '" + ruleId + "', language: " + language);
    }
    ids.add(ruleId);
    ruleClasses.add(rule.getClass());
  }

  private void assertIdValidity(Language language, Rule rule) {
    final String ruleId = rule.getId();
    if (!ruleId.matches("^[A-Z_]+$")) {
      throw new RuntimeException("Invalid character in rule id: '" + ruleId + "', language: "
              + language + ", only [A-Z_] are allowed");
    }
  }

}

@@ -2389,32 +2389,66 @@
 age(language));%0A
+          testExamples(rule, lt);%0A
         %7D%0A      
@@ -3165,10 +3165,1717 @@
  %7D%0A  %7D%0A%0A
+  private void testExamples(Rule rule, JLanguageTool lt) throws IOException %7B%0A    testCorrectExamples(rule, lt);%0A    testIncorrectExamples(rule, lt);%0A  %7D%0A%0A  private void testCorrectExamples(Rule rule, JLanguageTool lt) throws IOException %7B%0A    List%3CString%3E correctExamples = rule.getCorrectExamples();%0A    for (String correctExample : correctExamples) %7B%0A      String input = cleanMarkers(correctExample);%0A      enableOnlyOneRule(lt, rule);%0A      List%3CRuleMatch%3E ruleMatches = lt.check(input);%0A      assertEquals(%22Got unexpected rule match for correct example sentence:%5Cn%22%0A              + %22Text: %22 + input + %22%5Cn%22%0A              + %22Rule: %22 + rule.getId() + %22%5Cn%22%0A              + %22Matches: %22 + ruleMatches, 0, ruleMatches.size());%0A    %7D%0A  %7D%0A%0A  private void testIncorrectExamples(Rule rule, JLanguageTool lt) throws IOException %7B%0A    List%3CIncorrectExample%3E incorrectExamples = rule.getIncorrectExamples();%0A    for (IncorrectExample incorrectExample : incorrectExamples) %7B%0A      String input = cleanMarkers(incorrectExample.getExample());%0A      enableOnlyOneRule(lt, rule);%0A      List%3CRuleMatch%3E ruleMatches = lt.check(input);%0A      assertEquals(%22Did not get the expected rule match for the incorrect example sentence:%5Cn%22%0A              + %22Text: %22 + input + %22%5Cn%22%0A              + %22Rule: %22 + rule.getId() + %22%5Cn%22%0A              + %22Matches: %22 + ruleMatches, 1, ruleMatches.size());%0A    %7D%0A  %7D%0A%0A  private void enableOnlyOneRule(JLanguageTool lt, Rule ruleToActivate) %7B%0A    for (Rule rule : lt.getAllRules()) %7B%0A      lt.disableRule(rule.getId());%0A    %7D%0A    lt.enableRule(ruleToActivate.getId());%0A  %7D%0A%0A  private String cleanMarkers(String example) %7B%0A    return example.replace(%22%3Cmarker%3E%22, %22%22).replace(%22%3C/marker%3E%22, %22%22);%0A  %7D%0A%0A
 %7D%0A

use the new examples in the Java rules as test input