Class: Asciidoctor::DocTest::IO::Base Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/asciidoctor/doctest/io/base.rb

Overview

This class is abstract.

This is a base class that should be extended for specific example formats.

Direct Known Subclasses

Asciidoc, XML

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path: DocTest.examples_path, file_ext: nil) ⇒ Base

Returns a new instance of Base

Parameters:

  • path (String, Array<String>)

    path of the directory (or multiple directories) where to look for the examples.

  • file_ext (String)

    the filename extension (e.g. .adoc) of the examples group files. Must not be nil or blank. (required)


25
26
27
28
29
30
31
# File 'lib/asciidoctor/doctest/io/base.rb', line 25

def initialize(path: DocTest.examples_path, file_ext: nil)
  fail ArgumentError, 'file_ext must not be blank or nil' if file_ext.blank?

  @path = Array(path).freeze
  @file_ext = file_ext.strip.freeze
  @examples_cache = {}
end

Instance Attribute Details

#file_extvoid (readonly)

Returns the value of attribute file_ext


16
17
18
# File 'lib/asciidoctor/doctest/io/base.rb', line 16

def file_ext
  @file_ext
end

#pathvoid (readonly)

Returns the value of attribute path


16
17
18
# File 'lib/asciidoctor/doctest/io/base.rb', line 16

def path
  @path
end

Instance Method Details

#group_namesArray<String>

Returns names of all the example groups (files with #file_ext) found on the #path.

Returns:

  • (Array<String>)

146
147
148
149
150
151
152
# File 'lib/asciidoctor/doctest/io/base.rb', line 146

def group_names
  @path.reduce(Set.new) { |acc, path|
    acc | Pathname.new(path).each_child
      .select { |p| p.file? && p.extname == @file_ext }
      .map { |p| p.sub_ext('').basename.to_s }
  }.sort
end

#pair_with(other_suite) ⇒ Enumerator

Returns enumerator that yields pairs of the examples from this suite and the other_suite (examples with the same name) in order of this suite.

When some example is missing in this or the other_suite, it's substituted with an empty example of the corresponding type and name. In the case of missing example from this suite, the pair is placed at the end of the examples group.

Parameters:

  • other_suite (Base)

Returns:

  • (Enumerator)

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/asciidoctor/doctest/io/base.rb', line 72

def pair_with(other_suite)
  Enumerator.new do |y|
    group_names.each do |group_name|
      theirs_by_name = other_suite.read_examples(group_name).index_by(&:name)

      read_examples(group_name).each do |ours|
        theirs = theirs_by_name.delete(ours.name)
        theirs ||= other_suite.create_example(ours.name)
        y.yield ours, theirs
      end

      theirs_by_name.each_value do |theirs|
        y.yield create_example(theirs.name), theirs
      end
    end
  end
end

#parse(input, group_name) ⇒ Array<Example>

This method is abstract.

Parses group of examples from the input and returns array of the parsed examples.

:nocov:

Parameters:

  • input (#each_line)

    the file content to parse.

  • group_name (String)

    the examples group name.

Returns:

  • (Array<Example>)

    parsed examples.


42
43
44
# File 'lib/asciidoctor/doctest/io/base.rb', line 42

def parse(input, group_name)
  fail NotImplementedError
end

#read_examples(group_name) ⇒ Array<Example>

Reads the named examples group from file(s). When multiple matching files are found on the #path, it merges them together. If two files defines example with the same name, then the first wins (i.e. first on the #path).

Parameters:

  • group_name (String)

    the examples group name.

Returns:

  • (Array<Example>)

    an array of parsed examples, or an empty array if no file found.


100
101
102
103
104
105
# File 'lib/asciidoctor/doctest/io/base.rb', line 100

def read_examples(group_name)
  @examples_cache[group_name] ||= read_files(group_name)
    .map { |data| parse(data, group_name) }
    .flatten
    .uniq(&:name)
end

#serialize(examples) ⇒ String

This method is abstract.

Serializes the given examples into string.

:nocov:

Parameters:

Returns:

  • (String)

54
55
56
# File 'lib/asciidoctor/doctest/io/base.rb', line 54

def serialize(examples)
  fail NotImplementedError
end

#update_examples(examples) ⇒ void

Replaces existing examples with the given ones.

Parameters:

  • examples (Array<Example] the updated examples.)

    xamples [Array<Example] the updated examples.

See Also:


127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/asciidoctor/doctest/io/base.rb', line 127

def update_examples(examples)
  examples.group_by(&:group_name).each do |group, exmpls|
    # replace cached examples with the given ones and preserve original order
    updated_group = [ read_examples(group), exmpls ]
      .map { |e| e.index_by(&:local_name) }
      .reduce(:merge)
      .values

    write_examples updated_group
    @examples_cache.delete(group)  # flush cache
  end
end

#write_examples(examples) ⇒ void

Writes the given examples into file(s) {path.first}/{group_name}{file_ext}. Already existing files will be overwritten!

Parameters:


114
115
116
117
118
119
# File 'lib/asciidoctor/doctest/io/base.rb', line 114

def write_examples(examples)
  examples.group_by(&:group_name).each do |group_name, exmpls|
    path = file_path(@path.first, group_name)
    File.write(path, serialize(exmpls))
  end
end