diff --git a/Gemfile.lock b/Gemfile.lock index 26566cd..a3e764f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,9 +7,15 @@ PATH GEM remote: https://rubygems.org/ specs: + diffy (3.4.2) + json (2.7.1) kramdown (2.4.0) rexml minitest (5.16.3) + minitest-match_json (0.2.0) + diffy + json + minitest (>= 4.0) rake (13.0.6) rexml (3.2.5) @@ -19,6 +25,7 @@ PLATFORMS DEPENDENCIES kramdown-prismic! minitest (~> 5.0) + minitest-match_json (~> 0.2.0) rake (~> 13.0) BUNDLED WITH diff --git a/Rakefile b/Rakefile index 3bbc89c..6590825 100644 --- a/Rakefile +++ b/Rakefile @@ -4,6 +4,6 @@ require 'rake/testtask' Rake::TestTask.new do |t| t.libs << 'test' - t.test_files = FileList['test/*_test.rb'] + t.test_files = FileList['test/**/*_test.rb'] t.verbose = true end diff --git a/bin/html2prismic b/bin/html2prismic index 55e6780..f4785db 100755 --- a/bin/html2prismic +++ b/bin/html2prismic @@ -2,5 +2,26 @@ require 'kramdown-prismic' require 'json' +require 'optparse' -print Kramdown::Document.new(ARGV[0], input: :html).to_prismic.to_json.to_s +options = {} +OptionParser.new do |opts| + opts.banner = "Usage: html2prismic [options]" + + opts.on("-fFORMAT", "--format=FORMAT", "Prismic format to use") do |format| + options[:format] = format&.strip&.downcase&.to_sym + end +end.parse! + +document = Kramdown::Document.new(ARGV[0], input: :html) + +result = case options.fetch(:format, :v1) + when :v1 + document.to_prismic + when :v2 + document.to_prismic_v2 + else + print "Unknown Prismic fomat variant" +end + +print result.to_json.to_s diff --git a/bin/markdown2prismic b/bin/markdown2prismic index 898c724..75278e5 100755 --- a/bin/markdown2prismic +++ b/bin/markdown2prismic @@ -2,5 +2,28 @@ require 'kramdown-prismic' require 'json' +require 'optparse' -print Kramdown::Document.new(ARGV[0], input: :markdown).to_prismic.to_json.to_s +begin + options = {} + OptionParser.new do |opts| + opts.banner = "Usage: markdown2prismic [options]" + + opts.on("-fFORMAT", "--format=FORMAT", "Prismic format to use") do |format| + options[:format] = format&.strip&.downcase&.to_sym + end + end.parse! + + document = Kramdown::Document.new(ARGV[0], input: :markdown) + + result = case options.fetch(:format, :v1) + when :v1 + document.to_prismic + when :v2 + document.to_prismic_v2 + else + print "Unknown Prismic fomat variant" + end + + print result.to_json.to_s +end \ No newline at end of file diff --git a/bin/prismic2html b/bin/prismic2html new file mode 100755 index 0000000..4c68640 --- /dev/null +++ b/bin/prismic2html @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby + +require 'kramdown-prismic' +require 'json' +require 'optparse' + +begin + options = {} + OptionParser.new do |opts| + opts.banner = "Usage: prismic2markdown [options]" + + opts.on("-fFORMAT", "--format=FORMAT", "Prismic format to use") do |format| + options[:format] = format&.strip&.downcase&.to_sym + end + end.parse! + + source = JSON.parse(ARGV[0], symbolize_names: true) + + format = case options.fetch(:format, :v1) + when :v1 + :prismic + when :v2 + :prismic_v2 + else + print "Unknown Prismic fomat variant" + end + + document = Kramdown::Document.new(source, input: format) + + print document.to_html +end \ No newline at end of file diff --git a/bin/prismic2markdown b/bin/prismic2markdown index d19e05c..4034684 100755 --- a/bin/prismic2markdown +++ b/bin/prismic2markdown @@ -2,7 +2,30 @@ require 'kramdown-prismic' require 'json' +require 'optparse' -source = JSON.parse(ARGV[0], symbolize_names: true) +begin + options = {} + OptionParser.new do |opts| + opts.banner = "Usage: prismic2markdown [options]" -print Kramdown::Document.new(source, input: :prismic).to_kramdown + opts.on("-fFORMAT", "--format=FORMAT", "Prismic format to use") do |format| + options[:format] = format&.strip&.downcase&.to_sym + end + end.parse! + + source = JSON.parse(ARGV[0], symbolize_names: true) + + format = case options.fetch(:format, :v1) + when :v1 + :prismic + when :v2 + :prismic_v2 + else + print "Unknown Prismic fomat variant" + end + + document = Kramdown::Document.new(source, input: format) + + print document.to_kramdown +end \ No newline at end of file diff --git a/kramdown-prismic.gemspec b/kramdown-prismic.gemspec index 58cc0f7..c8defdd 100644 --- a/kramdown-prismic.gemspec +++ b/kramdown-prismic.gemspec @@ -20,6 +20,8 @@ Gem::Specification.new do |s| s.license = 'MIT' s.add_dependency 'kramdown', '>= 1', '< 3' + s.add_development_dependency 'minitest', '~> 5.0' s.add_development_dependency 'rake', '~> 13.0' + s.add_development_dependency 'minitest-match_json', '~> 0.2.0' end diff --git a/lib/kramdown-prismic.rb b/lib/kramdown-prismic.rb index a580fa1..ba2d250 100644 --- a/lib/kramdown-prismic.rb +++ b/lib/kramdown-prismic.rb @@ -2,6 +2,40 @@ require 'kramdown' -require 'kramdown/parser/prismic' -require 'kramdown/converter/prismic' require 'kramdown-prismic/version' +require 'kramdown-prismic/format_util' +require 'kramdown-prismic/parser/import_api' +require 'kramdown-prismic/parser/migration_api' +require 'kramdown-prismic/converter/import_api' +require 'kramdown-prismic/converter/migration_api' + +# Injects Prismic converters and parsers so that Kramdown can see them +# +# At a high level we implement only one format for each and convert the +# other into it. Since conversion from the V1 to the V1 API format is +# simpler - we only need to inline a few files into their enclosing +# elements (see `FormatUtil::V2` for details) instead of tracking which +# of the fields should be nested from a flatter represenation - in each +# case we choose the format we can apply the V1 -> V2 conversion. +# +# This means that: +# * for the converter it's more conventient to implement it on the V1 +# format and then use `FormatUtil::V2.from_v1` to flatten it +# appropriately _after_ the conversion, if output is in V2, +# * for the parser it's more convenient to implement it on the V2 +# format and then use `FormatUtil::V2.from_v1` to flatten it +# appropriately before parsing, if input is in V1. +module Kramdown + module Converter + Prismic = KramdownPrismic::Converter::ImportApi + PrismicV2 = KramdownPrismic::Converter::MigrationApi + end + + module Parser + # NOTE: odd constant naming is due to how `input` parameter -> classname conversion is handled for + # parser, which - contrary to converters - doesn't handle PascalCase correctly: + # https://github.com/gettalong/kramdown/blob/REL_2_4_0/lib/kramdown/document.rb#L98-L102 + Prismic_v2 = KramdownPrismic::Parser::MigrationApi + Prismic = KramdownPrismic::Parser::ImportApi + end +end \ No newline at end of file diff --git a/lib/kramdown/converter/prismic.rb b/lib/kramdown-prismic/converter/import_api.rb similarity index 85% rename from lib/kramdown/converter/prismic.rb rename to lib/kramdown-prismic/converter/import_api.rb index d68dd75..2fe8180 100644 --- a/lib/kramdown/converter/prismic.rb +++ b/lib/kramdown-prismic/converter/import_api.rb @@ -2,16 +2,20 @@ require 'kramdown/converter/base' -module Kramdown +module KramdownPrismic module Converter - class Prismic < Base + Utils = Kramdown::Utils + Element = Kramdown::Element + + # Converter for the Prismic API V1 format (aka Import API format) + class ImportApi < Kramdown::Converter::Base def convert(root) cleanup_ast(root).map do |child| convert_element(child) end.compact.flatten end - private + protected def cleanup_ast(root) remove_blanks(root) @@ -56,7 +60,28 @@ def extract_non_nestable_elements(child, elements) end def convert_element(element) - send("convert_#{element.type}", element) + result = send("convert_#{element.type}", element) + + case result + when nil then nil + when Array + result.map(&method(:with_sorted_spans)) + else + with_sorted_spans(result) + end + end + + # Sort spans to match default Prismic ordering - it is not + # an API requirement, but makes testing easier if you have + # a matching ordering + def with_sorted_spans(element) + if (spans = element.dig(:content, :spans)) + element[:content][:spans] = spans.sort do |lhs, rhs| + [lhs[:type], lhs[:start]] <=> [rhs[:type], rhs[:start]] + end + end + + element end def convert_header(element) @@ -133,6 +158,7 @@ def convert_img(element) end # This can only apply when an link with an image inside has been detected + # TODO: This is not quite true, it's also callded with (at least) a top-level `` as well def convert_a(element) image = element.children.first { @@ -173,11 +199,11 @@ def convert_sub_html_element(element, type) def convert_html_element(element) if element.value == 'iframe' { + type: 'embed', content: { - spans: [], - text: '' + text: '', + spans: [] }, - type: 'embed', data: { embed_url: element.attr['src'], type: 'link' @@ -235,10 +261,21 @@ def extract_content(element, memo = { text: '', spans: [] }) end end - def insert_span(element, memo, span) + def insert_span(element, memo, span_attributes) + # Attributes are inserted in order of: + # type, start, end, other attributes + # again, for slighly simpler comparisions + # against typical Prismic ordering in tests + span = { + type: span_attributes.delete(:type), + } + span[:start] = memo[:text].size extract_content(element, memo) span[:end] = memo[:text].size + + span.merge!(span_attributes) + memo[:spans] << span memo end diff --git a/lib/kramdown-prismic/converter/migration_api.rb b/lib/kramdown-prismic/converter/migration_api.rb new file mode 100644 index 0000000..281e75e --- /dev/null +++ b/lib/kramdown-prismic/converter/migration_api.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require_relative 'import_api' + +module KramdownPrismic + module Converter + # Converter for the Prismic API V2 format (aka Migration API format) + # + # It's basically thing wrapper over the V1 converter, that applies + # common conversion rules between those formats when emitting an element + class MigrationApi < ImportApi + def convert_element(element) + result = super + + return nil unless result + + case result + when Array then result.map(&FormatUtil::V2.method(:from_v1)) + else FormatUtil::V2.from_v1(result) + end + end + end + end +end diff --git a/lib/kramdown-prismic/format_util.rb b/lib/kramdown-prismic/format_util.rb new file mode 100644 index 0000000..d0f0c9e --- /dev/null +++ b/lib/kramdown-prismic/format_util.rb @@ -0,0 +1,111 @@ +# frozen_string_literal: true + +module KramdownPrismic + module FormatUtil + # Utilities for converting to API V2 representation (used e.g. in the Migration API) + module V2 + class << self + # Convert element from API V1 representation + def from_v1(element) + element = element.dup + type = element[:type] + + # All content attributes are inlined into the enclosing object + content = element.delete(:content)&.dup || {} + + # Except some types don't have content-related attributes at all + element = element.merge(content) unless type == "image" || type == "embed" + + # If there's some special processing needed for the element type, do that + element = process_element(element) + + # Adjust any span-level elements to the new format + element[:spans] = element[:spans].map(&method(:process_span_element)) if element.has_key?(:spans) + + element + end + + private + + def process_element(element) + processor_method = :"#{ element[:type] }_from_v1" + + # We need to include private methods here + return element unless respond_to?(processor_method, true) + + send(processor_method, element) + end + + def process_span_element(element) + processor_method = :"span_#{ element[:type] }_from_v1" + + # We need to include private methods here + return element unless respond_to?(processor_method, true) + + send(processor_method, element) + end + + def image_from_v1(element) + # Attributes describing the image are no longer nested under `data` + data = element.delete(:data)&.dup + + # The `id` and `url`` attributes need to be inlined into the top-level object + origin = data.delete(:origin) + + data[:id] = origin[:id] if origin[:id] + data[:url] = origin[:url] if origin[:url] + + # Image dimesions need to nested into an object under `dimensions` ke + height = data.delete(:height) + width = data.delete(:width) + + if !(dimensions = {:height => height, :width => width}.compact).empty? + data[:dimensions] = dimensions + end + + # Cropping attributes need to inlined into the parent `edit` object + if data.dig(:edit, :crop) + data[:edit] = data[:edit].dup + + data[:edit].merge!(data[:edit].delete(:crop)) + end + + # The image attributes are instead inlined into the top-level object + element.merge(data) + end + + def embed_from_v1(element) + data = element.delete(:data) + + # The object with embed attributes is renamed + element[:oembed] = data + + element + end + + def span_hyperlink_from_v1(element) + data = element[:data].dup + uri = data.delete(:url) + + # Prismic treats links to internal assets specially + case link_kind(uri) + when :web then data.merge!(url: uri, link_type: "Web") + when :document then data.merge!(wioUrl: uri, link_type: "Document") + when :media then data.merge!(wioUrl: uri, link_type: "Media") + end + + element[:data] = data + element + end + + def link_kind(uri) + case uri + when /^wio:\/\/documents\// then :document + when /^wio:\/\/medias\// then :media + else :web + end + end + end + end + end +end \ No newline at end of file diff --git a/lib/kramdown-prismic/parser/import_api.rb b/lib/kramdown-prismic/parser/import_api.rb new file mode 100644 index 0000000..3a13414 --- /dev/null +++ b/lib/kramdown-prismic/parser/import_api.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require_relative 'migration_api' + +module KramdownPrismic + module Parser + # Converter for the Prismic API V1 format (aka Import API format) + # + # It's basically thing wrapper over the V2 converter, that applies + # common conversion rules between those formats before parsing + # an element + class ImportApi < MigrationApi + protected + + def parse_element(block, memo) + converted = FormatUtil::V2.from_v1(block) + + super(converted, memo) + end + end + end +end diff --git a/lib/kramdown/parser/prismic.rb b/lib/kramdown-prismic/parser/migration_api.rb similarity index 74% rename from lib/kramdown/parser/prismic.rb rename to lib/kramdown-prismic/parser/migration_api.rb index e475aea..4e955c8 100644 --- a/lib/kramdown/parser/prismic.rb +++ b/lib/kramdown-prismic/parser/migration_api.rb @@ -1,8 +1,14 @@ # frozen_string_literal: true -module Kramdown +require 'kramdown/parser/base' + +module KramdownPrismic module Parser - class Prismic < Base + Utils = Kramdown::Utils + Element = Kramdown::Element + + # Converter for the Prismic API V2 format (aka Migration API format) + class MigrationApi < Kramdown::Parser::Base def parse @root.options[:encoding] = 'UTF-8' @root.children = @source.reduce([]) do |memo, block| @@ -10,7 +16,7 @@ def parse end end - private + protected def parse_element(block, memo) type = block[:type].gsub('-', '_') @@ -39,9 +45,10 @@ def parse_paragraph(_block) def parse_image(block) p = Element.new(:p) - img = Element.new(:img, nil, { 'src' => block[:data][:origin][:url], 'alt' => block[:data][:alt] }) - if block[:data][:linkTo] - a = Element.new(:a, nil, { 'href' => block[:data][:linkTo][:url] }) + # Note that in V2 format the `data` attribute is inlined + img = Element.new(:img, nil, { 'src' => block[:url], 'alt' => block[:alt] }) + if block[:linkTo] + a = Element.new(:a, nil, { 'href' => block.dig(:linkTo, :url) }) a.children << img p.children << a else @@ -68,13 +75,17 @@ def parse_list(type, block, memo) end def parse_embed(block) - Element.new(:html_element, 'iframe', { src: block[:data][:embed_url] }) + # Note how in V2 format `data` attribute is now `oembed` + Element.new(:html_element, 'iframe', { src: block[:oembed][:embed_url] }) end def parse_spans(element, block) stack = [] - (block[:content][:text].size + 1).times do |index| + # In V2 some entities (such as images or embeds) don't get content attributes + return unless block.has_key?(:text) + + (block[:text].size + 1).times do |index| starting_spans = find_starting_spans_for(block, index) ending_spans = find_ending_spans_for(block, index) @@ -94,7 +105,7 @@ def parse_spans(element, block) end end - char = block[:content][:text][index] + char = block[:text][index] next if char.nil? current_text = if stack.empty? @@ -115,7 +126,8 @@ def parse_spans(element, block) end def find_starting_spans_for(block, index) - block[:content][:spans].find_all do |span| + # Note how in V2 `content` attributes are inlined + block[:spans].find_all do |span| span[:start] == index end.sort_by do |span| -span[:end] @@ -123,7 +135,8 @@ def find_starting_spans_for(block, index) end def find_ending_spans_for(block, index) - block[:content][:spans].find_all do |span| + # Note how in V2 `content` attributes are inlined + block[:spans].find_all do |span| span[:end] == index end end diff --git a/test/conversion_test.rb b/test/conversion_test.rb new file mode 100644 index 0000000..65c915d --- /dev/null +++ b/test/conversion_test.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +require "json" + +require "minitest/autorun" +require 'minitest/match_json' + +require "kramdown-prismic" + + +class KramdownPrismicImportApiConverterTest < Minitest::Test + def test_from_html_to_prismic_v1 + document = Kramdown::Document.new(fixture("web.html"), :input => :html) + expected = JSON.parse(fixture("import-api.json"), :symbolize_names => true) + + assert_match_json expected, document.to_prismic + end + + def test_from_html_to_prismic_v2 + document = Kramdown::Document.new(fixture("web.html"), :input => :html) + expected = JSON.parse(fixture("migration-api.json"), :symbolize_names => true) + + assert_match_json expected, document.to_prismic_v2 + end + + def test_from_markdown_to_prismic_v1 + document = Kramdown::Document.new(fixture("markdown.md"), :input => :markdown) + expected = JSON.parse(fixture("import-api.json"), :symbolize_names => true) + result = document.to_prismic + + result.each do |element| + if (text = element.dig(:content, :text)) + element[:content][:text] = text.gsub(/\n/, " ") + end + end + + assert_match_json expected, result + end + + def test_from_markdown_to_prismic_v2 + document = Kramdown::Document.new(fixture("markdown.md"), :input => :markdown) + expected = JSON.parse(fixture("migration-api.json"), :symbolize_names => true) + result = document.to_prismic_v2 + + result.each do |element| + if (text = element[:text]) + element[:text] = text.gsub(/\n/, " ") + end + end + + assert_match_json expected, result + end + + def test_from_prismic_v1_to_markdown + document = Kramdown::Document.new(JSON.parse(fixture("import-api.json"), :symbolize_names => true), :input => :prismic) + expected = fixture("markdown.md") + + assert_match expected, document.to_kramdown + end + + def test_from_prismic_v2_to_markdown + document = Kramdown::Document.new(JSON.parse(fixture("migration-api.json"), :symbolize_names => true), :input => :prismic_v2) + expected = fixture("markdown.md") + + assert_match expected, document.to_kramdown + end + + protected + + def fixture(name) + File.read(File.expand_path(File.join("fixtures", name), __dir__)) + end +end diff --git a/test/converter_test.rb b/test/converter/import_api_test.rb similarity index 99% rename from test/converter_test.rb rename to test/converter/import_api_test.rb index f01589a..019b6da 100644 --- a/test/converter_test.rb +++ b/test/converter/import_api_test.rb @@ -3,7 +3,7 @@ require 'minitest/autorun' require 'kramdown-prismic' -class KramdownPrismicConverterTest < Minitest::Test +class KramdownPrismicImportApiConverterTest < Minitest::Test 6.times do |heading| define_method "test_convert_heading_#{heading}" do expected = [ diff --git a/test/converter/migration_api_test.rb b/test/converter/migration_api_test.rb new file mode 100644 index 0000000..1d07b65 --- /dev/null +++ b/test/converter/migration_api_test.rb @@ -0,0 +1,669 @@ +# frozen_string_literal: true + +require 'minitest/autorun' +require 'kramdown-prismic' + +class KramdownPrismicMigrationApiConverterTest < Minitest::Test + 6.times do |heading| + define_method "test_convert_heading_#{heading}" do + expected = [ + { + type: "heading#{heading + 1}", + text: 'This is the document title', + spans: [] + } + ] + markdown = "#{'#' * (heading + 1)} This is the document title" + assert_equal expected, Kramdown::Document.new(markdown, input: :kramdown).to_prismic_v2 + end + end + + def test_convert_heading7 + expected = [ + { + type: 'heading6', + text: '# This is the document title', + spans: [] + } + ] + markdown = '####### This is the document title' + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_heading_with_spans + expected = [ + { + type: 'heading2', + text: 'This is a document title', + spans: [ + { + type: 'em', + start: 0, + end: 4 + } + ] + } + ] + markdown = '## *This* is a document title' + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_paragraph + expected = [ + { + type: 'paragraph', + text: 'This is a paragraph', + spans: [] + } + ] + markdown = 'This is a paragraph' + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_paragraph_with_spans + expected = [ + { + type: 'paragraph', + text: 'This is a paragraph', + spans: [ + { + type: 'hyperlink', + start: 0, + end: 19, + data: { + url: 'https://prismic.io', + link_type: 'Web' + } + } + ] + } + ] + markdown = '[This is a paragraph](https://prismic.io)' + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_paragraph_with_strong + expected = [ + { + type: 'paragraph', + text: 'This is a paragraph', + spans: [ + { + type: 'strong', + start: 0, + end: 19 + } + ] + } + ] + markdown = '**This is a paragraph**' + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_paragraph_with_strong2 + expected = [ + { + type: 'paragraph', + text: 'This is a paragraph', + spans: [ + { + type: 'strong', + start: 0, + end: 4 + } + ] + } + ] + markdown = '**This** is a paragraph' + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_html_strong + expected = [ + { + type: 'paragraph', + text: 'This is a paragraph', + spans: [ + { + type: 'strong', + start: 0, + end: 19 + } + ] + } + ] + markdown = 'This is a paragraph' + assert_equal expected, Kramdown::Document.new(markdown, input: :html).to_prismic_v2 + end + + def test_convert_paragraph_with_em + expected = [ + { + type: 'paragraph', + text: 'This is a paragraph', + spans: [ + { + type: 'em', + start: 0, + end: 4 + } + ] + } + ] + markdown = '*This* is a paragraph' + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_html_em + expected = [ + { + type: 'paragraph', + text: 'This', + spans: [ + { + type: 'em', + start: 0, + end: 4 + } + ] + } + ] + markdown = 'This' + assert_equal expected, Kramdown::Document.new(markdown, input: :html).to_prismic_v2 + end + + def test_convert_list_o + expected = [ + { + type: 'o-list-item', + text: 'This is a list item', + spans: [ + { + type: 'em', + start: 0, + end: 4 + } + ] + }, + { + type: 'o-list-item', + text: 'This is a second list item', + spans: [] + } + ] + markdown = "1. *This* is a list item\n2. This is a second list item" + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_list_u + expected = [ + { + type: 'list-item', + text: 'This is a list item', + spans: [ + { + type: 'em', + start: 0, + end: 4 + } + ] + }, + { + type: 'list-item', + text: 'This is a second list item', + spans: [] + } + ] + markdown = "- *This* is a list item\n- This is a second list item" + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_nested_ul + expected = [ + { + type: 'list-item', + text: "item1\n", + spans: [] + }, + { + type: 'list-item', + text: 'item2', + spans: [] + } + ] + markdown = "- item1\n - item2" + doc = Kramdown::Document.new(markdown, input: :markdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end + + def test_convert_nested_ol + expected = [ + { + type: 'list-item', + text: "item1\n", + spans: [] + }, + { + type: 'o-list-item', + text: 'item2', + spans: [] + } + ] + markdown = "- item1\n 1. item2" + doc = Kramdown::Document.new(markdown, input: :markdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end + + def test_convert_nested_nested_ul + expected = [ + { + type: 'list-item', + text: "item1\n", + spans: [] + }, + { + type: 'list-item', + text: "item2\n", + spans: [] + }, + { + type: 'list-item', + text: 'item3', + spans: [] + } + ] + markdown = "- item1\n - item2\n - item3" + doc = Kramdown::Document.new(markdown, input: :markdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 2, doc.warnings.size + end + + def test_convert_heading_in_list + expected = [ + { + type: 'list-item', + text: "", + spans: [] + }, + { + type: 'heading4', + text: 'Title', + spans: [] + } + ] + html = "" + doc = Kramdown::Document.new(html, input: :html) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end + + def test_convert_preformatted + expected = [ + { + type: 'preformatted', + text: "This is a pre block\n", + spans: [] + } + ] + markdown = " This is a pre block\n" + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_blockquote + expected = [ + { + type: 'preformatted', + text: 'This is a blockquote', + spans: [] + } + ] + markdown = "> This is a blockquote\n" + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_empty + expected = [] + markdown = '' + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_span_blank + expected = [ + { + type: 'o-list-item', + text: 'Testtest', + spans: [] + } + ] + markdown = "\n1. Test\n\n test\n" + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_hr + expected = [] + markdown = '---' + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + def test_convert_img + expected = [ + { + type: 'image', + url: '/img.png', + alt: 'alt text' + } + ] + markdown = '![alt text](/img.png)' + doc = Kramdown::Document.new(markdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 0, doc.warnings.size + end + + def test_convert_double_img + expected = [ + { + type: 'image', + url: '/img.png', + alt: '' + }, + { + type: 'image', + url: '/img2.png', + alt: '' + } + ] + markdown = '![](/img.png)![](/img2.png)' + doc = Kramdown::Document.new(markdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 2, doc.warnings.size + end + + # TODO: should probably be unsupported + def test_convert_img_with_link + expected = [ + { + type: 'image', + url: '/img.png', + alt: 'alt text', + linkTo: { + url: 'https://example.net/' + } + } + ] + markdown = '[![alt text](/img.png)](https://example.net/)' + doc = Kramdown::Document.new(markdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 0, doc.warnings.size + end + + def test_convert_entity + expected = [ + { + type: 'paragraph', + text: "\u00a0", + spans: [] + } + ] + markdown = ' ' + assert_equal expected, Kramdown::Document.new(markdown, input: :markdown).to_prismic_v2 + end + + [['mdash', ' ---', ' —'], + ['ndash', ' --', ' –'], + ['hellip', ' ...', ' …'], + ['laquo', ' <<', ' «'], + ['raquo', '>>', '»'], + ['laquo_space', ' << T', ' « T'], + ['raquo_space', ' >>', ' »']].each do |symbol| + define_method "test_convert_typographic_symbols_#{symbol[0]}" do + expected = [ + { + type: 'paragraph', + text: "Hello#{symbol[2]}", + spans: [] + } + ] + markdown = "Hello#{symbol[1]}" + assert_equal expected, Kramdown::Document.new(markdown, input: :kramdown).to_prismic_v2 + end + end + + def test_convert_smart_quote + expected = [ + { + type: 'paragraph', + text: "Test\u2019", + spans: [] + } + ] + markdown = "Test'" + assert_equal expected, Kramdown::Document.new(markdown, input: :kramdown).to_prismic_v2 + end + + def test_convert_inline_code + expected = [ + { + type: 'paragraph', + text: 'Hello code', + spans: [] + } + ] + markdown = 'Hello `code`' + doc = Kramdown::Document.new(markdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end + + def test_convert_br + expected = [ + { + type: 'paragraph', + text: "Test\n", + spans: [] + } + ] + html = '

