<commit_before>require_relative 'setup_tests'

class TestRules < Minitest::Test

  def setup
    @rules = MarkdownLint::RuleSet.load_default
  end

  def get_expected_errors(lines)
    # Looks for lines tagged with {MD123} to signify that a rule is expected to
    # fire for this line. It also looks for lines tagged with {MD123:1} to
    # signify that a rule is expected to fire on another line (the line number
    # after the colon).
    expected_errors = {}
    re = /\{(MD\d+)(?::(\d+))?\}/
    lines.each_with_index do |line, num|
      m = re.match(line)
      while m
        expected_errors[m[1]] ||= []
        if m[2]
          expected_line = m[2].to_i
        else
          expected_line = num + 1 # 1 indexed lines
        end
        expected_errors[m[1]] << expected_line
        m = re.match(line, m.end(0))
      end
    end
    expected_errors
  end

  def do_lint(filename)
    doc = MarkdownLint::Doc.new(File.read(filename))
    expected_errors = get_expected_errors(doc.lines)
    actual_errors = {}
    @rules.sort.each do |id, rule|
      error_lines = rule.check.call(doc)
      if error_lines and not error_lines.empty?
        actual_errors[id] = error_lines
      end
    end
    assert_equal expected_errors, actual_errors
  end

  Dir[File.expand_path("../rule_tests/*.md", __FILE__)].each do |filename|
    define_method("test_#{File.basename(filename, '.md')}") do
      do_lint(filename)
    end
  end
end<commit_msg>Allow tests to have their own style files<commit_after>require_relative 'setup_tests'

class TestRules < Minitest::Test

  def get_expected_errors(lines)
    # Looks for lines tagged with {MD123} to signify that a rule is expected to
    # fire for this line. It also looks for lines tagged with {MD123:1} to
    # signify that a rule is expected to fire on another line (the line number
    # after the colon).
    expected_errors = {}
    re = /\{(MD\d+)(?::(\d+))?\}/
    lines.each_with_index do |line, num|
      m = re.match(line)
      while m
        expected_errors[m[1]] ||= []
        if m[2]
          expected_line = m[2].to_i
        else
          expected_line = num + 1 # 1 indexed lines
        end
        expected_errors[m[1]] << expected_line
        m = re.match(line, m.end(0))
      end
    end
    expected_errors
  end

  def do_lint(filename)
    # Check for a test_case_style.rb style file for individual tests
    style_file = filename.sub(/.md$/, '_style.rb')
    if ! File.exist?(style_file)
      style_file = 'all'
    end

    rules = MarkdownLint::RuleSet.load_default
    style = MarkdownLint::Style.load(style_file, rules)
    rules.select! {|r| style.rules.include?(r)}

    doc = MarkdownLint::Doc.new(File.read(filename))
    expected_errors = get_expected_errors(doc.lines)
    actual_errors = {}
    rules.sort.each do |id, rule|
      error_lines = rule.check.call(doc)
      if error_lines and not error_lines.empty?
        actual_errors[id] = error_lines
      end
    end
    assert_equal expected_errors, actual_errors
  end

  Dir[File.expand_path("../rule_tests/*.md", __FILE__)].each do |filename|
    define_method("test_#{File.basename(filename, '.md')}") do
      do_lint(filename)
    end
  end
end
{'fraction_non_alphanumeric': 0.11163080760835672, 'fraction_numerical': 0.008730901153726224, 'mean_word_length': 2.76084407971864, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7177145', 'n_tokens_mistral': 1070, 'n_tokens_neox': 1046, 'n_words': 278}