#!/usr/bin/env ruby# frozen_string_literal: true# encoding=utf-8moduleMarkdownExecclassError<StandardError;end# Fenced Code Block (FCB)## This class represents a fenced code block in a markdown document.# It allows for setting and getting attributes related to the code block,# such as body, call, headings, and more.#classFCBdefinitialize(options={})@attrs={body: nil,call: nil,headings: [],dname: nil,indent: '',name: nil,nickname: nil,oname: nil,reqs: [],shell: '',title: '',random: Random.new.rand,text: nil# displayable in menu}.merge(options)enddeftitle=(value)@attrs[:title]=valueend# Derives a title from the body of an FCB object.# @param fcb [Object] The FCB object whose title is to be derived.# @return [String] The derived title.defderive_title_from_bodyunless(body_content=@attrs[:body])# empty body -> empty title@attrs[:title]=''returnend# body -> title@attrs[:title]=ifbody_content.count==1body_content.firstelseformat_multiline_body_as_title(body_content)endendprivate# Formats multiline body content as a title string.# indents all but first line with two spaces so it displays correctly in menu# @param body_lines [Array<String>] The lines of body content.# @return [String] Formatted title.defformat_multiline_body_as_title(body_lines)body_lines.map.with_indexdo|line,index|index.zero??line:" #{line}"end.join("\n")<<"\n"end# :reek:ManualDispatchdefmethod_missing(method,*args,&block)method_name=method.to_sif@attrs.respond_to?(method_name)@attrs.send(method_name,*args,&block)elsifmethod_name[-1]=='='@attrs[method_name.chop.to_sym]=args[0]else@attrs[method_name.to_sym]endrescueStandardError=>errwarn("ERROR ** FCB.method_missing(method: #{method_name},"\" *args: #{args.inspect}, &block)")warnerr.inspectwarn(caller[0..4])# raise StandardError, errorraiseerr# Here, we simply propagate the original error instead of wrapping it in a StandardError.endpublicdefrespond_to_missing?(method_name,include_private=false)@attrs.key?(method_name.to_sym)||superenddefto_h@attrsenddefto_yaml@attrs.to_yamlendendendif$PROGRAM_NAME==__FILE__require'bundler/setup'Bundler.require(:default)require'minitest/autorun'require'yaml'classFCBTest<Minitest::Testdefsetup@fcb_data={body: 'Sample body',call: 'Sample call',headings: %w[Header1 Header2],dname: 'Sample name',indent: '',nickname: nil,name: 'Sample name',oname: 'Sample name',reqs: %w[req1 req2],shell: 'bash',text: 'Sample Text',title: 'Sample Title'}@fcb=MarkdownExec::FCB.new(@fcb_data)enddeftest_initialization_with_correct_dataassert_equal'Sample body',@fcb.bodyassert_equal%w[Header1 Header2],@fcb.headingsenddeftest_to_h_methodassert_equal@fcb_data.merge({random: @fcb.random}),@fcb.to_henddeftest_to_yaml_methodassert_equalYAML.load(@fcb_data.merge({random: @fcb.random}).to_yaml),YAML.load(@fcb.to_yaml)enddeftest_method_missing_getterassert_equal'Sample Title',@fcb.titleenddeftest_method_missing_setter@fcb.title='New Title'assert_equal'New Title',@fcb.titleend# 2023-10-09 does not trigger error; treats as option name## def test_method_missing_with_unknown_method# assert_raises(NoMethodError) { @fcb.unknown_method }# endendend