Skip to content

Commit

Permalink
Refactor under tests yay
Browse files Browse the repository at this point in the history
  • Loading branch information
danott committed Jan 15, 2024
1 parent ac407a2 commit 17e02b3
Showing 1 changed file with 69 additions and 36 deletions.
105 changes: 69 additions & 36 deletions lib/magic_comment_hydrator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,79 @@ def hydrate
end

def next_magic_element
eval_ruby_regex = %r{<(eval-ruby)>(.*?)</eval-ruby>}m
include_in_header_regex =
%r{<(include-in-header)>(.*?)</include-in-header>}m
content.match(eval_ruby_regex) || content.match(include_in_header_regex)
IncludeInHeader.recognize(content) || EvalRuby.recognize(content, self)
end

def next
fail "No more hydrating to do!" if next_magic_element.nil?
return self.class.new(content: next_magic_element.result, data: data)
end

private

class IncludeInHeader
attr_reader :content
attr_reader :match

def self.recognize(content)
match = content.match(%r{<include-in-header>(.*?)</include-in-header>}m)
new(content:, match:) if match
end

def initialize(content:, match:)
@content = content
@match = match
end

def end_of_head
content.index("</head>")
end

def entire_magic_element
match[0]
end

def children
match[1]
end

def result
content.sub(entire_magic_element, "").insert(end_of_head, children)
end
end

class EvalRuby
attr_reader :content
attr_reader :hydrator
attr_reader :match

def self.recognize(content, hydrator)
match = content.match(%r{<eval-ruby>(.*?)</eval-ruby>}m)
new(content:, match:, hydrator:) if match
end

def initialize(content:, match:, hydrator:)
@content = content
@match = match
@hydrator = hydrator
end

entire_magic_element = next_magic_element[0]
magic_element_name = next_magic_element[1]
magic_element_children = next_magic_element[2]

replacement =
case magic_element_name
when "eval-ruby"
eval(magic_element_children).to_s.strip
when "include-in-header"
magic_element_children.to_s.strip
else
fail "Don't know how to handle #{magic_element_name}"
end

insert_at =
case magic_element_name
when "include-in-header"
content.index("</head>")
when "eval-ruby"
content.index(entire_magic_element)
else
fail "Don't know how to handle #{magic_element_name}"
end

if insert_at > content.index(entire_magic_element)
fail "Magic element cannot appear before the targeted replacement position, yet"
end

next_content =
content.sub(entire_magic_element, "").insert(insert_at, replacement)

self.class.new(content: next_content, data: data)
def entire_magic_element
match[0]
end

def ruby_code
match[1]
end

# Eval in the context of hydrator to have access to data
def replacement
hydrator.instance_eval(ruby_code).to_s
end

def result
position = content.index(entire_magic_element)
content.sub(entire_magic_element, "").insert(position, replacement)
end
end
end

0 comments on commit 17e02b3

Please sign in to comment.