liquid-diagrams 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +124 -0
  4. data/lib/liquid-diagrams.rb +3 -0
  5. data/lib/liquid_diagrams/basic_block.rb +49 -0
  6. data/lib/liquid_diagrams/basic_renderer.rb +20 -0
  7. data/lib/liquid_diagrams/errors.rb +12 -0
  8. data/lib/liquid_diagrams/renderers/blockdiag_renderer.rb +50 -0
  9. data/lib/liquid_diagrams/renderers/erd_renderer.rb +36 -0
  10. data/lib/liquid_diagrams/renderers/graphviz_renderer.rb +33 -0
  11. data/lib/liquid_diagrams/renderers/mermaid_renderer.rb +34 -0
  12. data/lib/liquid_diagrams/renderers/nomnoml_renderer.rb +17 -0
  13. data/lib/liquid_diagrams/renderers/plantuml_renderer.rb +20 -0
  14. data/lib/liquid_diagrams/renderers/smcat_renderer.rb +31 -0
  15. data/lib/liquid_diagrams/renderers/svgbob_renderer.rb +28 -0
  16. data/lib/liquid_diagrams/renderers/syntrax_renderer.rb +28 -0
  17. data/lib/liquid_diagrams/renderers/vega_renderer.rb +25 -0
  18. data/lib/liquid_diagrams/renderers/wavedrom_renderer.rb +17 -0
  19. data/lib/liquid_diagrams/rendering.rb +47 -0
  20. data/lib/liquid_diagrams/utils.rb +47 -0
  21. data/lib/liquid_diagrams/version.rb +5 -0
  22. data/lib/liquid_diagrams.rb +89 -0
  23. data/spec/liquid_diagrams/basic_block_spec.rb +49 -0
  24. data/spec/liquid_diagrams/basic_renderer_spec.rb +28 -0
  25. data/spec/liquid_diagrams/renderers/blockdiag_renderer_spec.rb +43 -0
  26. data/spec/liquid_diagrams/renderers/erd_renderer_spec.rb +49 -0
  27. data/spec/liquid_diagrams/renderers/graphviz_renderer_spec.rb +63 -0
  28. data/spec/liquid_diagrams/renderers/mermaid_renderer_spec.rb +31 -0
  29. data/spec/liquid_diagrams/renderers/nomnoml_renderer_spec.rb +15 -0
  30. data/spec/liquid_diagrams/renderers/plantuml_renderer_spec.rb +41 -0
  31. data/spec/liquid_diagrams/renderers/smcat_renderer_spec.rb +33 -0
  32. data/spec/liquid_diagrams/renderers/svgbob_renderer_spec.rb +31 -0
  33. data/spec/liquid_diagrams/renderers/syntrax_renderer_spec.rb +31 -0
  34. data/spec/liquid_diagrams/renderers/vega_renderer_spec.rb +33 -0
  35. data/spec/liquid_diagrams/renderers/wavedrom_renderer_spec.rb +15 -0
  36. data/spec/liquid_diagrams/rendering_spec.rb +127 -0
  37. data/spec/liquid_diagrams/utils_spec.rb +66 -0
  38. data/spec/liquid_diagrams_spec.rb +79 -0
  39. data/spec/spec_helper.rb +22 -0
  40. data/spec/support/shared_examples.rb +47 -0
  41. data/vendor/mermaid_puppeteer_config.json +3 -0
  42. data/vendor/plantuml.1.2020.1.jar +0 -0
  43. metadata +232 -0
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'liquid'
4
+
5
+ require_relative 'liquid_diagrams/version'
6
+
7
+ require_relative 'liquid_diagrams/errors'
8
+ require_relative 'liquid_diagrams/utils'
9
+ require_relative 'liquid_diagrams/rendering'
10
+
11
+ require_relative 'liquid_diagrams/basic_renderer'
12
+ require_relative 'liquid_diagrams/basic_block'
13
+
14
+ module LiquidDiagrams
15
+ # @note All renderers should be defined under this module
16
+ module Renderers
17
+ pattern = File.join(__dir__, 'liquid_diagrams/renderers/*_renderer.rb')
18
+
19
+ Dir[pattern].sort.each { |renderer| require renderer }
20
+ end
21
+
22
+ # @note All blocks are automaticly define under this module if not exist
23
+ module Blocks
24
+ Renderers.constants.grep(/Renderer$/).each do |renderer|
25
+ block_name = "#{renderer.to_s.chomp('Renderer')}Block"
26
+
27
+ next if Blocks.const_defined?(block_name)
28
+
29
+ Blocks.const_set(block_name, Class.new(BasicBlock))
30
+ end
31
+ end
32
+
33
+ class << self
34
+ # Return all diagrams defined in {Renderers}
35
+ #
36
+ # @return [Array<Symbol>]
37
+ def diagrams
38
+ @diagrams ||= renderers.keys
39
+ end
40
+
41
+ # Return all avaliable renderers under {Renderers}
42
+ #
43
+ # @return [Hash{Symbol => BasicRenderer}]
44
+ def renderers
45
+ @renderers ||= Hash[
46
+ Renderers.constants.grep(/Renderer$/).sort.map do |renderer|
47
+ [
48
+ renderer.to_s.chomp('Renderer').downcase.to_sym,
49
+ Renderers.const_get(renderer)
50
+ ]
51
+ end
52
+ ]
53
+ end
54
+
55
+ # Return all registered diagrams block
56
+ #
57
+ # Use {.register_diagrams} and {.register_diagram} to register a diagram
58
+ #
59
+ # @return [Hash{Symbol => BasicBlock}]
60
+ def registered_diagrams
61
+ @registered_diagrams ||= {}
62
+ end
63
+
64
+ # Register diagrams
65
+ #
66
+ # @param diagrams [Array<String, Symbol>] diagrams to register
67
+ #
68
+ # @return [Array<Liquid::Block>] the registered liquid blocks
69
+ def register_diagrams(*diagrams)
70
+ Array(diagrams).flatten.map { |diagram| register_diagram(diagram) }
71
+ end
72
+
73
+ # Register a diagram block
74
+ #
75
+ # @param diagram [#to_s] diagram name to register
76
+ #
77
+ # @return [Liquid::Block] the registered liquid block
78
+ def register_diagram(diagram)
79
+ diagram = diagram.to_s.downcase.to_sym
80
+
81
+ raise Errors::DiagramNotFoundError unless diagrams.include?(diagram)
82
+
83
+ block = Blocks.const_get("#{diagram.capitalize}Block")
84
+
85
+ registered_diagrams.merge!(diagram => block)
86
+ Liquid::Template.register_tag(diagram, block)
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::BasicBlock do
6
+ let(:block) do
7
+ TestBlock.parse(
8
+ 'test', '', Liquid::Tokenizer.new('{% endtest %}'),
9
+ Liquid::ParseContext.new
10
+ )
11
+ end
12
+
13
+ before do
14
+ stub_const('TestBlock', Class.new(described_class))
15
+ stub_const('TestRenderer', Class.new)
16
+ end
17
+
18
+ describe '.renderer' do
19
+ it 'return the renderer matching the block' do
20
+ expect(TestBlock.renderer).to be TestRenderer
21
+ end
22
+ end
23
+
24
+ describe '#render' do
25
+ it 'call #render!' do
26
+ allow(block).to receive(:render!).and_return 'success'
27
+
28
+ expect(block.render(Liquid::Context.new)).to eq 'success'
29
+ end
30
+
31
+ context 'when rendering failed' do
32
+ let(:error) { LiquidDiagrams::Errors::BasicError.new }
33
+
34
+ it 'rescue and return the error' do
35
+ allow(block).to receive(:render!).and_raise(error)
36
+
37
+ expect(block.render(Liquid::Context.new)).to eq error
38
+ end
39
+ end
40
+ end
41
+
42
+ describe '#render!' do
43
+ it 'render with renderer' do
44
+ allow(TestRenderer).to receive(:render).and_return 'success'
45
+
46
+ expect(block.render!(Liquid::Context.new)).to eq 'success'
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::BasicRenderer do
6
+ describe '.render' do
7
+ let(:renderer) { Object.new }
8
+
9
+ before do
10
+ allow(renderer).to receive(:render).and_return 'yay'
11
+ allow(described_class).to receive(:new).and_return(renderer)
12
+ end
13
+
14
+ it 'create an instance and render with it' do
15
+ expect(described_class.render('content', { k: 'v' })).to eq 'yay'
16
+ end
17
+ end
18
+
19
+ describe '#render' do
20
+ let(:renderer) { described_class.new('') }
21
+
22
+ it 'raise not implemented error' do
23
+ expect { renderer.render }.to raise_error(
24
+ LiquidDiagrams::Errors::NotImplementedError
25
+ )
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::Renderers::BlockdiagRenderer do
6
+ subject(:renderer) { described_class.new('content') }
7
+
8
+ describe '#render' do
9
+ include_examples 'render with tempfile', described_class
10
+ end
11
+
12
+ describe '#build_command' do
13
+ context 'when config is empty' do
14
+ it { expect(renderer.build_command).to eq 'blockdiag -T svg --nodoctype' }
15
+ end
16
+
17
+ context 'when config is not empty' do
18
+ before do
19
+ renderer.instance_variable_set(:@config, { 'size' => 10 })
20
+ end
21
+
22
+ it 'build command with config' do
23
+ expect(renderer.build_command).to match '--size=10'
24
+ end
25
+ end
26
+
27
+ context 'when switch is true' do
28
+ it 'build command' do
29
+ renderer.instance_variable_set(:@config, { 'antialias' => true })
30
+
31
+ expect(renderer.build_command).to match '--antialias'
32
+ end
33
+ end
34
+
35
+ context 'when switch is false' do
36
+ it 'build command' do
37
+ renderer.instance_variable_set(:@config, { 'antialias' => false })
38
+
39
+ expect(renderer.build_command).not_to match '--antialias'
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::Renderers::ErdRenderer do
6
+ subject(:renderer) { described_class.new('content') }
7
+
8
+ describe '#render' do
9
+ include_examples 'render with stdin and stdout', described_class
10
+ end
11
+
12
+ describe '#build_command' do
13
+ context 'when config is empty' do
14
+ it { expect(renderer.build_command).to eq 'erd --fmt=svg' }
15
+ end
16
+
17
+ context 'when config is not empty' do
18
+ before do
19
+ renderer.instance_variable_set(
20
+ :@config, { 'edge' => 10, 'color' => :blue }
21
+ )
22
+ end
23
+
24
+ it 'build command with config' do
25
+ expect(renderer.build_command).to match '--edge=10'
26
+ end
27
+
28
+ it 'ignore unsupported configuration' do
29
+ expect(renderer.build_command).not_to match '--color'
30
+ end
31
+ end
32
+
33
+ context 'when switch is true' do
34
+ it 'build command' do
35
+ renderer.instance_variable_set(:@config, { 'dot-entity' => true })
36
+
37
+ expect(renderer.build_command).to match '--dot-entity'
38
+ end
39
+ end
40
+
41
+ context 'when switch is false' do
42
+ it 'build command' do
43
+ renderer.instance_variable_set(:@config, { 'dot-entity' => false })
44
+
45
+ expect(renderer.build_command).not_to match '--dot-entity'
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::Renderers::GraphvizRenderer do
6
+ subject(:renderer) { described_class.new('content') }
7
+
8
+ describe '#render' do
9
+ include_examples 'render with stdin and stdout', described_class
10
+ end
11
+
12
+ describe '#build_command' do
13
+ context 'when config is empty' do
14
+ it { expect(renderer.build_command).to eq 'dot -Tsvg' }
15
+ end
16
+
17
+ context 'when config is not empty' do
18
+ before do
19
+ renderer.instance_variable_set(:@config, { 'layout' => 'dot' })
20
+ end
21
+
22
+ it 'build command with config' do
23
+ expect(renderer.build_command).to match '-Kdot'
24
+ end
25
+ end
26
+
27
+ context 'with string attributes' do
28
+ before do
29
+ renderer.instance_variable_set(
30
+ :@config, { 'graph_attributes' => 'color=red' }
31
+ )
32
+ end
33
+
34
+ it 'build command' do
35
+ expect(renderer.build_command).to match ' -Gcolor=red'
36
+ end
37
+ end
38
+
39
+ context 'with array attributes' do
40
+ before do
41
+ renderer.instance_variable_set(
42
+ :@config, { 'node_attributes' => %w[color=red size=10] }
43
+ )
44
+ end
45
+
46
+ it 'build command' do
47
+ expect(renderer.build_command).to match ' -Ncolor=red -Nsize=10'
48
+ end
49
+ end
50
+
51
+ context 'with hash attributes' do
52
+ before do
53
+ renderer.instance_variable_set(
54
+ :@config, { 'edge_attributes' => { 'color': 'red', 'size': '10' } }
55
+ )
56
+ end
57
+
58
+ it 'build command' do
59
+ expect(renderer.build_command).to match ' -Ecolor=red -Esize=10'
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::Renderers::MermaidRenderer do
6
+ subject(:renderer) { described_class.new('content') }
7
+
8
+ describe '#render' do
9
+ include_examples 'render with tempfile', described_class
10
+ end
11
+
12
+ describe '#build_command' do
13
+ context 'when config is empty' do
14
+ it { expect(renderer.build_command).to match 'mmdc --puppeteerConfigFile' }
15
+ end
16
+
17
+ context 'when config is not empty' do
18
+ before do
19
+ renderer.instance_variable_set(:@config, { 'scale' => 10, 'color' => :blue })
20
+ end
21
+
22
+ it 'build command with config' do
23
+ expect(renderer.build_command).to match '--scale 10'
24
+ end
25
+
26
+ it 'ignore unsupported configuration' do
27
+ expect(renderer.build_command).not_to match '--color blue'
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::Renderers::NomnomlRenderer do
6
+ subject(:renderer) { described_class.new('content') }
7
+
8
+ describe '#render' do
9
+ include_examples 'render with tempfile', described_class
10
+ end
11
+
12
+ describe '#build_command' do
13
+ it { expect(renderer.build_command).to eq 'nomnoml' }
14
+ end
15
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::Renderers::PlantumlRenderer do
6
+ subject(:renderer) { described_class.new('content') }
7
+
8
+ describe '#render' do
9
+ before do
10
+ allow(renderer).to receive(:build_command)
11
+ allow(LiquidDiagrams::Rendering).to receive(
12
+ :render_with_stdin_stdout
13
+ ).and_return('<?xml version="1.0" encoding="UTF-8" standalone="no"?><>')
14
+ end
15
+
16
+ it 'call build_command' do
17
+ renderer.render
18
+
19
+ expect(renderer).to have_received(:build_command)
20
+ end
21
+
22
+ it 'render with stdin and stdout' do
23
+ renderer.render
24
+
25
+ expect(LiquidDiagrams::Rendering).to have_received(:render_with_stdin_stdout)
26
+ end
27
+
28
+ it 'remove xml heading' do
29
+ expect(renderer.render).to eq '<>'
30
+ end
31
+ end
32
+
33
+ describe '#build_command' do
34
+ it do
35
+ command = renderer.build_command
36
+
37
+ expect(command).to match 'Plantuml'
38
+ expect(command).to match '-tsvg -pipe'
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::Renderers::SmcatRenderer do
6
+ subject(:renderer) { described_class.new('content') }
7
+
8
+ describe '#render' do
9
+ include_examples 'render with tempfile', described_class
10
+ end
11
+
12
+ describe '#build_command' do
13
+ context 'when config is empty' do
14
+ it { expect(renderer.build_command).to eq 'Smcat' }
15
+ end
16
+
17
+ context 'when config is not empty' do
18
+ before do
19
+ renderer.instance_variable_set(
20
+ :@config, { 'engine' => 'dot', 'color' => :blue }
21
+ )
22
+ end
23
+
24
+ it 'build command with config' do
25
+ expect(renderer.build_command).to match '--engine dot'
26
+ end
27
+
28
+ it 'ignore unsupported configuration' do
29
+ expect(renderer.build_command).not_to match '--color blue'
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::Renderers::SvgbobRenderer do
6
+ subject(:renderer) { described_class.new('content') }
7
+
8
+ describe '#render' do
9
+ include_examples 'render with stdin and stdout', described_class
10
+ end
11
+
12
+ describe '#build_command' do
13
+ context 'when config is empty' do
14
+ it { expect(renderer.build_command).to eq 'svgbob' }
15
+ end
16
+
17
+ context 'when config is not empty' do
18
+ before do
19
+ renderer.instance_variable_set(:@config, { 'scale' => 10, 'color' => :blue })
20
+ end
21
+
22
+ it 'build command with config' do
23
+ expect(renderer.build_command).to match '--scale 10'
24
+ end
25
+
26
+ it 'ignore unsupported configuration' do
27
+ expect(renderer.build_command).not_to match '--color blue'
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::Renderers::SyntraxRenderer do
6
+ subject(:renderer) { described_class.new('content') }
7
+
8
+ describe '#render' do
9
+ include_examples 'render with tempfile', described_class
10
+ end
11
+
12
+ describe '#build_command' do
13
+ context 'when config is empty' do
14
+ it { expect(renderer.build_command).to eq 'syntrax' }
15
+ end
16
+
17
+ context 'when config is not empty' do
18
+ before do
19
+ renderer.instance_variable_set(:@config, { 'scale' => 10, 'color' => :blue })
20
+ end
21
+
22
+ it 'build command with config' do
23
+ expect(renderer.build_command).to match '--scale 10'
24
+ end
25
+
26
+ it 'ignore unsupported configuration' do
27
+ expect(renderer.build_command).not_to match '--color blue'
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::Renderers::VegaRenderer do
6
+ subject(:renderer) { described_class.new('content') }
7
+
8
+ describe '#render' do
9
+ include_examples 'render with stdin and stdout', described_class
10
+ end
11
+
12
+ describe '#build_command' do
13
+ context 'when config is empty' do
14
+ it { expect(renderer.build_command).to eq 'vg2svg' }
15
+ end
16
+
17
+ context 'when config is not empty' do
18
+ before do
19
+ renderer.instance_variable_set(
20
+ :@config, { 'scale' => 10, 'other' => 'value' }
21
+ )
22
+ end
23
+
24
+ it 'build command with config' do
25
+ expect(renderer.build_command).to match '--scale 10'
26
+ end
27
+
28
+ it 'ignore unsupported configuration' do
29
+ expect(renderer.build_command).not_to match '--other'
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::Renderers::WavedromRenderer do
6
+ subject(:renderer) { described_class.new('content') }
7
+
8
+ describe '#render' do
9
+ include_examples 'render with tempfile', described_class
10
+ end
11
+
12
+ describe '#build_command' do
13
+ it { expect(renderer.build_command).to eq 'wavedrom-cli' }
14
+ end
15
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe LiquidDiagrams::Rendering do
6
+ describe '.render_with_stdin_stdout' do
7
+ it 'call render_with_command' do
8
+ allow(described_class).to receive(:render_with_command)
9
+
10
+ described_class.render_with_stdin_stdout('command', 'content')
11
+
12
+ expect(described_class).to have_received(:render_with_command).with(
13
+ 'command', :stdout, stdin_data: 'content'
14
+ )
15
+ end
16
+ end
17
+
18
+ describe '.render_with_tempfile' do
19
+ let(:input) { Object.new }
20
+ let(:output) { Object.new }
21
+
22
+ before do
23
+ allow(described_class).to receive(:render_with_command)
24
+
25
+ allow(File).to receive(:write)
26
+ allow(Tempfile).to receive(:new).and_return(input, output)
27
+
28
+ allow(input).to receive(:path)
29
+ allow(input).to receive(:close!)
30
+ allow(output).to receive(:path)
31
+ allow(output).to receive(:close!)
32
+ end
33
+
34
+ it 'call Tempfile.new twice to create input and output file' do
35
+ described_class.render_with_tempfile('command', 'content') {}
36
+
37
+ expect(Tempfile).to have_received(:new).twice
38
+ end
39
+
40
+ it 'yield input path and output path' do
41
+ described_class.render_with_tempfile('command', 'content') {}
42
+
43
+ expect(input).to have_received(:path).twice
44
+ expect(output).to have_received(:path).twice
45
+ end
46
+
47
+ it 'close input and output file after rendering' do
48
+ described_class.render_with_tempfile('command', 'content') {}
49
+
50
+ expect(input).to have_received(:close!).once
51
+ expect(output).to have_received(:close!).once
52
+ end
53
+
54
+ it 'call render_with_command' do
55
+ described_class.render_with_tempfile('command', 'content') {}
56
+
57
+ expect(described_class).to have_received(:render_with_command)
58
+ end
59
+ end
60
+
61
+ describe '.render_with_command' do
62
+ it 'call Open3.capture3' do
63
+ status = Object.new
64
+
65
+ allow(status).to receive(:success?).and_return(true)
66
+ allow(Open3).to receive(:capture3).and_return(['o', 'e', status])
67
+
68
+ described_class.render_with_command('command')
69
+
70
+ expect(Open3).to have_received(:capture3)
71
+ end
72
+
73
+ context 'when command is not found' do
74
+ it 'raise a command not found error' do
75
+ allow(Open3).to receive(:capture3).and_raise(Errno::ENOENT)
76
+
77
+ expect do
78
+ described_class.render_with_command('command')
79
+ end.to raise_error LiquidDiagrams::Errors::CommandNotFoundError
80
+ end
81
+ end
82
+
83
+ context 'when rendering failed' do
84
+ before do
85
+ status = Object.new
86
+
87
+ allow(status).to receive(:success?).and_return(false)
88
+ allow(Open3).to receive(:capture3).and_return(['o', 'e', status])
89
+ end
90
+
91
+ it 'raise a rendering failed error' do
92
+ expect do
93
+ described_class.render_with_command('command')
94
+ end.to raise_error LiquidDiagrams::Errors::RenderingFailedError
95
+ end
96
+ end
97
+
98
+ context 'when output is stdout' do
99
+ before do
100
+ status = Object.new
101
+
102
+ allow(status).to receive(:success?).and_return(true)
103
+ allow(Open3).to receive(:capture3).and_return(['o', 'e', status])
104
+ end
105
+
106
+ it 'read output from stdout' do
107
+ expect(described_class.render_with_command('cmd', :stdout)).to eq 'o'
108
+ end
109
+ end
110
+
111
+ context 'when output is a file' do
112
+ before do
113
+ status = Object.new
114
+
115
+ allow(status).to receive(:success?).and_return(true)
116
+ allow(Open3).to receive(:capture3).and_return(['o', 'e', status])
117
+ allow(File).to receive(:read)
118
+ end
119
+
120
+ it 'read output from the file' do
121
+ described_class.render_with_command('cmd', 'a_file')
122
+
123
+ expect(File).to have_received(:read).with('a_file')
124
+ end
125
+ end
126
+ end
127
+ end