Test

' + assert_equal expected, Kramdown::Document.new(html, input: :html).to_prismic_v2 + end + + def test_convert_br_in_root_element + expected = [ + { + type: 'paragraph', + text: "Test\n", + spans: [] + } + ] + html = '

Test

' + assert_equal expected, Kramdown::Document.new(html, input: :html).to_prismic_v2 + end + + def test_convert_html_with_no_tags + expected = [ + { + type: 'paragraph', + text: "Test ", + spans: [] + } + ] + html = 'Test' + assert_equal expected, Kramdown::Document.new(html, input: :html).to_prismic_v2 + end + + def test_convert_iframe + expected = [ + { + type: 'embed', + oembed: { + embed_url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', + type: 'link' + } + } + ] + html = '' + doc = Kramdown::Document.new(html, input: :markdown) + assert_equal expected, doc.to_prismic_v2 + end + + def test_convert_link + expected = [ + { + type: 'paragraph', + text: 'Test', + spans: [{type: 'hyperlink', data: {url: 'http://example.net', target: '_blank', link_type: 'Web'}, start: 0, end: 4}] + } + ] + html = '
Test' + doc = Kramdown::Document.new(html, input: :markdown) + assert_equal expected, doc.to_prismic_v2 + end + + def test_convert_html + expected = [] + html = '
' + doc = Kramdown::Document.new(html, input: :markdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end + + def test_convert_span_html_strong + expected = [ + { + type: 'paragraph', + text: 'This is a paragraph', + spans: [ + { + type: 'strong', + start: 10, + end: 20 + } + ] + } + ] + html = '

This is a paragraph

' + doc = Kramdown::Document.new(html, input: :html) + assert_equal expected, doc.to_prismic_v2 + assert_equal 0, doc.warnings.size + end + + def test_convert_span_html_br + expected = [ + { + type: 'paragraph', + text: "\n", + spans: [] + } + ] + html = '
' + doc = Kramdown::Document.new(html, input: :markdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 0, doc.warnings.size + end + + def test_convert_span_html_unknown + expected = [ + { + type: 'paragraph', + text: 'This is a ', + spans: [] + } + ] + html = '

This is a

detail

' + doc = Kramdown::Document.new(html, input: :html) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + assert_equal "translating html element 'details' is not supported", doc.warnings.first + end + + def test_convert_table + expected = [] + markdown = '| First cell|Second cell|Third cell|' + doc = Kramdown::Document.new(markdown, input: :kramdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end + + def test_convert_definition + expected = [] + markdown = "kramdown\n: A Markdown-superset converter" + doc = Kramdown::Document.new(markdown, input: :kramdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end + + def test_convert_math + expected = [] + markdown = '$$ 5 + 5 $$' + doc = Kramdown::Document.new(markdown, input: :kramdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end + + def test_convert_footnote + expected = [ + { + type: 'paragraph', + text: 'test', + spans: [] + } + ] + markdown = "test[^1]\n\n[^1]: test" + doc = Kramdown::Document.new(markdown, input: :kramdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end + + def test_convert_abbreviation + expected = [ + { + type: 'paragraph', + text: 'HTML', + spans: [] + } + ] + markdown = "HTML\n\n*[HTML]: test" + doc = Kramdown::Document.new(markdown, input: :kramdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end + + def test_convert_xml_comment + expected = [] + markdown = "" + doc = Kramdown::Document.new(markdown, input: :kramdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end + + def test_convert_span_xml_comment + expected = [ + { + type: 'paragraph', + text: 'test test', + spans: [] + } + ] + markdown = "test test" + doc = Kramdown::Document.new(markdown, input: :kramdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end + + def test_convert_comment + expected = [] + markdown = "{::comment}\nComment\n{:/comment}" + doc = Kramdown::Document.new(markdown, input: :kramdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end + + def test_convert_raw + expected = [] + markdown = "{::nomarkdown}\nComment\n{:/nomarkdown}" + doc = Kramdown::Document.new(markdown, input: :kramdown) + assert_equal expected, doc.to_prismic_v2 + assert_equal 1, doc.warnings.size + end +end diff --git a/test/fixtures/import-api.json b/test/fixtures/import-api.json new file mode 100644 index 0000000..d0454cf --- /dev/null +++ b/test/fixtures/import-api.json @@ -0,0 +1,195 @@ +[ + { + "type": "heading1", + "content": { + "text": "Herp Derp", + "spans": [] + } + }, + { + "type": "heading2", + "content": { + "text": "Hurr Durr", + "spans": [] + } + }, + { + "type": "paragraph", + "content": { + "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque ut bibendum purus. Nulla vel porttitor felis. Donec pellentesque egestas vulputate. Ut libero elit, condimentum eu nunc ac, tincidunt gravida velit. Quisque eu sodales nisi. Quisque aliquam laoreet ullamcorper. Donec vestibulum purus ornare velit ullamcorper eleifend. Interdum et malesuada fames ac ante ipsum primis in faucibus. Curabitur dictum venenatis mauris at aliquet. Etiam iaculis varius elit, ac blandit magna dapibus vel. Ut consectetur venenatis lectus, eu varius dui eleifend eu. Vestibulum urna tortor, bibendum a lacus nec, aliquam commodo augue. Nam ac dictum augue.", + "spans": [ + { + "type": "em", + "start": 28, + "end": 50 + }, + { + "type": "em", + "start": 117, + "end": 147 + }, + { + "type": "hyperlink", + "start": 0, + "end": 26, + "data": { + "url": "https://en.wikipedia.org/wiki/Lorem_ipsum" + } + }, + { + "type": "strong", + "start": 6, + "end": 17 + }, + { + "type": "strong", + "start": 130, + "end": 137 + } + ] + } + }, + { + "type": "paragraph", + "content": { + "text": "Donec interdum semper mollis. Ut tincidunt, lectus eu finibus ultrices, nisi quam fermentum nulla, sit amet pharetra quam ante et mi. Maecenas aliquet erat in sodales fringilla. Aliquam pharetra urna eu lacus dignissim dapibus. Curabitur venenatis libero sed sem dignissim ultrices. Nunc tempor pretium bibendum. Proin sagittis libero vitae lobortis vestibulum. Aenean non lacus purus. Nunc facilisis luctus diam, id consequat nunc viverra in. Nunc odio orci, cursus mollis elit sit amet, eleifend placerat velit. Suspendisse eget laoreet tortor. Integer hendrerit velit lacus, a vestibulum nisl aliquet vitae. Integer nec ligula hendrerit, posuere lectus ut, ultrices arcu. Praesent dui sem, pretium nec euismod nec, tempor ac massa. Morbi ut accumsan neque, non fermentum dui.", + "spans": [] + } + }, + { + "type": "heading2", + "content": { + "text": "Ayyy lmaoo", + "spans": [] + } + }, + { + "type": "paragraph", + "content": { + "text": "Pellentesque luctus nunc eget purus bibendum pulvinar. Vestibulum vitae erat at est rutrum tristique at non sapien. Curabitur elit ex, aliquam vel placerat id, molestie et dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam lobortis tempor quam at laoreet. Integer non ullamcorper nulla. Vivamus pharetra dolor ut urna lacinia malesuada. Duis leo justo, sollicitudin eu metus ornare, feugiat molestie nulla. Aenean finibus laoreet dolor eu tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin hendrerit semper orci, a accumsan turpis dictum ac. Fusce dolor sapien, consequat ut elit nec, imperdiet congue ante.", + "spans": [] + } + }, + { + "type": "heading2", + "content": { + "text": "UwU", + "spans": [] + } + }, + { + "type": "heading3", + "content": { + "text": "Smol", + "spans": [] + } + }, + { + "type": "heading4", + "content": { + "text": "Smoller", + "spans": [] + } + }, + { + "type": "heading5", + "content": { + "text": "Smollerer", + "spans": [] + } + }, + { + "type": "heading6", + "content": { + "text": "Smollest", + "spans": [] + } + }, + { + "type": "list-item", + "content": { + "text": "hurr", + "spans": [] + } + }, + { + "type": "list-item", + "content": { + "text": "durr", + "spans": [] + } + }, + { + "type": "list-item", + "content": { + "text": "herp", + "spans": [] + } + }, + { + "type": "list-item", + "content": { + "text": "derp", + "spans": [] + } + }, + { + "type": "o-list-item", + "content": { + "text": "ayyy", + "spans": [] + } + }, + { + "type": "o-list-item", + "content": { + "text": "lmaooo", + "spans": [] + } + }, + { + "type": "o-list-item", + "content": { + "text": "???", + "spans": [] + } + }, + { + "type": "o-list-item", + "content": { + "text": "PROFIT!", + "spans": [] + } + }, + { + "type": "preformatted", + "content": { + "text": "fac = foldr (*) 1 . enumFromTo 1", + "spans": [] + } + }, + { + "type": "image", + "content": { + "text": "", + "spans": [] + }, + "data": { + "origin": { + "url": "https://example.com" + }, + "alt": "QQ most cute" + } + }, + { + "type": "embed", + "content": { + "text": "", + "spans": [] + }, + "data": { + "embed_url": "https://www.youtube.com/watch?v=V265GNh_vEI", + "type": "link" + } + } +] \ No newline at end of file diff --git a/test/fixtures/markdown.md b/test/fixtures/markdown.md new file mode 100644 index 0000000..c8dc373 --- /dev/null +++ b/test/fixtures/markdown.md @@ -0,0 +1,70 @@ +# Herp Derp + +## Hurr Durr + +[Lorem **ipsum dolor** sit amet][1], *consectetur adipiscing* elit. +Quisque ut bibendum purus. Nulla vel porttitor felis. Donec +*pellentesque **egestas** vulputate*. Ut libero elit, condimentum eu +nunc ac, tincidunt gravida velit. Quisque eu sodales nisi. Quisque +aliquam laoreet ullamcorper. Donec vestibulum purus ornare velit +ullamcorper eleifend. Interdum et malesuada fames ac ante ipsum primis +in faucibus. Curabitur dictum venenatis mauris at aliquet. Etiam iaculis +varius elit, ac blandit magna dapibus vel. Ut consectetur venenatis +lectus, eu varius dui eleifend eu. Vestibulum urna tortor, bibendum a +lacus nec, aliquam commodo augue. Nam ac dictum augue. + +Donec interdum semper mollis. Ut tincidunt, lectus eu finibus ultrices, +nisi quam fermentum nulla, sit amet pharetra quam ante et mi. Maecenas +aliquet erat in sodales fringilla. Aliquam pharetra urna eu lacus +dignissim dapibus. Curabitur venenatis libero sed sem dignissim +ultrices. Nunc tempor pretium bibendum. Proin sagittis libero vitae +lobortis vestibulum. Aenean non lacus purus. Nunc facilisis luctus diam, +id consequat nunc viverra in. Nunc odio orci, cursus mollis elit sit +amet, eleifend placerat velit. Suspendisse eget laoreet tortor. Integer +hendrerit velit lacus, a vestibulum nisl aliquet vitae. Integer nec +ligula hendrerit, posuere lectus ut, ultrices arcu. Praesent dui sem, +pretium nec euismod nec, tempor ac massa. Morbi ut accumsan neque, non +fermentum dui. + +## Ayyy lmaoo + +Pellentesque luctus nunc eget purus bibendum pulvinar. Vestibulum vitae +erat at est rutrum tristique at non sapien. Curabitur elit ex, aliquam +vel placerat id, molestie et dolor. Class aptent taciti sociosqu ad +litora torquent per conubia nostra, per inceptos himenaeos. Nam lobortis +tempor quam at laoreet. Integer non ullamcorper nulla. Vivamus pharetra +dolor ut urna lacinia malesuada. Duis leo justo, sollicitudin eu metus +ornare, feugiat molestie nulla. Aenean finibus laoreet dolor eu +tincidunt. Pellentesque habitant morbi tristique senectus et netus et +malesuada fames ac turpis egestas. Proin hendrerit semper orci, a +accumsan turpis dictum ac. Fusce dolor sapien, consequat ut elit nec, +imperdiet congue ante. + +## UwU + +### Smol + +#### Smoller + +##### Smollerer + +###### Smollest + +* hurr +* durr +* herp +* derp + +1. ayyy +2. lmaooo +3. ??? +4. PROFIT! + +> fac = foldr (\*) 1 . enumFromTo 1 + +![QQ most cute](https://example.com) + + + + +[1]: https://en.wikipedia.org/wiki/Lorem_ipsum diff --git a/test/fixtures/migration-api.json b/test/fixtures/migration-api.json new file mode 100644 index 0000000..a658524 --- /dev/null +++ b/test/fixtures/migration-api.json @@ -0,0 +1,146 @@ +[ + { + "type": "heading1", + "text": "Herp Derp", + "spans": [] + }, + { + "type": "heading2", + "text": "Hurr Durr", + "spans": [] + }, + { + "type": "paragraph", + "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque ut bibendum purus. Nulla vel porttitor felis. Donec pellentesque egestas vulputate. Ut libero elit, condimentum eu nunc ac, tincidunt gravida velit. Quisque eu sodales nisi. Quisque aliquam laoreet ullamcorper. Donec vestibulum purus ornare velit ullamcorper eleifend. Interdum et malesuada fames ac ante ipsum primis in faucibus. Curabitur dictum venenatis mauris at aliquet. Etiam iaculis varius elit, ac blandit magna dapibus vel. Ut consectetur venenatis lectus, eu varius dui eleifend eu. Vestibulum urna tortor, bibendum a lacus nec, aliquam commodo augue. Nam ac dictum augue.", + "spans": [ + { + "type": "em", + "start": 28, + "end": 50 + }, + { + "type": "em", + "start": 117, + "end": 147 + }, + { + "type": "hyperlink", + "start": 0, + "end": 26, + "data": { + "url": "https://en.wikipedia.org/wiki/Lorem_ipsum", + "link_type": "Web" + } + }, + { + "type": "strong", + "start": 6, + "end": 17 + }, + { + "type": "strong", + "start": 130, + "end": 137 + } + ] + }, + { + "type": "paragraph", + "text": "Donec interdum semper mollis. Ut tincidunt, lectus eu finibus ultrices, nisi quam fermentum nulla, sit amet pharetra quam ante et mi. Maecenas aliquet erat in sodales fringilla. Aliquam pharetra urna eu lacus dignissim dapibus. Curabitur venenatis libero sed sem dignissim ultrices. Nunc tempor pretium bibendum. Proin sagittis libero vitae lobortis vestibulum. Aenean non lacus purus. Nunc facilisis luctus diam, id consequat nunc viverra in. Nunc odio orci, cursus mollis elit sit amet, eleifend placerat velit. Suspendisse eget laoreet tortor. Integer hendrerit velit lacus, a vestibulum nisl aliquet vitae. Integer nec ligula hendrerit, posuere lectus ut, ultrices arcu. Praesent dui sem, pretium nec euismod nec, tempor ac massa. Morbi ut accumsan neque, non fermentum dui.", + "spans": [] + }, + { + "type": "heading2", + "text": "Ayyy lmaoo", + "spans": [] + }, + { + "type": "paragraph", + "text": "Pellentesque luctus nunc eget purus bibendum pulvinar. Vestibulum vitae erat at est rutrum tristique at non sapien. Curabitur elit ex, aliquam vel placerat id, molestie et dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam lobortis tempor quam at laoreet. Integer non ullamcorper nulla. Vivamus pharetra dolor ut urna lacinia malesuada. Duis leo justo, sollicitudin eu metus ornare, feugiat molestie nulla. Aenean finibus laoreet dolor eu tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin hendrerit semper orci, a accumsan turpis dictum ac. Fusce dolor sapien, consequat ut elit nec, imperdiet congue ante.", + "spans": [] + }, + { + "type": "heading2", + "text": "UwU", + "spans": [] + }, + { + "type": "heading3", + "text": "Smol", + "spans": [] + }, + { + "type": "heading4", + "text": "Smoller", + "spans": [] + }, + { + "type": "heading5", + "text": "Smollerer", + "spans": [] + }, + { + "type": "heading6", + "text": "Smollest", + "spans": [] + }, + { + "type": "list-item", + "text": "hurr", + "spans": [] + }, + { + "type": "list-item", + "text": "durr", + "spans": [] + }, + { + "type": "list-item", + "text": "herp", + "spans": [] + }, + { + "type": "list-item", + "text": "derp", + "spans": [] + }, + { + "type": "o-list-item", + "text": "ayyy", + "spans": [] + }, + { + "type": "o-list-item", + "text": "lmaooo", + "spans": [] + }, + { + "type": "o-list-item", + "text": "???", + "spans": [] + }, + { + "type": "o-list-item", + "text": "PROFIT!", + "spans": [] + }, + { + "type": "preformatted", + "text": "fac = foldr (*) 1 . enumFromTo 1", + "spans": [] + }, + { + "type": "image", + "origin": { + "url": "https://example.com" + }, + "alt": "QQ most cute" + }, + { + "type": "embed", + "oembed": { + "embed_url": "https://www.youtube.com/watch?v=V265GNh_vEI", + "type": "link" + } + } +] \ No newline at end of file diff --git a/test/fixtures/web.html b/test/fixtures/web.html new file mode 100644 index 0000000..4932d30 --- /dev/null +++ b/test/fixtures/web.html @@ -0,0 +1,31 @@ +

Herp Derp

+

Hurr Durr

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque ut bibendum purus. Nulla vel porttitor felis. Donec pellentesque egestas vulputate. Ut libero elit, condimentum eu nunc ac, tincidunt gravida velit. Quisque eu sodales nisi. Quisque aliquam laoreet ullamcorper. Donec vestibulum purus ornare velit ullamcorper eleifend. Interdum et malesuada fames ac ante ipsum primis in faucibus. Curabitur dictum venenatis mauris at aliquet. Etiam iaculis varius elit, ac blandit magna dapibus vel. Ut consectetur venenatis lectus, eu varius dui eleifend eu. Vestibulum urna tortor, bibendum a lacus nec, aliquam commodo augue. Nam ac dictum augue.

+

Donec interdum semper mollis. Ut tincidunt, lectus eu finibus ultrices, nisi quam fermentum nulla, sit amet pharetra quam ante et mi. Maecenas aliquet erat in sodales fringilla. Aliquam pharetra urna eu lacus dignissim dapibus. Curabitur venenatis libero sed sem dignissim ultrices. Nunc tempor pretium bibendum. Proin sagittis libero vitae lobortis vestibulum. Aenean non lacus purus. Nunc facilisis luctus diam, id consequat nunc viverra in. Nunc odio orci, cursus mollis elit sit amet, eleifend placerat velit. Suspendisse eget laoreet tortor. Integer hendrerit velit lacus, a vestibulum nisl aliquet vitae. Integer nec ligula hendrerit, posuere lectus ut, ultrices arcu. Praesent dui sem, pretium nec euismod nec, tempor ac massa. Morbi ut accumsan neque, non fermentum dui.

+

Ayyy lmaoo

+

Pellentesque luctus nunc eget purus bibendum pulvinar. Vestibulum vitae erat at est rutrum tristique at non sapien. Curabitur elit ex, aliquam vel placerat id, molestie et dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam lobortis tempor quam at laoreet. Integer non ullamcorper nulla. Vivamus pharetra dolor ut urna lacinia malesuada. Duis leo justo, sollicitudin eu metus ornare, feugiat molestie nulla. Aenean finibus laoreet dolor eu tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin hendrerit semper orci, a accumsan turpis dictum ac. Fusce dolor sapien, consequat ut elit nec, imperdiet congue ante.

+

UwU

+

Smol

+

Smoller

+
Smollerer
+
Smollest
+ +
    +
  1. ayyy
  2. +
  3. lmaooo
  4. +
  5. ???
  6. +
  7. PROFIT!
  8. +
+
+fac = foldr (*) 1 . enumFromTo 1 + + + +
+

QQ most cute

+ diff --git a/test/parser_test.rb b/test/parser/import_api_test.rb similarity index 99% rename from test/parser_test.rb rename to test/parser/import_api_test.rb index 4b87806..83e8a2a 100644 --- a/test/parser_test.rb +++ b/test/parser/import_api_test.rb @@ -3,7 +3,7 @@ require 'minitest/autorun' require 'kramdown-prismic' -class KramdownPrismicParserTest < Minitest::Test +class KramdownPrismicImportApiParserTest < Minitest::Test 6.times do |heading| define_method "test_parse_heading_#{heading}" do prismic = [ diff --git a/test/parser/migration_api_test.rb b/test/parser/migration_api_test.rb new file mode 100644 index 0000000..14fc1b9 --- /dev/null +++ b/test/parser/migration_api_test.rb @@ -0,0 +1,273 @@ +# frozen_string_literal: true + +require 'minitest/autorun' +require 'kramdown-prismic' + +class KramdownPrismicMigrationApiParserTest < Minitest::Test + 6.times do |heading| + define_method "test_parse_heading_#{heading}" do + prismic = [ + { + type: "heading#{heading + 1}", + text: 'This is the document title', + spans: [] + } + ] + expected = "#{'#' * (heading + 1)} This is the document title\n\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end + end + + def test_parse_paragraph + prismic = [ + { + type: 'paragraph', + text: 'This is a paragraph', + spans: [] + } + ] + expected = "This is a paragraph\n\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end + + def test_parse_paragraph_with_spans + prismic = [ + { + type: 'paragraph', + text: 'This is a paragraph', + spans: [ + { + type: 'em', + start: 0, + end: 4 + } + ] + } + ] + expected = "*This* is a paragraph\n\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end + + def test_parse_paragraph_with_multiple_spans + prismic = [ + { + type: 'paragraph', + text: 'This is a paragraph', + spans: [ + { + type: 'em', + start: 0, + end: 4 + }, + { + type: 'strong', + start: 5, + end: 7 + } + ] + } + ] + expected = "*This* **is** a paragraph\n\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end + + def test_parse_paragraph_with_link + prismic = [ + { + type: 'paragraph', + text: 'This is a paragraph', + spans: [ + { + type: 'hyperlink', + start: 0, + end: 19, + data: { + url: 'https://prismic.io', + link_type: 'Web' + } + } + ] + } + ] + expected = "[This is a paragraph][1]\n\n\n\n[1]: https://prismic.io\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end + + def test_parse_paragraph_with_nested_spans + prismic = [ + { + type: 'paragraph', + text: 'This is a paragraph', + spans: [ + { + type: 'em', + start: 0, + end: 4 + }, + { + type: 'hyperlink', + start: 0, + end: 19, + data: { + url: 'https://prismic.io' + } + } + ] + } + ] + expected = "[*This* is a paragraph][1]\n\n\n\n[1]: https://prismic.io\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end + + def test_parse_list_item + prismic = [ + { + type: 'list-item', + text: 'Hello', + spans: [] + }, + { + type: 'list-item', + text: 'World', + spans: [] + } + ] + expected = "* Hello\n* World\n\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end + + def test_parse_list_item_and_spans + prismic = [ + { + type: 'list-item', + text: 'Hello', + spans: [ + { + type: 'em', + start: 0, + end: 5 + } + ] + }, + { + type: 'list-item', + text: 'World', + spans: [] + } + ] + expected = "* *Hello*\n* World\n\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end + + def test_parse_o_list_item + prismic = [ + { + type: 'o-list-item', + text: 'Hello', + spans: [] + }, + { + type: 'o-list-item', + text: 'World', + spans: [] + } + ] + expected = "1. Hello\n2. World\n\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end + + def test_parse_o_list_item_and_list_item + prismic = [ + { + type: 'o-list-item', + text: 'Hello', + spans: [] + }, + { + type: 'o-list-item', + text: 'World', + spans: [] + }, + { + type: 'list-item', + text: 'Test', + spans: [] + }, + { + type: 'list-item', + text: 'roger', + spans: [] + } + ] + expected = "1. Hello\n2. World\n\n* Test\n* roger\n\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end + + def test_parse_image + prismic = [ + { + type: 'image', + url: '/img.png', + alt: 'alt text' + } + ] + expected = "![alt text](/img.png)\n\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end + + # TODO: should probably be unsupported + def test_parse_img_with_link + prismic = [ + { + type: 'image', + url: '/img.png', + alt: 'alt text', + linkTo: { + url: 'https://example.net/' + } + } + ] + expected = "[![alt text](/img.png)][1]\n\n\n\n[1]: https://example.net/\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end + + def test_parse_preformatted + prismic = [ + { + type: 'preformatted', + text: "This is a pre block\n", + spans: [] + } + ] + expected = "> This is a pre block \n\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end + + def test_parse_embed + prismic = [ + { + type: 'embed', + oembed: { + type: 'video', + embed_url: 'https://www.youtube.com/watch?v=y6y_4_b6RS8' + }, + } + ] + expected = "\n" + doc = Kramdown::Document.new(prismic, input: :prismic_v2) + assert_equal expected, doc.to_kramdown + end +end