spec_helper.cr 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. require "spec"
  2. require "../src/luce"
  3. require "../tools/expected_output"
  4. def validate_core(
  5. description : String,
  6. markdown : String,
  7. html : String,
  8. block_syntaxes = Array(Luce::BlockSyntax).new,
  9. inline_syntaxes = Array(Luce::InlineSyntax).new,
  10. extension_set : Luce::ExtensionSet? = nil,
  11. link_resolver : Luce::Resolver? = nil,
  12. image_link_resolver : Luce::Resolver? = nil,
  13. inline_only : Bool = false,
  14. enable_tag_filter : Bool = false
  15. )
  16. it description do
  17. result = Luce.to_html(markdown,
  18. block_syntaxes: block_syntaxes,
  19. inline_syntaxes: inline_syntaxes,
  20. extension_set: extension_set,
  21. link_resolver: link_resolver,
  22. image_link_resolver: image_link_resolver,
  23. inline_only: inline_only,
  24. enable_tag_filter: enable_tag_filter
  25. )
  26. result.should eq html
  27. end
  28. end
  29. def data_cases_in_file(path : String, base_dir : String? = nil, & : DataCase ->)
  30. file = Path[path].basename.to_s.sub(/\..+$/, "")
  31. base_dir ||= Path[Path[path].dirname].relative_to(Path[Path[path].dirname].dirname).to_s
  32. lines = File.read_lines(path, encoding: "utf-8")
  33. front_matter = String::Builder.new
  34. i = 0
  35. until lines[i].starts_with? ">>>"
  36. front_matter << "#{lines[i]}\n"
  37. i += 1
  38. end
  39. while i < lines.size
  40. description = lines[i].sub(/>>>\s*/, "").strip
  41. i += 1
  42. skip = description.starts_with? "skip:"
  43. if description.empty?
  44. description = "line #{i + 1}"
  45. else
  46. description = "line #{i + 1}: #{description}"
  47. end
  48. input = String::Builder.new
  49. until lines[i].starts_with? "<<<"
  50. input.puts(lines[i])
  51. i += 1
  52. end
  53. expected_output = String::Builder.new
  54. i += 1
  55. while i < lines.size && !lines[i].starts_with? ">>>"
  56. expected_output.puts(lines[i])
  57. i += 1
  58. end
  59. # You can only read from a String::Builder once.
  60. # So make a copy.
  61. front_matter_s = front_matter.to_s
  62. front_matter = String::Builder.new front_matter_s
  63. data_case = DataCase.new(input.to_s, expected_output.to_s, base_dir, file,
  64. front_matter_s, description, skip)
  65. yield data_case
  66. end
  67. end
  68. def data_cases(dir : String, ext = "unit", recursive = true) : Array(DataCase)
  69. entries = Dir[dir + "/**/*"]
  70. results = [] of DataCase
  71. entries.each do |entry|
  72. next unless entry.ends_with? ext
  73. relative_dir = Path[Path[entry].dirname].relative_to(Path[dir].dirname).to_s
  74. data_cases_in_file(entry, relative_dir) { |data_case| results << data_case }
  75. end
  76. results.sort do |lhs, rhs|
  77. compare = lhs.directory <=> rhs.directory
  78. next compare if compare != 0
  79. lhs.file <=> rhs.file
  80. end
  81. end
  82. def data_cases_under(dir : String, ext = "unit", recursive = true, &)
  83. directory = Path[Dir.current, "spec", dir].to_s
  84. data_cases(directory, ext, recursive).each { |data_case| yield data_case }
  85. end
  86. # Runs tests defined in "*.unit" files inside directory *name*.
  87. def test_directory(name : String, extension_set : Luce::ExtensionSet? = nil) : Nil
  88. data_cases_under(name) do |data_case|
  89. description = "#{data_case.directory}/#{data_case.file}.unit #{data_case.description}"
  90. inline_syntaxes = [] of Luce::InlineSyntax
  91. block_syntaxes = [] of Luce::BlockSyntax
  92. enable_tag_filter = false
  93. if data_case.file.ends_with? "_extension"
  94. extension = data_case.file[0...data_case.file.rindex("_extension")]
  95. case extension
  96. when "autolinks"
  97. inline_syntaxes << Luce::AutolinkExtensionSyntax.new
  98. when "strikethrough"
  99. inline_syntaxes << Luce::StrikethroughSyntax.new
  100. when "tables"
  101. block_syntaxes << Luce::TableSyntax.new
  102. when "disallowed_raw_html"
  103. enable_tag_filter = true
  104. else
  105. raise NotImplementedError.new("Extension set #{extension}")
  106. end
  107. end
  108. validate_core(
  109. description,
  110. data_case.input,
  111. data_case.expected_output,
  112. extension_set: extension_set,
  113. inline_syntaxes: inline_syntaxes,
  114. block_syntaxes: block_syntaxes,
  115. enable_tag_filter: enable_tag_filter)
  116. end
  117. end
  118. def test_file(file : String,
  119. block_syntaxes = Array(Luce::BlockSyntax).new,
  120. inline_syntaxes = Array(Luce::InlineSyntax).new)
  121. directory = Path[Dir.current, "spec"]
  122. data_cases_in_file(Path[directory, file].to_s) do |data_case|
  123. description = "#{data_case.directory}/#{data_case.file}.unit #{data_case.description}"
  124. validate_core(description, data_case.input, data_case.expected_output,
  125. block_syntaxes: block_syntaxes, inline_syntaxes: inline_syntaxes)
  126. end
  127. end
  128. class String < Reference
  129. # Converts this string to an array of `Luce::Line`.
  130. def to_lines : Array(Luce::Line)
  131. self.lines.map { |e| Luce::Line.new(e) }
  132. end
  133. end