Skip to content

Instantly share code, notes, and snippets.

@Yoshyn
Created October 21, 2016 10:36
Show Gist options
  • Save Yoshyn/6f2bd8b67d366bf55de8677ab67b7736 to your computer and use it in GitHub Desktop.
Save Yoshyn/6f2bd8b67d366bf55de8677ab67b7736 to your computer and use it in GitHub Desktop.
Rails wrapper for string like simple_form, tested implementation.
unless File.exist?('Gemfile')
File.write('Gemfile', <<-GEMFILE)
source 'https://rubygems.org'
gem 'rails', '~> 4.2' #, github: 'rails/rails'
GEMFILE
system 'bundle'
end
require 'bundler'
Bundler.setup(:default)
require 'minitest/autorun'
require 'logger'
require 'active_support/core_ext/hash/indifferent_access'
require 'action_view'
module Formatters
class Configuration
def initialize
@wrappers ||= HashWithIndifferentAccess.new
end
def wrappers(name, *args, &block)
@wrappers[name] = Wrappers::Builder.new(*args, &block)
end
def get_wrapper(name); @wrappers[name]; end
end
class << self
attr_accessor :configuration
alias_method :config, :configuration
end
@configuration ||= Configuration.new
def self.setup; yield(@configuration); end
def self.find_wrapper(wrapper_name);
(wrapper_name && @configuration.get_wrapper(wrapper_name).presence) || Wrappers::Proxy.new
end
end
module Wrappers
class Builder
include ActionView::Helpers::TagHelper
DEFAULT_TAG = :div
def initialize(options = {})
@options = options
tag(@options.delete(:tag))
yield(self) if block_given?
end
def wrap(content=nil)
ctag = @tag.presence || DEFAULT_TAG
ccontent = (content.presence || @content).to_s
wcontent = content_tag(ctag, ccontent, @options)
if @wrapper
@wrapper.wrap(@wrapper.get_prepend() + wcontent + @wrapper.get_append())
else
wcontent
end
end
def tag(tag); @tag = tag; end
def classes(classes); @options[:class] = classes; end
def content(value); @content = value; end
def prepend(*args, &block); @prepend = Wrappers::Builder.new(*args, &block); end
def append(*args, &block); @append = Wrappers::Builder.new(*args, &block); end
def wrapper(*args, &block); @wrapper = Wrappers::Builder.new(*args, &block); end
def get_append; @append.wrap(nil).to_s; end
def get_prepend; @prepend.wrap(nil).to_s; end
end
class Proxy
def wrap(content=nil); content; end;
end
end
Formatters.setup do |config|
config.wrappers :simple_wrapper do |dw|
dw.tag :div
dw.classes 'simple_wrapper_column'
end
config.wrappers :awesome_wrapper do |dw|
dw.tag :span
dw.classes 'awesome_wrapper_column'
dw.wrapper tag: 'div', class: 'awesome_wrapper' do |wavc|
wavc.prepend(tag: 'div', class: 'awesome_wrapper_prepend') do |prepend|
prepend.content('PREPEND')
end
wavc.append(tag: 'div', class: 'awesome_wrapper_append') do |append|
append.tag('span')
append.classes('awesome_wrapper_append')
append.content('APPEND')
end
end
end
end
class BugTest < Minitest::Test
def test_simple_wrapper
result = Formatters.find_wrapper(:simple_wrapper).wrap('This string must be wrapped!')
expect = <<-HTML
<div class="simple_wrapper_column">This string must be wrapped!</div>
HTML
assert_equal result, expect.gsub("\n", '').strip.gsub(/>\s+<(\/)?(div|span)/, '><\1\2')
end
def test_awesome_wrapper
result = Formatters.find_wrapper(:awesome_wrapper).wrap('This string must be wrapped!')
expect = <<-HTML
<div class="awesome_wrapper">
<div class="awesome_wrapper_prepend">PREPEND</div>
<span class="awesome_wrapper_column">This string must be wrapped!</span>
<span class="awesome_wrapper_append">APPEND</span>
</div>
HTML
assert_equal result, expect.gsub("\n", '').strip.gsub(/>\s+<(\/)?(div|span)/, '><\1\2')
end
def test_no_wrapper
result = Formatters.find_wrapper(nil).wrap('This string must not be wrapped!')
assert_equal result, 'This string must not be wrapped!'
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment