diff --git a/README.md b/README.md index c223146d..02a46ace 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,31 @@ kramdown: directory: path/to/themes ``` +### Dimensions and Styling + +It's possible to customize the dimensions of the diagram by providing the +`width` and `height` configuration keys. It's also possible to add arbitrary +styling with the `style` key. + +```yaml +kramdown: + plantuml: + width: 200px + height: 100px + style: "border: 1px solid black" +``` + +To remove the `width`, `height` and `style` attributes from the `` +element, set the key's value to `none`. + +```yaml +kramdown: + plantuml: + width: none + height: none + style: none +``` + ### Errors By default, `kramdown-plantuml` will raise an error and crash if something goes @@ -199,7 +224,7 @@ agreement][cla]. [codacy]: https://www.codacy.com/gh/SwedbankPay/kramdown-plantuml/dashboard?utm_source=github.com&utm_medium=referral&utm_content=SwedbankPay/kramdown-plantuml&utm_campaign=Badge_Grade [codecov-badge]: https://codecov.io/gh/SwedbankPay/kramdown-plantuml/branch/main/graph/badge.svg?token=U3QJLVG3HY [codecov]: https://codecov.io/gh/SwedbankPay/kramdown-plantuml/ -[diagram-svg]: ./spec/examples/diagram.svg +[diagram-svg]: ./spec/examples/network-diagram.svg [fenced]: https://www.markdownguide.org/extended-syntax/#syntax-highlighting [fork]: https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/fork-a-repo [gem-badge]: https://badge.fury.io/rb/kramdown-plantuml.svg diff --git a/kramdown-plantuml.gemspec b/kramdown-plantuml.gemspec index 7260872c..c86819da 100644 --- a/kramdown-plantuml.gemspec +++ b/kramdown-plantuml.gemspec @@ -42,6 +42,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rspec', '~> 3.2' + spec.add_development_dependency 'rspec-html-matchers', '>= 0.9' spec.add_development_dependency 'rspec-its', '~> 1.3' spec.add_development_dependency 'rubocop', '~> 1.12' spec.add_development_dependency 'rubocop-rake', '~> 0.6' diff --git a/lib/kramdown-plantuml/executor.rb b/lib/kramdown-plantuml/executor.rb index 59e3bb36..575c4e76 100644 --- a/lib/kramdown-plantuml/executor.rb +++ b/lib/kramdown-plantuml/executor.rb @@ -26,7 +26,7 @@ def initialize def execute(diagram) raise ArgumentError, 'diagram cannot be nil' if diagram.nil? - raise ArgumentError, "diagram must be a #{Diagram}" unless diagram.is_a?(Diagram) + raise ArgumentError, "diagram must be a #{PlantUmlDiagram}" unless diagram.is_a?(PlantUmlDiagram) cmd = "java -Djava.awt.headless=true -jar #{@plantuml_jar_file} -tsvg -failfast -pipe #{debug_args}" diff --git a/lib/kramdown-plantuml/jekyll_page_processor.rb b/lib/kramdown-plantuml/jekyll_page_processor.rb index 23a3d092..14aa0e13 100644 --- a/lib/kramdown-plantuml/jekyll_page_processor.rb +++ b/lib/kramdown-plantuml/jekyll_page_processor.rb @@ -91,8 +91,8 @@ def replace_needle(json) def decode_and_convert(hash, options) encoded_plantuml = hash['plantuml'] plantuml = HTMLEntities.new.decode encoded_plantuml - diagram = ::Kramdown::PlantUml::Diagram.new(plantuml, options) - diagram.convert_to_svg + diagram = ::Kramdown::PlantUml::PlantUmlDiagram.new(plantuml, options) + diagram.svg end def logger diff --git a/lib/kramdown-plantuml/none_s.rb b/lib/kramdown-plantuml/none_s.rb new file mode 100644 index 00000000..7ff444ef --- /dev/null +++ b/lib/kramdown-plantuml/none_s.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +# Ruby's Object class. +class Object + # Performs a case insensitive, trimmed comparison of the Object and the + # String 'none' and Symbol :none. Returns true if the comparison is true, + # otherwise false. + # + # @return [Boolean] True if the Object is equal to 'none' or :none, + # otherwise false. + def none_s? + return false if nil? + return true if self == :none + + to_s.strip.casecmp?('none') + end +end diff --git a/lib/kramdown-plantuml/options.rb b/lib/kramdown-plantuml/options.rb index bd9ae51c..7210b373 100644 --- a/lib/kramdown-plantuml/options.rb +++ b/lib/kramdown-plantuml/options.rb @@ -1,18 +1,20 @@ # frozen_string_literal: true +require_relative 'none_s' require_relative 'log_wrapper' module Kramdown module PlantUml # Options for PlantUML processing class Options - attr_reader :theme_name, :theme_directory + attr_reader :theme_name, :theme_directory, :width, :height, :style def initialize(options_hash = {}) @logger = LogWrapper.init @options = massage(options_hash) || {} @raise_errors = extract_raise_errors(@options) extract_theme_options(@options) + extract_style_options(@options) end def raise_errors? @@ -64,6 +66,23 @@ def extract_raise_errors(options) boolean(raise_errors, true) end + def extract_style_options(options) + return if options.nil? || options.empty? + + set_instance_property(:width, options) + set_instance_property(:height, options) + set_instance_property(:style, options) + end + + def set_instance_property(name, options) + return unless options.key? name + + value = options[name] + value = :none if value.none_s? + prop_name = "@#{name}".to_sym + instance_variable_set(prop_name, value) + end + def massage(options_hash) if options_hash.nil? || !options_hash.is_a?(Hash) || options_hash.empty? @logger.debug 'No options provided' diff --git a/lib/kramdown-plantuml/diagram.rb b/lib/kramdown-plantuml/plantuml_diagram.rb similarity index 66% rename from lib/kramdown-plantuml/diagram.rb rename to lib/kramdown-plantuml/plantuml_diagram.rb index 8a9b29f2..cd70851b 100644 --- a/lib/kramdown-plantuml/diagram.rb +++ b/lib/kramdown-plantuml/plantuml_diagram.rb @@ -1,17 +1,18 @@ # frozen_string_literal: true -require_relative 'version' -require_relative 'theme' +require_relative 'executor' +require_relative 'log_wrapper' require_relative 'options' require_relative 'plantuml_error' -require_relative 'log_wrapper' -require_relative 'executor' +require_relative 'svg_diagram' +require_relative 'theme' +require_relative 'version' module Kramdown module PlantUml # Represents a PlantUML diagram that can be converted to SVG. - class Diagram - attr_reader :theme, :plantuml, :result + class PlantUmlDiagram + attr_reader :theme, :plantuml, :result, :options def initialize(plantuml, options) raise ArgumentError, 'options cannot be nil' if options.nil? @@ -25,15 +26,13 @@ def initialize(plantuml, options) @logger.warn 'PlantUML diagram is empty' if @plantuml.nil? || @plantuml.empty? end - def convert_to_svg - return @svg unless @svg.nil? - return @plantuml if @plantuml.nil? || @plantuml.empty? + def svg + return @svg_diagram unless @svg_diagram.nil? @plantuml = @theme.apply(@plantuml) log(plantuml) @result = @executor.execute(self) - @result.validate - @svg = wrap(@result.without_xml_prologue) + @svg_diagram = SvgDiagram.new(@result) rescue StandardError => e raise e if @options.raise_errors? @@ -42,16 +41,6 @@ def convert_to_svg private - def wrap(svg) - theme_class = @theme.name ? "theme-#{@theme.name}" : '' - class_name = "plantuml #{theme_class}".strip - - wrapper_element_start = "
" - wrapper_element_end = '
' - - "#{wrapper_element_start}#{svg}#{wrapper_element_end}" - end - def log(plantuml) @logger.debug 'PlantUML converting diagram:' @logger.debug_multiline plantuml diff --git a/lib/kramdown-plantuml/plantuml_error.rb b/lib/kramdown-plantuml/plantuml_error.rb index 1cc8adeb..cc24beb9 100644 --- a/lib/kramdown-plantuml/plantuml_error.rb +++ b/lib/kramdown-plantuml/plantuml_error.rb @@ -31,11 +31,11 @@ def create_message(result) end def header(result) - if theme_not_found?(result) && !result.diagram.nil? && !result.diagram.theme.nil? + if theme_not_found?(result) && !result.plantuml_diagram.nil? && !result.plantuml_diagram.theme.nil? return <<~HEADER Conversion of the following PlantUML result failed because the - theme '#{result.diagram.theme.name}' can't be found in the directory - '#{result.diagram.theme.directory}': + theme '#{result.plantuml_diagram.theme.name}' can't be found in the directory + '#{result.plantuml_diagram.theme.directory}': HEADER end @@ -50,9 +50,9 @@ def theme_not_found?(result) end def plantuml(result) - return nil if result.nil? || result.diagram.nil? + return nil if result.nil? || result.plantuml_diagram.nil? - result.diagram.plantuml + result.plantuml_diagram.plantuml end def result(result) diff --git a/lib/kramdown-plantuml/plantuml_result.rb b/lib/kramdown-plantuml/plantuml_result.rb index 5108b930..779b2eed 100644 --- a/lib/kramdown-plantuml/plantuml_result.rb +++ b/lib/kramdown-plantuml/plantuml_result.rb @@ -2,46 +2,29 @@ require_relative 'log_wrapper' require_relative 'plantuml_error' -require_relative 'diagram' +require_relative 'svg_diagram' module Kramdown module PlantUml # Executes the PlantUML Java application. class PlantUmlResult - attr_reader :diagram, :stdout, :stderr, :exitcode + attr_reader :plantuml_diagram, :stdout, :stderr, :exitcode - def initialize(diagram, stdout, stderr, exitcode) - raise ArgumentError, 'diagram cannot be nil' if diagram.nil? - raise ArgumentError, "diagram must be a #{Diagram}" unless diagram.is_a?(Diagram) + def initialize(plantuml_diagram, stdout, stderr, exitcode) + raise ArgumentError, 'diagram cannot be nil' if plantuml_diagram.nil? + raise ArgumentError, "diagram must be a #{PlantUmlDiagram}" unless plantuml_diagram.is_a?(PlantUmlDiagram) raise ArgumentError, 'exitcode cannot be nil' if exitcode.nil? raise ArgumentError, "exitcode must be a #{Integer}" unless exitcode.is_a?(Integer) - @diagram = diagram + @plantuml_diagram = plantuml_diagram @stdout = stdout @stderr = stderr @exitcode = exitcode @logger = LogWrapper.init end - def without_xml_prologue - return @stdout if @stdout.nil? || @stdout.empty? - - xml_prologue_start = '' - - start_index = @stdout.index(xml_prologue_start) - - return @stdout if start_index.nil? - - end_index = @stdout.index(xml_prologue_end, xml_prologue_start.length) - - return @stdout if end_index.nil? - - end_index += xml_prologue_end.length - - @stdout.slice! start_index, end_index - - @stdout + def svg_diagram + @plantuml_diagram.svg end def valid? @@ -53,7 +36,7 @@ def valid? @stderr.include?('CoreText note:') end - def validate + def validate! raise PlantUmlError, self unless valid? return if @stderr.nil? || @stderr.empty? diff --git a/lib/kramdown-plantuml/style_builder.rb b/lib/kramdown-plantuml/style_builder.rb new file mode 100644 index 00000000..4b798aaa --- /dev/null +++ b/lib/kramdown-plantuml/style_builder.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require_relative 'none_s' + +module Kramdown + module PlantUml + # Builds a CSS style string from a hash of style properties. + class StyleBuilder + def initialize + @hash = {} + end + + def []=(key, value) + return if key.nil? + + case key + when :width, :height + if none(value) + @hash.delete(key) + else + @hash[key] = value + end + else + self.style = value + end + end + + def to_s + @hash.sort_by { |key, _| key }.map { |key, value| "#{key}:#{value}" }.join(';') + end + + private + + def none(value) + return true if value.nil? + + value_s = value.to_s.strip + + return true if value_s.empty? || value.none_s? + + false + end + + def style=(style) + return if style.nil? || style.strip.empty? + + style.split(';').each do |pair| + key, value = pair.split(':') + key = key.strip.to_sym + value = value.strip + @hash[key] = value + end + end + end + end +end diff --git a/lib/kramdown-plantuml/svg_diagram.rb b/lib/kramdown-plantuml/svg_diagram.rb new file mode 100644 index 00000000..a50be932 --- /dev/null +++ b/lib/kramdown-plantuml/svg_diagram.rb @@ -0,0 +1,115 @@ +# frozen_string_literal: true + +require 'rexml/document' +require_relative 'none_s' +require_relative 'style_builder' +require_relative 'plantuml_diagram' + +module Kramdown + module PlantUml + # A diagram in SVG format. + class SvgDiagram + def initialize(plantuml_result) + raise ArgumentError, 'plantuml_result cannot be nil' if plantuml_result.nil? + raise ArgumentError, "plantuml_result must be a #{PlantUmlResult}" unless plantuml_result.is_a?(PlantUmlResult) + + plantuml_result.validate! + svg = plantuml_result.stdout + @doc = REXML::Document.new svg + @source = plantuml_result.plantuml_diagram + @style_builder = StyleBuilder.new + transfer_options(plantuml_result) + end + + def to_s + return '' if @doc.root.nil? + + wrapper_doc = REXML::Document.new + wrapper_doc.context[:attribute_quote] = :quote + wrapper_element = REXML::Element.new('div').tap do |div| + div.add_attribute 'class', wrapper_class_name + div.add_element @doc.root + end + + wrapper_doc.add_element wrapper_element + wrapper_doc.to_s + end + + def width + get_xml_attribute_value(:width) + end + + def height + get_xml_attribute_value(:height) + end + + def style + get_xml_attribute_value(:style) + end + + private + + def wrapper_class_name + theme_class = @source.theme.name ? "theme-#{@source.theme.name}" : '' + "plantuml #{theme_class}".strip + end + + def get_xml_attribute_value(attribute_name) + return nil if @doc.root.nil? + + name = attribute_name.to_s + value = @doc.root.attributes[name] + value.nil? || value.none_s? ? :none : value + end + + def manipulate_xml_attribute(attribute_name, value) + if value.none_s? + remove_xml_attribute(attribute_name) + elsif !value.nil? && value.is_a?(String) && !value.strip.empty? + set_xml_attribute(attribute_name, value) + end + + update_style unless attribute_name == :style || style == :none + end + + def remove_xml_attribute(attribute_name) + @doc.root.attributes.get_attribute(attribute_name.to_s).remove + end + + def set_xml_attribute(attribute_name, value) + name = attribute_name.to_s + @doc.root.attributes[name] = value + @style_builder[attribute_name] = value + end + + def update_style + style = @style_builder.to_s + set_xml_attribute(:style, style) + end + + def transfer_options(plantuml_result) + return if (options = options(plantuml_result)).nil? + + %i[style width height].each do |attribute| + options.public_send(attribute).tap do |option_value| + next if option_value.nil? + + option_value = option_value.to_s.strip + + next if option_value.empty? + + manipulate_xml_attribute(attribute, option_value) + end + end + end + + def options(plantuml_result) + return nil if @doc.root.nil? \ + || plantuml_result.nil? \ + || plantuml_result.plantuml_diagram.nil? + + plantuml_result.plantuml_diagram.options + end + end + end +end diff --git a/lib/kramdown_html.rb b/lib/kramdown_html.rb index a7a40768..09c8d1ae 100644 --- a/lib/kramdown_html.rb +++ b/lib/kramdown_html.rb @@ -5,7 +5,7 @@ require_relative 'kramdown-plantuml/log_wrapper' require_relative 'kramdown-plantuml/plantuml_error' require_relative 'kramdown-plantuml/options' -require_relative 'kramdown-plantuml/diagram' +require_relative 'kramdown-plantuml/plantuml_diagram' require_relative 'kramdown-plantuml/jekyll_provider' module Kramdown @@ -38,8 +38,8 @@ def plantuml?(element) end def convert_plantuml(plantuml, options) - diagram = ::Kramdown::PlantUml::Diagram.new(plantuml, options) - diagram.convert_to_svg + diagram = ::Kramdown::PlantUml::PlantUmlDiagram.new(plantuml, options) + diagram.svg.to_s rescue StandardError => e raise e if options.raise_errors? diff --git a/spec/examples/_config.yml b/spec/examples/_config.yml index 9cba6e78..692aa187 100644 --- a/spec/examples/_config.yml +++ b/spec/examples/_config.yml @@ -1,2 +1 @@ -plugins: - - kramdown-plantuml +plugins: [kramdown-plantuml] diff --git a/spec/examples/_layouts/default.html b/spec/examples/_layouts/default.html new file mode 100644 index 00000000..679ff825 --- /dev/null +++ b/spec/examples/_layouts/default.html @@ -0,0 +1,11 @@ + + + + + + kramdown::plantuml + + + {{ content }} + + diff --git a/spec/examples/index.md b/spec/examples/index.md index 019fe2f2..ff36d5eb 100644 --- a/spec/examples/index.md +++ b/spec/examples/index.md @@ -1,9 +1,12 @@ --- title: Fixture +layout: default --- # This is a fixture +## Network diagram + ```plantuml @startuml Diagram actor client @@ -13,3 +16,129 @@ db -> app app -> client @enduml ``` + +## Sequence diagram + +```plantuml +@startuml "Sequence" + title "Checkout Sequence" + + group Checkin + Payer --> Merchant: Start Checkin + activate Payer + activate Merchant + Merchant --> SwedbankPay: POST /psp/consumers + activate SwedbankPay + SwedbankPay --> Merchant: rel:view-consumer-identification ① + deactivate SwedbankPay + Merchant --> Payer: Show Checkin on Merchant Page + deactivate Merchant + + SwedbankPay <-> Payer: Consumer identification process + deactivate Payer + + activate SwedbankPay + SwedbankPay ->> Merchant: onConsumerIdentified(consumerProfileRef) ④ + deactivate SwedbankPay + activate Merchant + deactivate Merchant + end group + + group#fff #ebf8f2 Payment Menu + Payer -> Merchant: Initiate Purchase + deactivate Payer + Merchant -> SwedbankPay: POST /psp/paymentorders { paymentUrl, consumerProfileRef } + deactivate Merchant + SwedbankPay --> Merchant: rel:view-paymentorder + deactivate SwedbankPay + Merchant --> Payer: Display Payment Menu on Merchant Page + activate Payer + Payer ->> Payer: Initiate Payment Menu Hosted View (open iframe) + Payer --> SwedbankPay: Show Payment UI page in iframe + deactivate Payer + SwedbankPay -> Payer: Do payment logic + deactivate SwedbankPay + Payer ->> SwedbankPay: Do payment logic + deactivate Payer + + opt Consumer perform payment out of iFrame + Payer ->> Payer: Redirect to 3rd party + Payer -> 3rdParty: Redirect to 3rdPartyUrl URL + deactivate Payer + 3rdParty --> Payer: Redirect back to paymentUrl (merchant) + deactivate 3rdParty + Payer ->> Payer: Initiate Payment Menu Hosted View (open iframe) + Payer -> SwedbankPay: Show Payment UI page in iframe + deactivate Payer + end + + SwedbankPay -->> Payer: Payment status + + alt If payment is completed + activate Payer + Payer ->> Payer: Event: onPaymentCompleted + Payer -> Merchant: Check payment status + deactivate Payer + Merchant -> SwedbankPay: GET + deactivate Merchant + SwedbankPay -> Merchant: rel: paid-paymentorder + deactivate SwedbankPay + opt#fff #eee Get PaymentOrder Details (if paid-paymentorder operation exist) + activate Merchant + Merchant -> SwedbankPay: GET rel:paid-paymentorder.href + activate SwedbankPay + SwedbankPay -->> Merchant: Payment Details + deactivate SwedbankPay + deactivate Merchant + end + end + end group + + opt If payment is failed + activate Payer + Payer ->> Payer: Event: OnPaymentFailed + Payer -> Merchant: Check payment status + deactivate Payer + Merchant -> SwedbankPay: GET {paymentorder.id} + deactivate Merchant + SwedbankPay --> Merchant: rel: failed-paymentorder + + deactivate SwedbankPay + opt Get PaymentOrder Details (if failed-paymentorder operation exist) + activate Payer + deactivate Payer + Merchant -> SwedbankPay: GET rel: failed-paymentorder + deactivate Merchant + SwedbankPay -->> Merchant: Payment Details + deactivate SwedbankPay + end + end + + activate Merchant + Merchant --> Payer: Show Purchase complete + opt PaymentOrder Callback (if callbackUrls is set) + activate Payer + deactivate Payer + SwedbankPay ->> Merchant: POST Payment Callback + end + + group Capture + note left of Merchant + Capture here only if the purchased goods don't require shipping. + If shipping is required, perform capture after the goods have + shipped. Should only be used for PaymentInstruments that support + Authorizations. + end note + + Merchant -> Merchant: Capture + activate Merchant + Merchant -> SwedbankPay: GET {paymentorder.id} + activate SwedbankPay + SwedbankPay --> Merchant: paymentorder + Merchant -> SwedbankPay: rel:create-paymentorder-capture + SwedbankPay --> Merchant: Capture status + deactivate SwedbankPay + deactivate Merchant + end group +@enduml +``` diff --git a/spec/examples/diagram.plantuml b/spec/examples/network-diagram.puml similarity index 100% rename from spec/examples/diagram.plantuml rename to spec/examples/network-diagram.puml diff --git a/spec/examples/diagram.svg b/spec/examples/network-diagram.svg similarity index 100% rename from spec/examples/diagram.svg rename to spec/examples/network-diagram.svg diff --git a/spec/executor_spec.rb b/spec/executor_spec.rb index 3db3a2d8..0b892743 100644 --- a/spec/executor_spec.rb +++ b/spec/executor_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false require 'rspec/its' -require 'kramdown-plantuml/diagram' +require 'kramdown-plantuml/plantuml_diagram' Executor = ::Kramdown::PlantUml::Executor @@ -29,8 +29,8 @@ it { expect { subject.execute(nil) }.to raise_error(ArgumentError, 'diagram cannot be nil') } end - context 'diagram is not Diagram' do - it { expect { subject.execute('') }.to raise_error(ArgumentError, "diagram must be a #{Diagram}") } + context 'diagram is not PlantUmlDiagram' do + it { expect { subject.execute('') }.to raise_error(ArgumentError, "diagram must be a #{Kramdown::PlantUml::PlantUmlDiagram}") } end end end diff --git a/spec/jekyll_page_processor_spec.rb b/spec/jekyll_page_processor_spec.rb index a4746179..97d6db98 100644 --- a/spec/jekyll_page_processor_spec.rb +++ b/spec/jekyll_page_processor_spec.rb @@ -4,7 +4,7 @@ require 'kramdown-plantuml/options' require 'kramdown-plantuml/jekyll_page_processor' -Options = Kramdown::PlantUml::Options +Options ||= Kramdown::PlantUml::Options JekyllPageProcessor = ::Kramdown::PlantUml::JekyllPageProcessor describe JekyllPageProcessor do diff --git a/spec/jekyll_provider_spec.rb b/spec/jekyll_provider_spec.rb index e1739875..8af389ae 100644 --- a/spec/jekyll_provider_spec.rb +++ b/spec/jekyll_provider_spec.rb @@ -4,11 +4,11 @@ require 'kramdown-plantuml/options' require 'kramdown-plantuml/jekyll_provider' -Options = Kramdown::PlantUml::Options +Options ||= Kramdown::PlantUml::Options JekyllProvider = ::Kramdown::PlantUml::JekyllProvider describe JekyllProvider do - let (:plantuml_file_contents) { File.read(File.join(__dir__, 'examples', 'diagram.plantuml')) } + let (:plantuml_file_contents) { File.read(File.join(__dir__, 'examples', 'network-diagram.puml')) } let (:plantuml) { nil } let (:options) { Options.new } subject { JekyllProvider } @@ -59,8 +59,13 @@ subject { File.read(File.join(jekyll_destination, 'index.html')) } context 'when plantuml contains HTML entities', :jekyll do - it { is_expected.to match(/
<\/div>/m) } - it { is_expected.to match(/This is a fixture<\/h1>/m) } + it do + is_expected.to have_tag('div', with: { class: 'plantuml' }) do + with_tag('svg') + end + end + + it { is_expected.to have_tag('h1', text: 'This is a fixture') } end end end diff --git a/spec/kramdown_html_spec.rb b/spec/kramdown_html_spec.rb index 1bb874af..7c1bba6e 100644 --- a/spec/kramdown_html_spec.rb +++ b/spec/kramdown_html_spec.rb @@ -8,15 +8,13 @@ let (:options) { { input: 'GFM' } } subject do - diagram = File.read(File.join(__dir__, 'examples', 'diagram.plantuml')) + diagram = File.read(File.join(__dir__, 'examples', 'network-diagram.puml')) document = "```plantuml\n#{diagram}\n```" Kramdown::Document.new(document, options).to_html end context 'clean' do - it { - is_expected.to include('class="plantuml">') - } + it { is_expected.to have_tag('div', with: { class: 'plantuml' }) } end context 'built-in theme' do @@ -31,9 +29,7 @@ } } - it { - is_expected.to include('class="plantuml theme-spacelab">') - } + it { is_expected.to have_tag('div', with: { class: 'plantuml theme-spacelab' }) } it 'has theme metadata', :debug do is_expected.to include("!theme spacelab") @@ -55,9 +51,7 @@ } } - it { - is_expected.to include('class="plantuml theme-c2a3b0">') - } + it { is_expected.to have_tag('div', with: { class: 'plantuml theme-c2a3b0' }) } it 'has theme metadata', :debug do is_expected.to include("!theme c2a3b0 from #{examples_dir}") diff --git a/spec/none_s_spec.rb b/spec/none_s_spec.rb new file mode 100644 index 00000000..42234b10 --- /dev/null +++ b/spec/none_s_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: false + +require 'kramdown-plantuml/none_s' + +describe Object do + describe '#none_s?' do + subject { value.none_s? } + + context 'with invalid values' do + [{}, [], nil, '', ' ', 'a', '0', '1', 'true', 'false', 'nil', '[]', '{}'].each do |v| + context "'#{v}'" do + let (:value) { v } + it { is_expected.to be false } + end + end + end + + context 'with valid values' do + ['none', ' none ', 'NONE', 'NoNe', :none].each do |v| + context "'#{v}'" do + let (:value) { v } + it { is_expected.to be true } + end + end + end + end +end diff --git a/spec/options_spec.rb b/spec/options_spec.rb index cc2d5791..f4228599 100644 --- a/spec/options_spec.rb +++ b/spec/options_spec.rb @@ -3,7 +3,7 @@ require 'rspec/its' require 'kramdown-plantuml/options' -Options = Kramdown::PlantUml::Options +Options ||= Kramdown::PlantUml::Options describe Options do let(:hash) { {} } diff --git a/spec/diagram_spec.rb b/spec/plantuml_diagram_spec.rb similarity index 57% rename from spec/diagram_spec.rb rename to spec/plantuml_diagram_spec.rb index b10151e3..93390df8 100644 --- a/spec/diagram_spec.rb +++ b/spec/plantuml_diagram_spec.rb @@ -1,20 +1,20 @@ # frozen_string_literal: false require 'rspec/its' -require 'kramdown-plantuml/diagram' +require 'kramdown-plantuml/plantuml_diagram' -Diagram = ::Kramdown::PlantUml::Diagram +PlantUmlDiagram ||= ::Kramdown::PlantUml::PlantUmlDiagram -describe Diagram do - plantuml_content = File.read(File.join(__dir__, 'examples', 'diagram.plantuml')) +describe PlantUmlDiagram do + plantuml_content = File.read(File.join(__dir__, 'examples', 'network-diagram.puml')) - describe '#convert_to_svg' do + describe '#svg' do context 'gracefully fails' do - subject { Diagram.new(plantuml, Options.new).convert_to_svg } + subject { PlantUmlDiagram.new(plantuml, Options.new).svg.to_s } context 'with nil plantuml' do let(:plantuml) { nil } - it { is_expected.to be_nil } + it { is_expected.to be_empty } end context 'with empty plantuml' do @@ -24,58 +24,42 @@ end context 'successfully converts' do - before(:all) { @converted_svg = Diagram.new(plantuml_content, Options.new).convert_to_svg } + before(:all) { @converted_svg = PlantUmlDiagram.new(plantuml_content, Options.new).svg.to_s } subject { @converted_svg } it { is_expected.not_to include('No @startuml/@enduml found') } - it { - is_expected.to include('') - } - it { is_expected.not_to include('