slim-3.0.6/ 0000755 0000041 0000041 00000000000 12555545227 012530 5 ustar www-data www-data slim-3.0.6/Rakefile 0000644 0000041 0000041 00000004546 12555545227 014206 0 ustar www-data www-data begin
require 'bundler/setup'
Bundler::GemHelper.install_tasks
rescue Exception
end
require 'rake/testtask'
desc 'Run Slim benchmarks! (default parameters slow=false)'
task :bench, :slow do
ruby('benchmarks/run-benchmarks.rb')
end
task 'test' => %w(test:core_and_plugins)
namespace 'test' do
task 'core_and_plugins' => %w(core literate logic_less translator smart include)
Rake::TestTask.new('core') do |t|
t.libs << 'lib' << 'test/core'
t.test_files = FileList['test/core/test_*.rb']
t.verbose = true
#t.ruby_opts << '-w' << '-v'
end
Rake::TestTask.new('literate') do |t|
t.libs << 'lib' << 'test/literate'
t.test_files = FileList['test/literate/run.rb']
t.verbose = true
end
Rake::TestTask.new('logic_less') do |t|
t.libs << 'lib' << 'test/core'
t.test_files = FileList['test/logic_less/test_*.rb']
t.verbose = true
end
Rake::TestTask.new('translator') do |t|
t.libs << 'lib' << 'test/core'
t.test_files = FileList['test/translator/test_*.rb']
t.verbose = true
end
Rake::TestTask.new('smart') do |t|
t.libs << 'lib' << 'test/core'
t.test_files = FileList['test/smart/test_*.rb']
t.verbose = true
end
Rake::TestTask.new('include') do |t|
t.libs << 'lib' << 'test/core'
t.test_files = FileList['test/include/test_*.rb']
t.verbose = true
end
Rake::TestTask.new('rails') do |t|
t.libs << 'lib'
t.test_files = FileList['test/rails/test/test_*.rb']
t.verbose = true
end
begin
require 'sinatra'
spec = Gem::Specification.find_by_name('sinatra')
Rake::TestTask.new('sinatra') do |t|
file = "#{spec.gem_dir}/test/slim_test.rb"
if Sinatra::VERSION =~ /\A1\.3/
# FIXME: Rename deprecated attribute
code = File.read(file)
code.gsub!('attr_wrapper', 'attr_quote')
File.open(file, 'w') {|out| out.write(code) }
end
# Run Slim integration test in Sinatra
t.test_files = FileList[file]
t.verbose = true
end
rescue LoadError
task :sinatra do
abort 'Sinatra is not available'
end
end
end
begin
require 'yard'
YARD::Rake::YardocTask.new do |t|
t.files = %w(lib/**/*.rb)
end
rescue LoadError
task :yard do
abort 'YARD is not available. In order to run yard, you must: gem install yard'
end
end
desc "Generate Documentation"
task doc: :yard
task default: 'test'
slim-3.0.6/bin/ 0000755 0000041 0000041 00000000000 12555545227 013300 5 ustar www-data www-data slim-3.0.6/bin/slimrb 0000755 0000041 0000041 00000000167 12555545227 014522 0 ustar www-data www-data #!/usr/bin/env ruby
$:.unshift File.dirname(__FILE__) + '/../lib'
require 'slim/command'
Slim::Command.new(ARGV).run
slim-3.0.6/Gemfile 0000644 0000041 0000041 00000002544 12555545227 014030 0 ustar www-data www-data source 'https://rubygems.org/'
gemspec
if ENV['TRAVIS'] || ENV['TEMPLE'] == 'master'
gem 'temple', github: 'judofyr/temple'
end
if ENV['TILT']
if ENV['TILT'] == 'master'
gem 'tilt', github: 'rtomayko/tilt'
else
gem 'tilt', "= #{ENV['TILT']}"
end
end
if ENV['RAILS']
# we need some smarter test logic for the different Rails versions
gem 'nokogiri'
if ENV['RAILS'] == 'master'
gem 'rails', github: 'rails/rails'
else
gem 'rails', "= #{ENV['RAILS']}"
end
end
#Choose minitest 4.7.x for sinatra < 1.4.6 or rails 3 and 4.0 otherwise go for newer version
if (ENV['SINATRA'] && ENV['SINATRA'] < '1.4.6') || (ENV['RAILS'] && ENV['RAILS'].match(/^(3|4\.0)/))
gem 'minitest', '~> 4.7.4'
else
gem 'minitest', '~> 5.1'
end
#Ruby >= 2.2.0 has removed test/unit from Stdlib
if RUBY_VERSION >= '2.2.0'
gem 'test-unit', platforms: :mri
end
if RUBY_ENGINE == 'rbx' && !ENV['TRAVIS']
gem 'psych'
end
if ENV['SINATRA']
gem 'rack-test'
if ENV['SINATRA'] == 'master'
gem 'sinatra', github: 'sinatra/sinatra'
else
gem 'sinatra', "= #{ENV['SINATRA']}"
end
end
gem 'rake', '>= 0.8.7'
gem 'sass', '>= 3.1.0'
gem 'kramdown'
gem 'creole'
gem 'builder'
gem 'asciidoctor'
gem 'org-ruby'
if ENV['TASK'] == 'bench'
gem 'benchmark-ips'
gem 'erubis'
gem 'haml'
end
if ENV['CODECLIMATE_REPO_TOKEN']
gem 'codeclimate-test-reporter'
end
slim-3.0.6/doc/ 0000755 0000041 0000041 00000000000 12555545227 013275 5 ustar www-data www-data slim-3.0.6/doc/include.md 0000644 0000041 0000041 00000001045 12555545227 015242 0 ustar www-data www-data # Include
The include plugin allows Slim templates to include other files. The .slim extension is appended automatically to the
filename. If the included file is not a Slim file, it is interpreted as a text file with `#{interpolation}`.
Example:
include partial.slim
include partial
include partial.txt
Enable the include plugin with
require 'slim/include'
# Options
| Type | Name | Default | Purpose |
| ---- | ---- | ------- | ------- |
| Boolean | :include_dirs | [Dir.pwd, '.'] | Directories where to look for the files |
slim-3.0.6/doc/logic_less.md 0000644 0000041 0000041 00000007411 12555545227 015745 0 ustar www-data www-data # Logic less mode
Logic less mode is inspired by [Mustache](https://github.com/defunkt/mustache). Logic less mode uses a dictionary object
e.g. a recursive hash tree which contains the dynamic content.
## Conditional
If the object is not false or empty?, the content will show
- article
h1 = title
## Inverted conditional
If the object is false or empty?, the content will show
-! article
p Sorry, article not found
## Iteration
If the object is an array, the section will iterate
- articles
tr: td = title
## Lambdas
Like mustache, Slim supports lambdas.
= person
= name
The lambda method could be defined like this
def lambda_method
"
#{yield(name: 'Andrew')}
"
end
You can optionally pass one or more hashes to `yield`. If you pass multiple hashes, the block will be iterated as described above.
## Dictionary access
Example code:
- article
h1 = title
The dictionary object is accessed in the order given by the `:dictionary_access`. Default order:
1. `:symbol` - If `article.respond_to?(:has_key?)` and `article.has_key?(:title)`, Slim will execute `article[:title]`
2. `:string` - If `article.respond_to?(:has_key?)` and `article.has_key?('title')`, Slim will execute `article['title']`
3. `:method` - If `article.respond_to?(:title)`, Slim will execute `article.send(:title)`
4. `:instance_variable` - If `article.instance_variable_defined?(@title)`, Slim will execute `article.instance_variable_get @title`
If all the above fails, Slim will try to resolve the title reference in the same order against the parent object. In this example, the parent would be the dictionary object you are rendering the template against.
As you might have guessed, the article reference goes through the same steps against the dictionary. Instance variables are not allowed in the view code, but Slim will find and use them. Essentially, you're just using dropping the @ prefix in your template. Parameterized method calls are not allowed.
## Strings
The `self` keyword will return the `.to_s` value for the element under consideration.
Given
{
article: [
'Article 1',
'Article 2'
]
}
And
- article
tr: td = self
This will yield
翻訳プラグインを有効化します。
require 'slim/translator'
# オプション
| 種類 | 名前 | デフォルト | 用途 |
| ---- | ---- | ---------- | ---- |
| 真偽値 | :tr | true | 翻訳の有効化 ('slim/translator' の required が必要) |
| シンボル | :tr_mode | :dynamic | 翻訳を :static = コンパイル時に実施, :dynamic = ランタイムで実施 |
| 文字列 | :tr_fn | インストールされた翻訳ライブラリに依存 | 翻訳用ヘルパ, gettext の場合 '_' |
slim-3.0.6/doc/translator.md 0000644 0000041 0000041 00000001604 12555545227 016011 0 ustar www-data www-data # Translator/I18n
The translator plugin provides automatic translation of the templates using Gettext, Fast-Gettext or Rails I18n. Static text
in the template is replaced by the translated version.
Example:
h1 Welcome to #{url}!
Gettext translates the string from english to german where interpolations are replaced by %1, %2, ...
"Welcome to %1!" -> "Willkommen auf %1!"
and renders as
Willkommen auf slim-lang.com!
Enable the translator plugin with
require 'slim/translator'
# Options
| Type | Name | Default | Purpose |
| ---- | ---- | ------- | ------- |
| Boolean | :tr | true | Enable translator (Enabled if 'slim/translator' is required) |
| Symbol | :tr_mode | :dynamic | When to translate: :static = at compile time, :dynamic = at runtime |
| String | :tr_fn | Depending on installed translation library | Translation function, could be '_' for gettext |
slim-3.0.6/.travis.yml 0000644 0000041 0000041 00000002727 12555545227 014651 0 ustar www-data www-data language: ruby
rvm:
- ruby-head
- 2.2.2
- 2.1.6
- 2.0.0
- rbx-2
- 1.9.3
- jruby-head
- jruby-19mode
sudo: false
script: "bundle exec rake $TASK"
env:
global:
# travis encrypt CODECLIMATE_REPO_TOKEN=???
- secure: "a7sD9iwPJJn3Fj+mn62GAmy/PEguh3elrilsp1KS+WfDiCiIKD8Q5KG2Jv67DGcQAGI3dPWeh7+ZhZ/W7nEipwWUBmSvGYVeoF63y8j6mNRLeekqspj94l47hXyFePj9bCadY1b1/xY4lE1pMEU8eA8AOUHUqCSuH+Kk/MuvyLM="
matrix:
- "TASK=test:core_and_plugins TILT=master"
- "TASK=test:core_and_plugins TILT=1.3.7"
- "TASK=test:core_and_plugins TILT=1.4.1"
- "TASK=test:core_and_plugins TILT=2.0.1"
- "TASK=test:rails RAILS=master"
- "TASK=test:rails RAILS=3.1.12 TILT=1.3.4"
- "TASK=test:rails RAILS=3.2.21 TILT=1.3.4"
- "TASK=test:rails RAILS=4.0.13"
- "TASK=test:rails RAILS=4.1.10"
- "TASK=test:rails RAILS=4.2.1"
- "TASK=test:sinatra SINATRA=master"
- "TASK=test:sinatra SINATRA=1.3.6"
- "TASK=test:sinatra SINATRA=1.4.6"
- "TASK=bench"
- "TASK=bench slow=1"
matrix:
exclude:
- rvm: rbx-2
env: "TASK=test:rails RAILS=master"
- rvm: 1.9.3
env: "TASK=test:rails RAILS=master"
- rvm: 2.0.0
env: "TASK=test:rails RAILS=master"
allow_failures:
- env: "TASK=test:core_and_plugins TILT=master"
- env: "TASK=test:rails RAILS=master"
- env: "TASK=test:sinatra SINATRA=master"
- rvm: ruby-head
- rvm: jruby-19mode
- rvm: jruby-head
notifications:
irc: "chat.freenode.net#slim-lang" slim-3.0.6/lib/ 0000755 0000041 0000041 00000000000 12555545227 013276 5 ustar www-data www-data slim-3.0.6/lib/slim/ 0000755 0000041 0000041 00000000000 12555545227 014242 5 ustar www-data www-data slim-3.0.6/lib/slim/erb_converter.rb 0000644 0000041 0000041 00000000476 12555545227 017435 0 ustar www-data www-data require 'slim'
module Slim
# Slim to ERB converter
#
# @example Conversion
# Slim::ERBConverter.new(options).call(slim_code) # outputs erb_code
#
# @api public
class ERBConverter < Engine
replace :StaticMerger, Temple::Filters::CodeMerger
replace :Generator, Temple::Generators::ERB
end
end
slim-3.0.6/lib/slim/embedded.rb 0000644 0000041 0000041 00000017527 12555545227 016334 0 ustar www-data www-data module Slim
# @api private
class TextCollector < Filter
def call(exp)
@collected = ''
super(exp)
@collected
end
def on_slim_interpolate(text)
@collected << text
nil
end
end
# @api private
class NewlineCollector < Filter
def call(exp)
@collected = [:multi]
super(exp)
@collected
end
def on_newline
@collected << [:newline]
nil
end
end
# @api private
class OutputProtector < Filter
def call(exp)
@protect, @collected, @tag = [], '', "%#{object_id.abs.to_s(36)}%"
super(exp)
@collected
end
def on_static(text)
@collected << text
nil
end
def on_slim_output(escape, text, content)
@collected << @tag
@protect << [:slim, :output, escape, text, content]
nil
end
def unprotect(text)
block = [:multi]
while text =~ /#{@tag}/
block << [:static, $`]
block << @protect.shift
text = $'
end
block << [:static, text]
end
end
# Temple filter which processes embedded engines
# @api private
class Embedded < Filter
@engines = {}
class << self
attr_reader :engines
# Register embedded engine
#
# @param [String] name Name of the engine
# @param [Class] klass Engine class
# @param option_filter List of options to pass to engine.
# Last argument can be default option hash.
def register(name, klass, *option_filter)
name = name.to_sym
local_options = option_filter.last.respond_to?(:to_hash) ? option_filter.pop.to_hash : {}
define_options(name, *option_filter)
klass.define_options(name)
engines[name.to_sym] = proc do |options|
klass.new({}.update(options).delete_if {|k,v| !option_filter.include?(k) && k != name }.update(local_options))
end
end
def create(name, options)
constructor = engines[name] || raise(Temple::FilterError, "Embedded engine #{name} not found")
constructor.call(options)
end
end
define_options :enable_engines, :disable_engines
def initialize(opts = {})
super
@engines = {}
@enabled = normalize_engine_list(options[:enable_engines])
@disabled = normalize_engine_list(options[:disable_engines])
end
def on_slim_embedded(name, body)
name = name.to_sym
raise(Temple::FilterError, "Embedded engine #{name} is disabled") unless enabled?(name)
@engines[name] ||= self.class.create(name, options)
@engines[name].on_slim_embedded(name, body)
end
def enabled?(name)
(!@enabled || @enabled.include?(name)) &&
(!@disabled || !@disabled.include?(name))
end
protected
def normalize_engine_list(list)
raise(ArgumentError, "Option :enable_engines/:disable_engines must be String or Symbol list") unless !list || Array === list
list && list.map(&:to_sym)
end
class Engine < Filter
protected
def collect_text(body)
@text_collector ||= TextCollector.new
@text_collector.call(body)
end
def collect_newlines(body)
@newline_collector ||= NewlineCollector.new
@newline_collector.call(body)
end
end
# Basic tilt engine
class TiltEngine < Engine
def on_slim_embedded(engine, body)
tilt_engine = Tilt[engine] || raise(Temple::FilterError, "Tilt engine #{engine} is not available.")
tilt_options = options[engine.to_sym] || {}
[:multi, tilt_render(tilt_engine, tilt_options, collect_text(body)), collect_newlines(body)]
end
protected
def tilt_render(tilt_engine, tilt_options, text)
[:static, tilt_engine.new(tilt_options) { text }.render]
end
end
# Sass engine which supports :pretty option
class SassEngine < TiltEngine
define_options :pretty
protected
def tilt_render(tilt_engine, tilt_options, text)
text = tilt_engine.new(tilt_options.merge(
style: options[:pretty] ? :expanded : :compressed,
cache: false)) { text }.render
text.chomp!
[:static, text]
end
end
# Tilt-based engine which is precompiled
class PrecompiledTiltEngine < TiltEngine
protected
def tilt_render(tilt_engine, tilt_options, text)
# HACK: Tilt::Engine#precompiled is protected
[:dynamic, tilt_engine.new(tilt_options) { text }.send(:precompiled, {}).first]
end
end
# Static template with interpolated ruby code
class InterpolateTiltEngine < TiltEngine
def collect_text(body)
output_protector.call(interpolation.call(body))
end
def tilt_render(tilt_engine, tilt_options, text)
output_protector.unprotect(tilt_engine.new(tilt_options) { text }.render)
end
private
def interpolation
@interpolation ||= Interpolation.new
end
def output_protector
@output_protector ||= OutputProtector.new
end
end
# ERB engine (uses the Temple ERB implementation)
class ERBEngine < Engine
def on_slim_embedded(engine, body)
[:multi, [:newline], erb_parser.call(collect_text(body))]
end
protected
def erb_parser
@erb_parser ||= Temple::ERB::Parser.new
end
end
# Tag wrapper engine
# Generates a html tag and wraps another engine (specified via :engine option)
class TagEngine < Engine
disable_option_validator!
def on_slim_embedded(engine, body)
if options[:engine]
opts = {}.update(options)
opts.delete(:engine)
opts.delete(:tag)
opts.delete(:attributes)
@engine ||= options[:engine].new(opts)
body = @engine.on_slim_embedded(engine, body)
end
[:html, :tag, options[:tag], [:html, :attrs, *options[:attributes].map {|k, v| [:html, :attr, k, [:static, v]] }], body]
end
end
# Javascript wrapper engine.
# Like TagEngine, but can wrap content in html comment or cdata.
class JavaScriptEngine < TagEngine
disable_option_validator!
set_options tag: :script, attributes: {}
def on_slim_embedded(engine, body)
super(engine, [:html, :js, body])
end
end
# Embeds ruby code
class RubyEngine < Engine
def on_slim_embedded(engine, body)
[:multi, [:newline], [:code, collect_text(body)]]
end
end
# These engines are executed at compile time, embedded ruby is interpolated
register :asciidoc, InterpolateTiltEngine
register :markdown, InterpolateTiltEngine
register :textile, InterpolateTiltEngine
register :rdoc, InterpolateTiltEngine
register :creole, InterpolateTiltEngine
register :wiki, InterpolateTiltEngine
register :mediawiki, InterpolateTiltEngine
register :org, InterpolateTiltEngine
# These engines are executed at compile time
register :coffee, JavaScriptEngine, engine: TiltEngine
register :opal, JavaScriptEngine, engine: TiltEngine
register :less, TagEngine, tag: :style, attributes: { type: 'text/css' }, engine: TiltEngine
register :styl, TagEngine, tag: :style, attributes: { type: 'text/css' }, engine: TiltEngine
register :sass, TagEngine, :pretty, tag: :style, attributes: { type: 'text/css' }, engine: SassEngine
register :scss, TagEngine, :pretty, tag: :style, attributes: { type: 'text/css' }, engine: SassEngine
# These engines are precompiled, code is embedded
register :erb, ERBEngine
register :nokogiri, PrecompiledTiltEngine
register :builder, PrecompiledTiltEngine
# Embedded javascript/css
register :javascript, JavaScriptEngine
register :css, TagEngine, tag: :style, attributes: { type: 'text/css' }
# Embedded ruby code
register :ruby, RubyEngine
end
end
slim-3.0.6/lib/slim/grammar.rb 0000644 0000041 0000041 00000001057 12555545227 016220 0 ustar www-data www-data module Slim
# Slim expression grammar
# @api private
module Grammar
extend Temple::Grammar
TextTypes << :verbatim | :explicit | :implicit | :inline
Expression <<
[:slim, :control, String, Expression] |
[:slim, :output, Bool, String, Expression] |
[:slim, :interpolate, String] |
[:slim, :embedded, String, Expression] |
[:slim, :text, TextTypes, Expression] |
[:slim, :attrvalue, Bool, String]
HTMLAttr <<
[:slim, :splat, String]
end
end
slim-3.0.6/lib/slim/interpolation.rb 0000644 0000041 0000041 00000002113 12555545227 017453 0 ustar www-data www-data module Slim
# Perform interpolation of #{var_name} in the
# expressions `[:slim, :interpolate, string]`.
#
# @api private
class Interpolation < Filter
# Handle interpolate expression `[:slim, :interpolate, string]`
#
# @param [String] string Static interpolate
# @return [Array] Compiled temple expression
def on_slim_interpolate(string)
# Interpolate variables in text (#{variable}).
# Split the text into multiple dynamic and static parts.
block = [:multi]
begin
case string
when /\A\\#\{/
# Escaped interpolation
block << [:static, '#{']
string = $'
when /\A#\{((?>[^{}]|(\{(?>[^{}]|\g<1>)*\}))*)\}/
# Interpolation
string, code = $', $1
escape = code !~ /\A\{.*\}\Z/
block << [:slim, :output, escape, escape ? code : code[1..-2], [:multi]]
when /\A([#\\]?[^#\\]*([#\\][^\\#\{][^#\\]*)*)/
# Static text
block << [:static, $&]
string = $'
end
end until string.empty?
block
end
end
end
slim-3.0.6/lib/slim/end_inserter.rb 0000644 0000041 0000041 00000003622 12555545227 017253 0 ustar www-data www-data module Slim
# In Slim you don't need to close any blocks:
#
# - if Slim.awesome?
# | But of course it is!
#
# However, the parser is not smart enough (and that's a good thing) to
# automatically insert end's where they are needed. Luckily, this filter
# does *exactly* that (and it does it well!)
#
# @api private
class EndInserter < Filter
IF_RE = /\A(if|unless|else|elsif|when|rescue|ensure)\b|\bdo\s*(\|[^\|]*\|)?\s*$/
ELSE_RE = /\A(else|elsif|when|rescue|ensure)\b/
END_RE = /\Aend\b/
# Handle multi expression `[:multi, *exps]`
#
# @return [Array] Corrected Temple expression with ends inserted
def on_multi(*exps)
result = [:multi]
# This variable is true if the previous line was
# (1) a control code and (2) contained indented content.
prev_indent = false
exps.each do |exp|
if control?(exp)
raise(Temple::FilterError, 'Explicit end statements are forbidden') if exp[2] =~ END_RE
# Two control code in a row. If this one is *not*
# an else block, we should close the previous one.
append_end(result) if prev_indent && exp[2] !~ ELSE_RE
# Indent if the control code starts a block.
prev_indent = exp[2] =~ IF_RE
elsif exp[0] != :newline && prev_indent
# This is *not* a control code, so we should close the previous one.
# Ignores newlines because they will be inserted after each line.
append_end(result)
prev_indent = false
end
result << compile(exp)
end
# The last line can be a control code too.
prev_indent ? append_end(result) : result
end
private
# Appends an end
def append_end(result)
result << [:code, 'end']
end
# Checks if an expression is a Slim control code
def control?(exp)
exp[0] == :slim && exp[1] == :control
end
end
end
slim-3.0.6/lib/slim/logic_less.rb 0000644 0000041 0000041 00000000213 12555545227 016706 0 ustar www-data www-data require 'slim'
require 'slim/logic_less/filter'
require 'slim/logic_less/context'
Slim::Engine.after Slim::Interpolation, Slim::LogicLess
slim-3.0.6/lib/slim/parser.rb 0000644 0000041 0000041 00000040724 12555545227 016072 0 ustar www-data www-data # coding: utf-8
module Slim
# Parses Slim code and transforms it to a Temple expression
# @api private
class Parser < Temple::Parser
define_options :file,
:default_tag,
tabsize: 4,
code_attr_delims: {
'(' => ')',
'[' => ']',
'{' => '}',
},
attr_list_delims: {
'(' => ')',
'[' => ']',
'{' => '}',
},
shortcut: {
'#' => { attr: 'id' },
'.' => { attr: 'class' }
}
class SyntaxError < StandardError
attr_reader :error, :file, :line, :lineno, :column
def initialize(error, file, line, lineno, column)
@error = error
@file = file || '(__TEMPLATE__)'
@line = line.to_s
@lineno = lineno
@column = column
end
def to_s
line = @line.lstrip
column = @column + line.size - @line.size
%{#{error}
#{file}, Line #{lineno}, Column #{@column}
#{line}
#{' ' * column}^
}
end
end
def initialize(opts = {})
super
@attr_list_delims = options[:attr_list_delims]
@code_attr_delims = options[:code_attr_delims]
tabsize = options[:tabsize]
if tabsize > 1
@tab_re = /\G((?: {#{tabsize}})*) {0,#{tabsize-1}}\t/
@tab = '\1' + ' ' * tabsize
else
@tab_re = "\t"
@tab = ' '
end
@tag_shortcut, @attr_shortcut = {}, {}
options[:shortcut].each do |k,v|
raise ArgumentError, 'Shortcut requires :tag and/or :attr' unless (v[:attr] || v[:tag]) && (v.keys - [:attr, :tag]).empty?
@tag_shortcut[k] = v[:tag] || options[:default_tag]
if v.include?(:attr)
@attr_shortcut[k] = [v[:attr]].flatten
raise ArgumentError, 'You can only use special characters for attribute shortcuts' if k =~ /(\p{Word}|-)/
end
end
keys = Regexp.union @attr_shortcut.keys.sort_by {|k| -k.size }
@attr_shortcut_re = /\A(#{keys}+)((?:\p{Word}|-)*)/
keys = Regexp.union @tag_shortcut.keys.sort_by {|k| -k.size }
@tag_re = /\A(?:#{keys}|\*(?=[^\s]+)|(\p{Word}(?:\p{Word}|:|-)*\p{Word}|\p{Word}+))/
keys = Regexp.escape @code_attr_delims.keys.join
@code_attr_delims_re = /\A[#{keys}]/
keys = Regexp.escape @attr_list_delims.keys.join
@attr_list_delims_re = /\A\s*([#{keys}])/
@embedded_re = /\A(#{Regexp.union(Embedded.engines.keys.map(&:to_s))}):(\s*)/
keys = Regexp.escape ('"\'>='.split(//) + @attr_list_delims.flatten + @code_attr_delims.flatten).uniq.join
@attr_name = "\\A\\s*([^\0\s#{keys}]+)"
@quoted_attr_re = /#{@attr_name}\s*=(=?)\s*("|')/
@code_attr_re = /#{@attr_name}\s*=(=?)\s*/
end
# Compile string to Temple expression
#
# @param [String] str Slim code
# @return [Array] Temple expression representing the code]]
def call(str)
result = [:multi]
reset(str.split(/\r?\n/), [result])
parse_line while next_line
reset
result
end
protected
def reset(lines = nil, stacks = nil)
# Since you can indent however you like in Slim, we need to keep a list
# of how deeply indented you are. For instance, in a template like this:
#
# doctype # 0 spaces
# html # 0 spaces
# head # 1 space
# title # 4 spaces
#
# indents will then contain [0, 1, 4] (when it's processing the last line.)
#
# We uses this information to figure out how many steps we must "jump"
# out when we see an de-indented line.
@indents = []
# Whenever we want to output something, we'll *always* output it to the
# last stack in this array. So when there's a line that expects
# indentation, we simply push a new stack onto this array. When it
# processes the next line, the content will then be outputted into that
# stack.
@stacks = stacks
@lineno = 0
@lines = lines
@line = @orig_line = nil
end
def next_line
if @lines.empty?
@orig_line = @line = nil
else
@orig_line = @lines.shift
@lineno += 1
@line = @orig_line.dup
end
end
def get_indent(line)
# Figure out the indentation. Kinda ugly/slow way to support tabs,
# but remember that this is only done at parsing time.
line[/\A[ \t]*/].gsub(@tab_re, @tab).size
end
def parse_line
if @line =~ /\A\s*\Z/
@stacks.last << [:newline]
return
end
indent = get_indent(@line)
# Choose first indentation yourself
@indents << indent if @indents.empty?
# Remove the indentation
@line.lstrip!
# If there's more stacks than indents, it means that the previous
# line is expecting this line to be indented.
expecting_indentation = @stacks.size > @indents.size
if indent > @indents.last
# This line was actually indented, so we'll have to check if it was
# supposed to be indented or not.
syntax_error!('Unexpected indentation') unless expecting_indentation
@indents << indent
else
# This line was *not* indented more than the line before,
# so we'll just forget about the stack that the previous line pushed.
@stacks.pop if expecting_indentation
# This line was deindented.
# Now we're have to go through the all the indents and figure out
# how many levels we've deindented.
while indent < @indents.last && @indents.size > 1
@indents.pop
@stacks.pop
end
# This line's indentation happens lie "between" two other line's
# indentation:
#
# hello
# world
# this # <- This should not be possible!
syntax_error!('Malformed indentation') if indent != @indents.last
end
parse_line_indicators
end
def parse_line_indicators
case @line
when /\A\/!( ?)/
# HTML comment
@stacks.last << [:html, :comment, [:slim, :text, :verbatim, parse_text_block($', @indents.last + $1.size + 2)]]
when /\A\/\[\s*(.*?)\s*\]\s*\Z/
# HTML conditional comment
block = [:multi]
@stacks.last << [:html, :condcomment, $1, block]
@stacks << block
when /\A\//
# Slim comment
parse_comment_block
when /\A([\|'])( ?)/
# Found verbatim text block.
trailing_ws = $1 == "'"
@stacks.last << [:slim, :text, :verbatim, parse_text_block($', @indents.last + $2.size + 1)]
@stacks.last << [:static, ' '] if trailing_ws
when /\A
# Inline html
block = [:multi]
@stacks.last << [:multi, [:slim, :interpolate, @line], block]
@stacks << block
when /\A-/
# Found a code block.
# We expect the line to be broken or the next line to be indented.
@line.slice!(0)
block = [:multi]
@stacks.last << [:slim, :control, parse_broken_line, block]
@stacks << block
when /\A=(=?)(['<>]*)/
# Found an output block.
# We expect the line to be broken or the next line to be indented.
@line = $'
trailing_ws = $2.include?('>')
if $2.include?('\'')
deprecated_syntax '=\' for trailing whitespace is deprecated in favor of =>'
trailing_ws = true
end
block = [:multi]
@stacks.last << [:static, ' '] if $2.include?('<')
@stacks.last << [:slim, :output, $1.empty?, parse_broken_line, block]
@stacks.last << [:static, ' '] if trailing_ws
@stacks << block
when @embedded_re
# Embedded template detected. It is treated as block.
@stacks.last << [:slim, :embedded, $1, parse_text_block($', @orig_line.size - $'.size + $2.size)]
when /\Adoctype\b/
# Found doctype declaration
@stacks.last << [:html, :doctype, $'.strip]
when @tag_re
# Found a HTML tag.
@line = $' if $1
parse_tag($&)
else
unknown_line_indicator
end
@stacks.last << [:newline]
end
# Unknown line indicator found. Overwrite this method if
# you want to add line indicators to the Slim parser.
# The default implementation throws a syntax error.
def unknown_line_indicator
syntax_error! 'Unknown line indicator'
end
def parse_comment_block
while !@lines.empty? && (@lines.first =~ /\A\s*\Z/ || get_indent(@lines.first) > @indents.last)
next_line
@stacks.last << [:newline]
end
end
def parse_text_block(first_line = nil, text_indent = nil)
result = [:multi]
if !first_line || first_line.empty?
text_indent = nil
else
result << [:slim, :interpolate, first_line]
end
empty_lines = 0
until @lines.empty?
if @lines.first =~ /\A\s*\Z/
next_line
result << [:newline]
empty_lines += 1 if text_indent
else
indent = get_indent(@lines.first)
break if indent <= @indents.last
if empty_lines > 0
result << [:slim, :interpolate, "\n" * empty_lines]
empty_lines = 0
end
next_line
@line.lstrip!
# The text block lines must be at least indented
# as deep as the first line.
offset = text_indent ? indent - text_indent : 0
if offset < 0
text_indent += offset
offset = 0
end
result << [:newline] << [:slim, :interpolate, (text_indent ? "\n" : '') + (' ' * offset) + @line]
# The indentation of first line of the text block
# determines the text base indentation.
text_indent ||= indent
end
end
result
end
def parse_broken_line
broken_line = @line.strip
while broken_line =~ /[,\\]\Z/
expect_next_line
broken_line << "\n" << @line
end
broken_line
end
def parse_tag(tag)
if @tag_shortcut[tag]
@line.slice!(0, tag.size) unless @attr_shortcut[tag]
tag = @tag_shortcut[tag]
end
# Find any shortcut attributes
attributes = [:html, :attrs]
while @line =~ @attr_shortcut_re
# The class/id attribute is :static instead of :slim :interpolate,
# because we don't want text interpolation in .class or #id shortcut
syntax_error!('Illegal shortcut') unless shortcut = @attr_shortcut[$1]
shortcut.each {|a| attributes << [:html, :attr, a, [:static, $2]] }
@line = $'
end
@line =~ /\A[<>']*/
@line = $'
trailing_ws = $&.include?('>')
if $&.include?('\'')
deprecated_syntax 'tag\' for trailing whitespace is deprecated in favor of tag>'
trailing_ws = true
end
leading_ws = $&.include?('<')
parse_attributes(attributes)
tag = [:html, :tag, tag, attributes]
@stacks.last << [:static, ' '] if leading_ws
@stacks.last << tag
@stacks.last << [:static, ' '] if trailing_ws
case @line
when /\A\s*:\s*/
# Block expansion
@line = $'
if @line =~ @embedded_re
tag << [:slim, :embedded, $1, parse_text_block($', @orig_line.size - @line.size + $2.size)]
else
(@line =~ @tag_re) || syntax_error!('Expected tag')
@line = $' if $1
content = [:multi]
tag << content
i = @stacks.size
@stacks << content
parse_tag($&)
@stacks.delete_at(i)
end
when /\A\s*=(=?)(['<>]*)/
# Handle output code
@line = $'
trailing_ws2 = $2.include?('>')
if $2.include?('\'')
deprecated_syntax '=\' for trailing whitespace is deprecated in favor of =>'
trailing_ws2 = true
end
block = [:multi]
@stacks.last.insert(-2, [:static, ' ']) if !leading_ws && $2.include?('<')
tag << [:slim, :output, $1 != '=', parse_broken_line, block]
@stacks.last << [:static, ' '] if !trailing_ws && trailing_ws2
@stacks << block
when /\A\s*\/\s*/
# Closed tag. Do nothing
@line = $'
syntax_error!('Unexpected text after closed tag') unless @line.empty?
when /\A\s*\Z/
# Empty content
content = [:multi]
tag << content
@stacks << content
when /\A ?/
# Text content
tag << [:slim, :text, :inline, parse_text_block($', @orig_line.size - $'.size)]
end
end
def parse_attributes(attributes)
# Check to see if there is a delimiter right after the tag name
delimiter = nil
if @line =~ @attr_list_delims_re
delimiter = @attr_list_delims[$1]
@line = $'
end
if delimiter
boolean_attr_re = /#{@attr_name}(?=(\s|#{Regexp.escape delimiter}|\Z))/
end_re = /\A\s*#{Regexp.escape delimiter}/
end
while true
case @line
when /\A\s*\*(?=[^\s]+)/
# Splat attribute
@line = $'
attributes << [:slim, :splat, parse_ruby_code(delimiter)]
when @quoted_attr_re
# Value is quoted (static)
@line = $'
attributes << [:html, :attr, $1,
[:escape, $2.empty?, [:slim, :interpolate, parse_quoted_attribute($3)]]]
when @code_attr_re
# Value is ruby code
@line = $'
name = $1
escape = $2.empty?
value = parse_ruby_code(delimiter)
syntax_error!('Invalid empty attribute') if value.empty?
attributes << [:html, :attr, name, [:slim, :attrvalue, escape, value]]
else
break unless delimiter
case @line
when boolean_attr_re
# Boolean attribute
@line = $'
attributes << [:html, :attr, $1, [:multi]]
when end_re
# Find ending delimiter
@line = $'
break
else
# Found something where an attribute should be
@line.lstrip!
syntax_error!('Expected attribute') unless @line.empty?
# Attributes span multiple lines
@stacks.last << [:newline]
syntax_error!("Expected closing delimiter #{delimiter}") if @lines.empty?
next_line
end
end
end
end
def parse_ruby_code(outer_delimiter)
code, count, delimiter, close_delimiter = '', 0, nil, nil
# Attribute ends with space or attribute delimiter
end_re = /\A[\s#{Regexp.escape outer_delimiter.to_s}]/
until @line.empty? || (count == 0 && @line =~ end_re)
if @line =~ /\A[,\\]\Z/
code << @line << "\n"
expect_next_line
else
if count > 0
if @line[0] == delimiter[0]
count += 1
elsif @line[0] == close_delimiter[0]
count -= 1
end
elsif @line =~ @code_attr_delims_re
count = 1
delimiter, close_delimiter = $&, @code_attr_delims[$&]
end
code << @line.slice!(0)
end
end
syntax_error!("Expected closing delimiter #{close_delimiter}") if count != 0
code
end
def parse_quoted_attribute(quote)
value, count = '', 0
until count == 0 && @line[0] == quote[0]
if @line =~ /\A(\\)?\Z/
value << ($1 ? ' ' : "\n")
expect_next_line
else
if @line[0] == ?{
count += 1
elsif @line[0] == ?}
count -= 1
end
value << @line.slice!(0)
end
end
@line.slice!(0)
value
end
# Helper for raising exceptions
def syntax_error!(message)
raise SyntaxError.new(message, options[:file], @orig_line, @lineno,
@orig_line && @line ? @orig_line.size - @line.size : 0)
rescue SyntaxError => ex
# HACK: Manipulate stacktrace for Rails and other frameworks
# to find the right file.
ex.backtrace.unshift "#{options[:file]}:#{@lineno}"
raise
end
def deprecated_syntax(message)
line = @orig_line.lstrip
column = (@orig_line && @line ? @orig_line.size - @line.size : 0) + line.size - @orig_line.size
warn %{Deprecated syntax: #{message}
#{options[:file]}, Line #{@lineno}, Column #{@column}
#{line}
#{' ' * column}^
}
end
def expect_next_line
next_line || syntax_error!('Unexpected end of file')
@line.strip!
end
end
end
slim-3.0.6/lib/slim/engine.rb 0000644 0000041 0000041 00000003000 12555545227 016025 0 ustar www-data www-data # The Slim module contains all Slim related classes (e.g. Engine, Parser).
# Plugins might also reside within the Slim module (e.g. Include, Smart).
# @api public
module Slim
# Slim engine which transforms slim code to executable ruby code
# @api public
class Engine < Temple::Engine
# This overwrites some Temple default options or sets default options for Slim specific filters.
# It is recommended to set the default settings only once in the code and avoid duplication. Only use
# `define_options` when you have to override some default settings.
define_options pretty: false,
sort_attrs: true,
format: :xhtml,
attr_quote: '"',
merge_attrs: {'class' => ' '},
generator: Temple::Generators::ArrayBuffer,
default_tag: 'div'
filter :Encoding
filter :RemoveBOM
use Slim::Parser
use Slim::Embedded
use Slim::Interpolation
use Slim::Splat::Filter
use Slim::DoInserter
use Slim::EndInserter
use Slim::Controls
html :AttributeSorter
html :AttributeMerger
use Slim::CodeAttributes
use(:AttributeRemover) { Temple::HTML::AttributeRemover.new(remove_empty_attrs: options[:merge_attrs].keys) }
html :Pretty
filter :Escapable
filter :ControlFlow
filter :MultiFlattener
filter :StaticMerger
use :Generator do
options[:generator].new(options.to_hash.reject {|k,v| !options[:generator].options.valid_key?(k) })
end
end
end
slim-3.0.6/lib/slim/command.rb 0000644 0000041 0000041 00000006667 12555545227 016224 0 ustar www-data www-data require 'slim'
require 'optparse'
module Slim
Engine.set_options pretty: false
# Slim commandline interface
# @api private
class Command
def initialize(args)
@args = args
@options = {}
end
# Run command
def run
@opts = OptionParser.new(&method(:set_opts))
@opts.parse!(@args)
process
end
private
# Configure OptionParser
def set_opts(opts)
opts.on('-s', '--stdin', 'Read input from standard input instead of an input file') do
@options[:input] = $stdin
end
opts.on('--trace', 'Show a full traceback on error') do
@options[:trace] = true
end
opts.on('-c', '--compile', 'Compile only but do not run') do
@options[:compile] = true
end
opts.on('-e', '--erb', 'Convert to ERB') do
@options[:erb] = true
end
opts.on('--rails', 'Generate rails compatible code (Implies --compile)') do
Engine.set_options disable_capture: true, generator: Temple::Generators::RailsOutputBuffer
@options[:compile] = true
end
opts.on('-r', '--require library', "Load library or plugin with -r slim/plugin") do |lib|
require lib.strip
end
opts.on('-p', '--pretty', 'Produce pretty html') do
Engine.set_options pretty: true
end
opts.on('-o', '--option name=code', String, 'Set slim option') do |str|
parts = str.split('=', 2)
Engine.options[parts.first.gsub(/\A:/, '').to_sym] = eval(parts.last)
end
opts.on('-l', '--locals Hash|YAML|JSON', String, 'Set local variables') do |locals|
@options[:locals] =
if locals =~ /\A\s*\{\s*\p{Word}+:/
eval(locals)
else
require 'yaml'
if RUBY_ENGINE == 'rbx'
begin
require 'psych'
rescue LoadError
$stderr.puts 'Please install psych gem as Rubunius ships with an old YAML engine.'
end
end
YAML.load(locals)
end
end
opts.on_tail('-h', '--help', 'Show this message') do
puts opts
exit
end
opts.on_tail('-v', '--version', 'Print version') do
puts "Slim #{VERSION}"
exit
end
end
# Process command
def process
args = @args.dup
unless @options[:input]
file = args.shift
if file
@options[:file] = file
@options[:input] = File.open(file, 'r')
else
@options[:file] = 'STDIN'
@options[:input] = $stdin
end
end
locals = @options.delete(:locals) || {}
result =
if @options[:erb]
require 'slim/erb_converter'
ERBConverter.new(file: @options[:file]).call(@options[:input].read)
elsif @options[:compile]
Engine.new(file: @options[:file]).call(@options[:input].read)
else
Template.new(@options[:file]) { @options[:input].read }.render(nil, locals)
end
rescue Exception => ex
raise ex if @options[:trace] || SystemExit === ex
$stderr.print "#{ex.class}: " if ex.class != RuntimeError
$stderr.puts ex.message
$stderr.puts ' Use --trace for backtrace.'
exit 1
else
unless @options[:output]
file = args.shift
@options[:output] = file ? File.open(file, 'w') : $stdout
end
@options[:output].puts(result)
exit 0
end
end
end
slim-3.0.6/lib/slim/code_attributes.rb 0000644 0000041 0000041 00000004102 12555545227 017744 0 ustar www-data www-data module Slim
# @api private
class CodeAttributes < Filter
define_options :merge_attrs
# Handle attributes expression `[:html, :attrs, *attrs]`
#
# @param [Array] attrs Array of temple expressions
# @return [Array] Compiled temple expression
def on_html_attrs(*attrs)
[:multi, *attrs.map {|a| compile(a) }]
end
# Handle attribute expression `[:html, :attr, name, value]`
#
# @param [String] name Attribute name
# @param [Array] value Value expression
# @return [Array] Compiled temple expression
def on_html_attr(name, value)
if value[0] == :slim && value[1] == :attrvalue && !options[:merge_attrs][name]
# We handle the attribute as a boolean attribute
escape, code = value[2], value[3]
case code
when 'true'
[:html, :attr, name, [:multi]]
when 'false', 'nil'
[:multi]
else
tmp = unique_name
[:multi,
[:code, "#{tmp} = #{code}"],
[:if, tmp,
[:if, "#{tmp} == true",
[:html, :attr, name, [:multi]],
[:html, :attr, name, [:escape, escape, [:dynamic, tmp]]]]]]
end
else
# Attribute with merging
@attr = name
super
end
end
# Handle attribute expression `[:slim, :attrvalue, escape, code]`
#
# @param [Boolean] escape Escape html
# @param [String] code Ruby code
# @return [Array] Compiled temple expression
def on_slim_attrvalue(escape, code)
# We perform attribute merging on Array values
if delimiter = options[:merge_attrs][@attr]
tmp = unique_name
[:multi,
[:code, "#{tmp} = #{code}"],
[:if, "Array === #{tmp}",
[:multi,
[:code, "#{tmp} = #{tmp}.flatten"],
[:code, "#{tmp}.map!(&:to_s)"],
[:code, "#{tmp}.reject!(&:empty?)"],
[:escape, escape, [:dynamic, "#{tmp}.join(#{delimiter.inspect})"]]],
[:escape, escape, [:dynamic, tmp]]]]
else
[:escape, escape, [:dynamic, code]]
end
end
end
end
slim-3.0.6/lib/slim/filter.rb 0000644 0000041 0000041 00000001407 12555545227 016056 0 ustar www-data www-data module Slim
# Base class for Temple filters used in Slim
#
# This base filter passes everything through and allows
# to override only some methods without affecting the rest
# of the expression.
#
# @api private
class Filter < Temple::HTML::Filter
# Pass-through handler
def on_slim_text(type, content)
[:slim, :text, type, compile(content)]
end
# Pass-through handler
def on_slim_embedded(type, content)
[:slim, :embedded, type, compile(content)]
end
# Pass-through handler
def on_slim_control(code, content)
[:slim, :control, code, compile(content)]
end
# Pass-through handler
def on_slim_output(escape, code, content)
[:slim, :output, escape, code, compile(content)]
end
end
end
slim-3.0.6/lib/slim/smart.rb 0000644 0000041 0000041 00000000425 12555545227 015716 0 ustar www-data www-data require 'slim'
require 'slim/smart/filter'
require 'slim/smart/escaper'
require 'slim/smart/parser'
Slim::Engine.replace Slim::Parser, Slim::Smart::Parser
Slim::Engine.after Slim::Smart::Parser, Slim::Smart::Filter
Slim::Engine.after Slim::Interpolation, Slim::Smart::Escaper
slim-3.0.6/lib/slim/include.rb 0000644 0000041 0000041 00000003401 12555545227 016210 0 ustar www-data www-data require 'slim'
module Slim
# Handles inlined includes
#
# Slim files are compiled, non-Slim files are included as text with `#{interpolation}`
#
# @api private
class Include < Slim::Filter
define_options :file, include_dirs: [Dir.pwd, '.']
def on_html_tag(tag, attributes, content = nil)
return super if tag != 'include'
name = content.to_a.flatten.select {|s| String === s }.join
raise ArgumentError, 'Invalid include statement' unless attributes == [:html, :attrs] && !name.empty?
unless file = find_file(name)
name = "#{name}.slim" if name !~ /\.slim\Z/i
file = find_file(name)
end
raise Temple::FilterError, "'#{name}' not found in #{options[:include_dirs].join(':')}" unless file
content = File.read(file)
if file =~ /\.slim\Z/i
Thread.current[:slim_include_engine].call(content)
else
[:slim, :interpolate, content]
end
end
protected
def find_file(name)
current_dir = File.dirname(File.expand_path(options[:file]))
options[:include_dirs].map {|dir| File.expand_path(File.join(dir, name), current_dir) }.find {|file| File.file?(file) }
end
end
class Engine
after Slim::Parser, Slim::Include
after Slim::Include, :stop do |exp|
throw :stop, exp if Thread.current[:slim_include_level] > 1
exp
end
# @api private
alias call_without_include call
# @api private
def call(input)
Thread.current[:slim_include_engine] = self
Thread.current[:slim_include_level] ||= 0
Thread.current[:slim_include_level] += 1
catch(:stop) { call_without_include(input) }
ensure
Thread.current[:slim_include_engine] = nil if (Thread.current[:slim_include_level] -= 1) == 0
end
end
end
slim-3.0.6/lib/slim/version.rb 0000644 0000041 0000041 00000000114 12555545227 016250 0 ustar www-data www-data module Slim
# Slim version string
# @api public
VERSION = '3.0.6'
end
slim-3.0.6/lib/slim/controls.rb 0000644 0000041 0000041 00000004004 12555545227 016430 0 ustar www-data www-data module Slim
# @api private
class Controls < Filter
define_options :disable_capture
IF_RE = /\A(if|unless)\b|\bdo\s*(\|[^\|]*\|)?\s*$/
# Handle control expression `[:slim, :control, code, content]`
#
# @param [String] code Ruby code
# @param [Array] content Temple expression
# @return [Array] Compiled temple expression
def on_slim_control(code, content)
[:multi,
[:code, code],
compile(content)]
end
# Handle output expression `[:slim, :output, escape, code, content]`
#
# @param [Boolean] escape Escape html
# @param [String] code Ruby code
# @param [Array] content Temple expression
# @return [Array] Compiled temple expression
def on_slim_output(escape, code, content)
if code =~ IF_RE
tmp = unique_name
[:multi,
# Capture the result of the code in a variable. We can't do
# `[:dynamic, code]` because it's probably not a complete
# expression (which is a requirement for Temple).
[:block, "#{tmp} = #{code}",
# Capture the content of a block in a separate buffer. This means
# that `yield` will not output the content to the current buffer,
# but rather return the output.
#
# The capturing can be disabled with the option :disable_capture.
# Output code in the block writes directly to the output buffer then.
# Rails handles this by replacing the output buffer for helpers.
options[:disable_capture] ? compile(content) : [:capture, unique_name, compile(content)]],
# Output the content.
[:escape, escape, [:dynamic, tmp]]]
else
[:multi, [:escape, escape, [:dynamic, code]], content]
end
end
# Handle text expression `[:slim, :text, type, content]`
#
# @param [Symbol] type Text type
# @param [Array] content Temple expression
# @return [Array] Compiled temple expression
def on_slim_text(type, content)
compile(content)
end
end
end
slim-3.0.6/lib/slim/splat/ 0000755 0000041 0000041 00000000000 12555545227 015365 5 ustar www-data www-data slim-3.0.6/lib/slim/splat/filter.rb 0000644 0000041 0000041 00000005674 12555545227 017213 0 ustar www-data www-data module Slim
module Splat
# @api private
class Filter < ::Slim::Filter
define_options :merge_attrs, :attr_quote, :sort_attrs, :default_tag, :format, :disable_capture,
hyphen_attrs: %w(data aria), use_html_safe: ''.respond_to?(:html_safe?)
def call(exp)
@splat_options = nil
exp = compile(exp)
if @splat_options
opts = options.to_hash.reject {|k,v| !Filter.options.valid_key?(k) }.inspect
[:multi, [:code, "#{@splat_options} = #{opts}"], exp]
else
exp
end
end
# Handle tag expression `[:html, :tag, name, attrs, content]`
#
# @param [String] name Tag name
# @param [Array] attrs Temple expression
# @param [Array] content Temple expression
# @return [Array] Compiled temple expression
def on_html_tag(name, attrs, content = nil)
return super if name != '*'
builder, block = make_builder(attrs[2..-1])
if content
[:multi,
block,
[:slim, :output, false,
"#{builder}.build_tag #{empty_exp?(content) ? '{}' : 'do'}",
compile(content)]]
else
[:multi,
block,
[:dynamic, "#{builder}.build_tag"]]
end
end
# Handle attributes expression `[:html, :attrs, *attrs]`
#
# @param [Array] attrs Array of temple expressions
# @return [Array] Compiled temple expression
def on_html_attrs(*attrs)
if attrs.any? {|attr| splat?(attr) }
builder, block = make_builder(attrs)
[:multi,
block,
[:dynamic, "#{builder}.build_attrs"]]
else
super
end
end
protected
def splat?(attr)
# Splat attribute given
attr[0] == :slim && attr[1] == :splat ||
# Hyphenated attribute also needs splat handling
(attr[0] == :html && attr[1] == :attr && options[:hyphen_attrs].include?(attr[2]) &&
attr[3][0] == :slim && attr[3][1] == :attrvalue)
end
def make_builder(attrs)
@splat_options ||= unique_name
builder = unique_name
result = [:multi, [:code, "#{builder} = ::Slim::Splat::Builder.new(#{@splat_options})"]]
attrs.each do |attr|
result <<
if attr[0] == :html && attr[1] == :attr
if attr[3][0] == :slim && attr[3][1] == :attrvalue
[:code, "#{builder}.code_attr(#{attr[2].inspect}, #{attr[3][2]}, (#{attr[3][3]}))"]
else
tmp = unique_name
[:multi,
[:capture, tmp, compile(attr[3])],
[:code, "#{builder}.attr(#{attr[2].inspect}, #{tmp})"]]
end
elsif attr[0] == :slim && attr[1] == :splat
[:code, "#{builder}.splat_attrs((#{attr[2]}))"]
else
attr
end
end
return builder, result
end
end
end
end
slim-3.0.6/lib/slim/splat/builder.rb 0000644 0000041 0000041 00000006036 12555545227 017345 0 ustar www-data www-data module Slim
module Splat
# @api private
class Builder
def initialize(options)
@options = options
@attrs = {}
end
def code_attr(name, escape, value)
if delim = @options[:merge_attrs][name]
value = Array === value ? value.join(delim) : value.to_s
attr(name, escape_html(escape, value)) unless value.empty?
elsif @options[:hyphen_attrs].include?(name) && Hash === value
hyphen_attr(name, escape, value)
elsif value != false && value != nil
attr(name, escape_html(value != true && escape, value))
end
end
def splat_attrs(splat)
splat.each do |name, value|
code_attr(name.to_s, true, value)
end
end
def attr(name, value)
if @attrs[name]
if delim = @options[:merge_attrs][name]
@attrs[name] += delim + value.to_s
else
raise("Multiple #{name} attributes specified")
end
else
@attrs[name] = value
end
end
def build_tag(&block)
tag = @attrs.delete('tag').to_s
tag = @options[:default_tag] if tag.empty?
if block
# This is a bit of a hack to get a universal capturing.
#
# TODO: Add this as a helper somewhere to solve these capturing issues
# once and for all.
#
# If we have Slim capturing disabled and the scope defines the method `capture` (i.e. Rails)
# we use this method to capture the content.
#
# otherwise we just use normal Slim capturing (yield).
#
# See https://github.com/slim-template/slim/issues/591
# https://github.com/slim-template/slim#helpers-capturing-and-includes
#
content =
if @options[:disable_capture] && (scope = block.binding.eval('self')).respond_to?(:capture)
scope.capture(&block)
else
yield
end
"<#{tag}#{build_attrs}>#{content}#{tag}>"
else
"<#{tag}#{build_attrs} />"
end
end
def build_attrs
attrs = @options[:sort_attrs] ? @attrs.sort_by(&:first) : @attrs
attrs.map do |k, v|
if v == true
if @options[:format] == :xhtml
" #{k}=#{@options[:attr_quote]}#{@options[:attr_quote]}"
else
" #{k}"
end
else
" #{k}=#{@options[:attr_quote]}#{v}#{@options[:attr_quote]}"
end
end.join
end
private
def hyphen_attr(name, escape, value)
if Hash === value
value.each do |n, v|
hyphen_attr("#{name}-#{n.to_s.gsub('_', '-')}", escape, v)
end
else
attr(name, escape_html(value != true && escape, value))
end
end
def escape_html(escape, value)
return value unless escape
@options[:use_html_safe] ? Temple::Utils.escape_html_safe(value) : Temple::Utils.escape_html(value)
end
end
end
end
slim-3.0.6/lib/slim/smart/ 0000755 0000041 0000041 00000000000 12555545227 015370 5 ustar www-data www-data slim-3.0.6/lib/slim/smart/parser.rb 0000644 0000041 0000041 00000002431 12555545227 017211 0 ustar www-data www-data # coding: utf-8
module Slim
module Smart
# @api private
class Parser < ::Slim::Parser
define_options implicit_text: true
def initialize(opts = {})
super
word_re = options[:implicit_text] ? '[_a-z0-9]' : '\p{Word}'
attr_keys = Regexp.union(@attr_shortcut.keys.sort_by {|k| -k.size } )
@attr_shortcut_re = /\A(#{attr_keys}+)((?:\p{Word}|-)*)/
tag_keys = Regexp.union((@tag_shortcut.keys - @attr_shortcut.keys).sort_by {|k| -k.size } )
@tag_re = /\A(?:#{attr_keys}(?=-*\p{Word})|#{tag_keys}|\*(?=[^\s]+)|(#{word_re}(?:#{word_re}|:|-)*#{word_re}|#{word_re}+))/
end
def unknown_line_indicator
if @line =~ /\A>( ?)/
# Found explicit text block.
@stacks.last << [:slim, :text, :explicit, parse_text_block($', @indents.last + $1.size + 1)]
else
unless options[:implicit_text]
syntax_error! 'Illegal shortcut' if @line =~ @attr_shortcut_re
super
end
# Found implicit smart text block.
if line = @lines.first
indent = ( line =~ /\A\s*\Z/ ? @indents.last + 1 : get_indent(line) )
end
@stacks.last << [:slim, :text, :implicit, parse_text_block(@line, indent)]
end
end
end
end
end
slim-3.0.6/lib/slim/smart/filter.rb 0000644 0000041 0000041 00000006445 12555545227 017213 0 ustar www-data www-data module Slim
module Smart
# Perform newline processing in the
# expressions `[:slim, :text, type, Expression]`.
#
# @api private
class Filter < ::Slim::Filter
define_options smart_text: true,
smart_text_end_chars: '([{',
smart_text_begin_chars: ',.;:!?)]}'
def initialize(opts = {})
super
@active = @prepend = @append = false
@prepend_re = /\A#{chars_re(options[:smart_text_begin_chars])}/
@append_re = /#{chars_re(options[:smart_text_end_chars])}\Z/
end
def call(exp)
if options[:smart_text]
super
else
exp
end
end
def on_multi(*exps)
# The [:multi] blocks serve two purposes.
# On outer level, they collect the building blocks like
# tags, verbatim text, and implicit/explicit text.
# Within a text block, they collect the individual
# lines in [:slim, :interpolate, string] blocks.
#
# Our goal here is to decide when we want to prepend and
# append newlines to those individual interpolated lines.
# We basically want the text to come out as it was originally entered,
# while removing newlines next to the enclosing tags.
#
# On outer level, we choose to prepend every time, except
# right after the opening tag or after other text block.
# We also use the append flag to recognize the last expression
# before the closing tag, as we don't want to append newline there.
#
# Within text block, we prepend only before the first line unless
# the outer level tells us not to, and we append only after the last line,
# unless the outer level tells us it is the last line before the closing tag.
# Of course, this is later subject to the special begin/end characters
# which may further suppress the newline at the corresponding line boundary.
# Also note that the lines themselves are already correctly separated by newlines,
# so we don't have to worry about that at all.
block = [:multi]
prev = nil
last_exp = exps.reject{ |exp| exp.first == :newline }.last unless @active && @append
exps.each do |exp|
@append = exp.equal?(last_exp)
if @active
@prepend = false if prev
else
@prepend = prev && ( prev.first != :slim || prev[1] != :text )
end
block << compile(exp)
prev = exp unless exp.first == :newline
end
block
end
def on_slim_text(type, content)
@active = type != :verbatim
[:slim, :text, type, compile(content)]
ensure
@active = false
end
def on_slim_text_inline(content)
# Inline text is not wrapped in multi block, so set it up as if it was.
@prepend = false
@append = true
on_slim_text(:inline, content)
end
def on_slim_interpolate(string)
if @active
string = "\n" + string if @prepend && string !~ @prepend_re
string += "\n" if @append && string !~ @append_re
end
[:slim, :interpolate, string]
end
private
def chars_re(string)
Regexp.union(string.split(//))
end
end
end
end
slim-3.0.6/lib/slim/smart/escaper.rb 0000644 0000041 0000041 00000001742 12555545227 017343 0 ustar www-data www-data module Slim
module Smart
# Perform smart entity escaping in the
# expressions `[:slim, :text, type, Expression]`.
#
# @api private
class Escaper < ::Slim::Filter
define_options smart_text_escaping: true
def call(exp)
if options[:smart_text_escaping]
super
else
exp
end
end
def on_slim_text(type, content)
[:escape, type != :verbatim, [:slim, :text, type, compile(content)]]
end
def on_static(string)
# Prevent obvious &foo; and Ӓ and ÿ entities from escaping.
block = [:multi]
until string.empty?
case string
when /\A&(\w+|#x[0-9a-f]+|#\d+);/i
# Entity.
block << [:escape, false, [:static, $&]]
string = $'
when /\A&?[^&]*/
# Other text.
block << [:static, $&]
string = $'
end
end
block
end
end
end
end
slim-3.0.6/lib/slim/do_inserter.rb 0000644 0000041 0000041 00000002146 12555545227 017107 0 ustar www-data www-data module Slim
# In Slim you don't need the do keyword sometimes. This
# filter adds the missing keyword.
#
# - 10.times
# | Hello
#
# @api private
class DoInserter < Filter
BLOCK_REGEX = /(\A(if|unless|else|elsif|when|begin|rescue|ensure|case)\b)|\bdo\s*(\|[^\|]*\|\s*)?\Z/
# Handle control expression `[:slim, :control, code, content]`
#
# @param [String] code Ruby code
# @param [Array] content Temple expression
# @return [Array] Compiled temple expression
def on_slim_control(code, content)
code = code + ' do' unless code =~ BLOCK_REGEX || empty_exp?(content)
[:slim, :control, code, compile(content)]
end
# Handle output expression `[:slim, :output, escape, code, content]`
#
# @param [Boolean] escape Escape html
# @param [String] code Ruby code
# @param [Array] content Temple expression
# @return [Array] Compiled temple expression
def on_slim_output(escape, code, content)
code = code + ' do' unless code =~ BLOCK_REGEX || empty_exp?(content)
[:slim, :output, escape, code, compile(content)]
end
end
end
slim-3.0.6/lib/slim/translator.rb 0000644 0000041 0000041 00000005605 12555545227 016766 0 ustar www-data www-data require 'slim'
module Slim
# @api private
class Translator < Filter
define_options :tr,
tr_mode: :dynamic,
tr_fn: '_'
if defined?(::I18n)
set_options tr_fn: '::Slim::Translator.i18n_text',
tr: true
elsif defined?(::GetText)
set_options tr_fn: '::GetText._',
tr: true
elsif defined?(::FastGettext)
set_options tr_fn: '::FastGettext::Translation._',
tr: true
end
def self.i18n_text(text)
I18n.t!(text)
rescue I18n::MissingTranslationData
text
end
def self.i18n_key(text)
key = text.parameterize.underscore
I18n.t!(key)
rescue I18n::MissingTranslationData
text
end
def call(exp)
options[:tr] ? super : exp
end
def initialize(opts = {})
super
case options[:tr_mode]
when :static
@translator = StaticTranslator.new(tr_fn: options[:tr_fn])
when :dynamic
@translator = DynamicTranslator.new(tr_fn: options[:tr_fn])
else
raise ArgumentError, "Invalid translator mode #{options[:tr_mode].inspect}"
end
end
def on_slim_text(type, exp)
[:slim, :text, type, @translator.call(exp)]
end
private
class StaticTranslator < Filter
define_options :tr_fn
def initialize(opts = {})
super
@translate = eval("proc {|string| #{options[:tr_fn]}(string) }")
end
def call(exp)
@text, @captures = '', []
result = compile(exp)
text = @translate.call(@text)
while text =~ /%(\d+)/
result << [:static, $`] << @captures[$1.to_i - 1]
text = $'
end
result << [:static, text]
end
def on_static(text)
@text << text
[:multi]
end
def on_slim_output(escape, code, content)
@captures << [:slim, :output, escape, code, content]
@text << "%#{@captures.size}"
[:multi]
end
end
class DynamicTranslator < Filter
define_options :tr_fn
def call(exp)
@captures_count, @captures_var, @text = 0, unique_name, ''
result = compile(exp)
if @captures_count > 0
result.insert(1, [:code, "#{@captures_var}=[]"])
result << [:slim, :output, false, "#{options[:tr_fn]}(#{@text.inspect}).gsub(/%(\\d+)/) { #{@captures_var}[$1.to_i-1] }", [:multi]]
else
result << [:slim, :output, false, "#{options[:tr_fn]}(#{@text.inspect})", [:multi]]
end
end
def on_static(text)
@text << text
[:multi]
end
def on_slim_output(escape, code, content)
@captures_count += 1
@text << "%#{@captures_count}"
[:capture, "#{@captures_var}[#{@captures_count-1}]", [:slim, :output, escape, code, content]]
end
end
end
end
Slim::Engine.before Slim::EndInserter, Slim::Translator
slim-3.0.6/lib/slim/logic_less/ 0000755 0000041 0000041 00000000000 12555545227 016365 5 ustar www-data www-data slim-3.0.6/lib/slim/logic_less/context.rb 0000644 0000041 0000041 00000005764 12555545227 020412 0 ustar www-data www-data module Slim
class LogicLess
# @api private
class Context
def initialize(dict, lookup)
@scope = [Scope.new(dict, lookup)]
end
def [](name)
scope[name]
end
def lambda(name)
scope.lambda(name) do |*dict|
if dict.empty?
yield
else
new_scope do
dict.inject('') do |result, d|
scope.dict = d
result << yield
end
end
end
end
end
def section(name)
if dict = scope[name]
if !dict.respond_to?(:has_key?) && dict.respond_to?(:each)
new_scope do
dict.each do |d|
scope.dict = d
yield
end
end
else
new_scope(dict) { yield }
end
end
end
def inverted_section(name)
value = scope[name]
yield if !value || (value.respond_to?(:empty?) && value.empty?)
end
def to_s
scope.to_s
end
private
class Scope
attr_reader :lookup
attr_writer :dict
def initialize(dict, lookup, parent = nil)
@dict, @lookup, @parent = dict, lookup, parent
end
def lambda(name, &block)
@lookup.each do |lookup|
case lookup
when :method
return @dict.send(name, &block) if @dict.respond_to?(name)
when :symbol
return @dict[name].call(&block) if has_key?(name)
when :string
return @dict[name.to_s].call(&block) if has_key?(name.to_s)
when :instance_variable
var_name = "@#{name}"
return @dict.instance_variable_get(var_name).call(&block) if instance_variable?(var_name)
end
end
@parent.lambda(name) if @parent
end
def [](name)
@lookup.each do |lookup|
case lookup
when :method
return @dict.send(name) if @dict.respond_to?(name)
when :symbol
return @dict[name] if has_key?(name)
when :string
return @dict[name.to_s] if has_key?(name.to_s)
when :instance_variable
var_name = "@#{name}"
return @dict.instance_variable_get(var_name) if instance_variable?(var_name)
end
end
@parent[name] if @parent
end
def to_s
@dict.to_s
end
private
def has_key?(name)
@dict.respond_to?(:has_key?) && @dict.has_key?(name)
end
def instance_variable?(name)
begin
@dict.instance_variable_defined?(name)
rescue NameError
false
end
end
end
def scope
@scope.last
end
def new_scope(dict = nil)
@scope << Scope.new(dict, scope.lookup, scope)
yield
ensure
@scope.pop
end
end
end
end
slim-3.0.6/lib/slim/logic_less/filter.rb 0000644 0000041 0000041 00000004271 12555545227 020203 0 ustar www-data www-data module Slim
# Handle logic less mode
# This filter can be activated with the option "logic_less"
# @api private
class LogicLess < Filter
# Default dictionary access order, change it with the option :dictionary_access
DEFAULT_ACCESS_ORDER = [:symbol, :string, :method, :instance_variable].freeze
define_options logic_less: true,
dictionary: 'self',
dictionary_access: DEFAULT_ACCESS_ORDER
def initialize(opts = {})
super
access = [options[:dictionary_access]].flatten.compact
access.each do |type|
raise ArgumentError, "Invalid dictionary access #{type.inspect}" unless DEFAULT_ACCESS_ORDER.include?(type)
end
raise ArgumentError, 'Option dictionary access is missing' if access.empty?
@access = access.inspect
end
def call(exp)
if options[:logic_less]
@context = unique_name
[:multi,
[:code, "#{@context} = ::Slim::LogicLess::Context.new(#{options[:dictionary]}, #{@access})"],
super]
else
exp
end
end
# Interpret control blocks as sections or inverted sections
def on_slim_control(name, content)
method =
if name =~ /\A!\s*(.*)/
name = $1
'inverted_section'
else
'section'
end
[:block, "#{@context}.#{method}(#{name.to_sym.inspect}) do", compile(content)]
end
def on_slim_output(escape, name, content)
[:slim, :output, escape, empty_exp?(content) ? access(name) :
"#{@context}.lambda(#{name.to_sym.inspect}) do", compile(content)]
end
def on_slim_attrvalue(escape, value)
[:slim, :attrvalue, escape, access(value)]
end
def on_slim_splat(code)
[:slim, :splat, access(code)]
end
def on_dynamic(code)
raise Temple::FilterError, 'Embedded code is forbidden in logic less mode'
end
def on_code(code)
raise Temple::FilterError, 'Embedded code is forbidden in logic less mode'
end
private
def access(name)
case name
when 'yield'
'yield'
when 'self'
"#{@context}.to_s"
else
"#{@context}[#{name.to_sym.inspect}]"
end
end
end
end
slim-3.0.6/lib/slim/template.rb 0000644 0000041 0000041 00000001670 12555545227 016406 0 ustar www-data www-data module Slim
# Tilt template implementation for Slim
# @api public
Template = Temple::Templates::Tilt(Slim::Engine, register_as: :slim)
if defined?(::ActionView)
# Rails template implementation for Slim
# @api public
RailsTemplate = Temple::Templates::Rails(Slim::Engine,
register_as: :slim,
# Use rails-specific generator. This is necessary
# to support block capturing and streaming.
generator: Temple::Generators::RailsOutputBuffer,
# Disable the internal slim capturing.
# Rails takes care of the capturing by itself.
disable_capture: true,
streaming: true)
end
end
slim-3.0.6/lib/slim.rb 0000644 0000041 0000041 00000000536 12555545227 014573 0 ustar www-data www-data require 'temple'
require 'slim/parser'
require 'slim/filter'
require 'slim/do_inserter'
require 'slim/end_inserter'
require 'slim/embedded'
require 'slim/interpolation'
require 'slim/controls'
require 'slim/splat/filter'
require 'slim/splat/builder'
require 'slim/code_attributes'
require 'slim/engine'
require 'slim/template'
require 'slim/version'
slim-3.0.6/metadata.yml 0000644 0000041 0000041 00000012771 12555545227 015043 0 ustar www-data www-data --- !ruby/object:Gem::Specification
name: slim
version: !ruby/object:Gem::Version
version: 3.0.6
platform: ruby
authors:
- Daniel Mendler
- Andrew Stone
- Fred Wu
autorequire:
bindir: bin
cert_chain: []
date: 2015-06-05 00:00:00.000000000 Z
dependencies:
- !ruby/object:Gem::Dependency
name: temple
requirement: !ruby/object:Gem::Requirement
requirements:
- - "~>"
- !ruby/object:Gem::Version
version: 0.7.3
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
requirements:
- - "~>"
- !ruby/object:Gem::Version
version: 0.7.3
- !ruby/object:Gem::Dependency
name: tilt
requirement: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
version: 1.3.3
- - "<"
- !ruby/object:Gem::Version
version: '2.1'
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
version: 1.3.3
- - "<"
- !ruby/object:Gem::Version
version: '2.1'
description: Slim is a template language whose goal is reduce the syntax to the essential
parts without becoming cryptic.
email:
- mail@daniel-mendler.de
- andy@stonean.com
- ifredwu@gmail.com
executables:
- slimrb
extensions: []
extra_rdoc_files: []
files:
- ".gitignore"
- ".travis.yml"
- ".yardopts"
- CHANGES
- Gemfile
- LICENSE
- README.jp.md
- README.md
- Rakefile
- benchmarks/context.rb
- benchmarks/profile-parser.rb
- benchmarks/profile-render.rb
- benchmarks/run-benchmarks.rb
- benchmarks/run-diffbench.rb
- benchmarks/view.erb
- benchmarks/view.haml
- benchmarks/view.slim
- bin/slimrb
- doc/include.md
- doc/jp/include.md
- doc/jp/logic_less.md
- doc/jp/smart.md
- doc/jp/translator.md
- doc/logic_less.md
- doc/smart.md
- doc/translator.md
- lib/slim.rb
- lib/slim/code_attributes.rb
- lib/slim/command.rb
- lib/slim/controls.rb
- lib/slim/do_inserter.rb
- lib/slim/embedded.rb
- lib/slim/end_inserter.rb
- lib/slim/engine.rb
- lib/slim/erb_converter.rb
- lib/slim/filter.rb
- lib/slim/grammar.rb
- lib/slim/include.rb
- lib/slim/interpolation.rb
- lib/slim/logic_less.rb
- lib/slim/logic_less/context.rb
- lib/slim/logic_less/filter.rb
- lib/slim/parser.rb
- lib/slim/smart.rb
- lib/slim/smart/escaper.rb
- lib/slim/smart/filter.rb
- lib/slim/smart/parser.rb
- lib/slim/splat/builder.rb
- lib/slim/splat/filter.rb
- lib/slim/template.rb
- lib/slim/translator.rb
- lib/slim/version.rb
- slim.gemspec
- test/core/helper.rb
- test/core/test_code_blocks.rb
- test/core/test_code_escaping.rb
- test/core/test_code_evaluation.rb
- test/core/test_code_output.rb
- test/core/test_code_structure.rb
- test/core/test_commands.rb
- test/core/test_embedded_engines.rb
- test/core/test_encoding.rb
- test/core/test_erb_converter.rb
- test/core/test_html_attributes.rb
- test/core/test_html_escaping.rb
- test/core/test_html_structure.rb
- test/core/test_parser_errors.rb
- test/core/test_pretty.rb
- test/core/test_ruby_errors.rb
- test/core/test_slim_template.rb
- test/core/test_tabs.rb
- test/core/test_text_interpolation.rb
- test/core/test_thread_options.rb
- test/core/test_unicode.rb
- test/include/files/recursive.slim
- test/include/files/slimfile.slim
- test/include/files/subdir/test.slim
- test/include/files/textfile
- test/include/test_include.rb
- test/literate/TESTS.md
- test/literate/helper.rb
- test/literate/run.rb
- test/logic_less/test_logic_less.rb
- test/rails/Rakefile
- test/rails/app/controllers/application_controller.rb
- test/rails/app/controllers/entries_controller.rb
- test/rails/app/controllers/slim_controller.rb
- test/rails/app/helpers/application_helper.rb
- test/rails/app/models/entry.rb
- test/rails/app/views/entries/edit.html.slim
- test/rails/app/views/layouts/application.html.slim
- test/rails/app/views/slim/_partial.html.slim
- test/rails/app/views/slim/content_for.html.slim
- test/rails/app/views/slim/erb.html.erb
- test/rails/app/views/slim/form_for.html.slim
- test/rails/app/views/slim/helper.html.slim
- test/rails/app/views/slim/integers.html.slim
- test/rails/app/views/slim/no_layout.html.slim
- test/rails/app/views/slim/normal.html.slim
- test/rails/app/views/slim/partial.html.slim
- test/rails/app/views/slim/splat.html.slim
- test/rails/app/views/slim/thread_options.html.slim
- test/rails/app/views/slim/variables.html.slim
- test/rails/app/views/slim/xml.slim
- test/rails/config.ru
- test/rails/config/application.rb
- test/rails/config/boot.rb
- test/rails/config/environment.rb
- test/rails/config/environments/test.rb
- test/rails/config/initializers/backtrace_silencers.rb
- test/rails/config/initializers/inflections.rb
- test/rails/config/initializers/mime_types.rb
- test/rails/config/initializers/secret_token.rb
- test/rails/config/initializers/session_store.rb
- test/rails/config/locales/en.yml
- test/rails/config/routes.rb
- test/rails/script/rails
- test/rails/test/helper.rb
- test/rails/test/test_slim.rb
- test/smart/test_smart_text.rb
- test/translator/test_translator.rb
homepage: http://slim-lang.com/
licenses:
- MIT
metadata: {}
post_install_message:
rdoc_options: []
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
version: 1.9.2
required_rubygems_version: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
version: '0'
requirements: []
rubyforge_project:
rubygems_version: 2.2.2
signing_key:
specification_version: 4
summary: Slim is a template language.
test_files: []
has_rdoc:
slim-3.0.6/test/ 0000755 0000041 0000041 00000000000 12555545227 013507 5 ustar www-data www-data slim-3.0.6/test/include/ 0000755 0000041 0000041 00000000000 12555545227 015132 5 ustar www-data www-data slim-3.0.6/test/include/files/ 0000755 0000041 0000041 00000000000 12555545227 016234 5 ustar www-data www-data slim-3.0.6/test/include/files/recursive.slim 0000644 0000041 0000041 00000000005 12555545227 021124 0 ustar www-data www-data | rec slim-3.0.6/test/include/files/slimfile.slim 0000644 0000041 0000041 00000000041 12555545227 020721 0 ustar www-data www-data | slim1
include recursive
| slim2 slim-3.0.6/test/include/files/subdir/ 0000755 0000041 0000041 00000000000 12555545227 017524 5 ustar www-data www-data slim-3.0.6/test/include/files/subdir/test.slim 0000644 0000041 0000041 00000000010 12555545227 021360 0 ustar www-data www-data | subdir slim-3.0.6/test/include/files/textfile 0000644 0000041 0000041 00000000012 12555545227 017774 0 ustar www-data www-data 1+2=#{1+2} slim-3.0.6/test/include/test_include.rb 0000644 0000041 0000041 00000001140 12555545227 020135 0 ustar www-data www-data require 'helper'
require 'slim/include'
class TestSlimInclude < TestSlim
def test_include
source = %q{
br/
a: include slimfile
b: include textfile
c: include slimfile.slim
d: include subdir/test
}
assert_html ' slim1recslim21+2=3slim1recslim2subdir', source, include_dirs: [File.expand_path('files', File.dirname(__FILE__))]
end
def test_include_with_newline
source = %q{
a: include slimfile
.content
}
assert_html 'slim1recslim2', source, include_dirs: [File.expand_path('files', File.dirname(__FILE__))]
end
end
slim-3.0.6/test/core/ 0000755 0000041 0000041 00000000000 12555545227 014437 5 ustar www-data www-data slim-3.0.6/test/core/test_text_interpolation.rb 0000644 0000041 0000041 00000003201 12555545227 021752 0 ustar www-data www-data require 'helper'
class TestSlimTextInterpolation < TestSlim
def test_interpolation_in_attribute
source = %q{
p id="a#{id_helper}b" = hello_world
}
assert_html '
Hello World from @env
', source
end
def test_nested_interpolation_in_attribute
source = %q{
p id="#{"abc#{1+1}" + "("}" = hello_world
}
assert_html '
Hello World from @env
', source
end
def test_interpolation_in_text
source = %q{
p
| #{hello_world} with "quotes"
p
|
A message from the compiler: #{hello_world}
}
assert_html '
Hello World from @env with "quotes"
A message from the compiler: Hello World from @env
', source
end
def test_interpolation_in_tag
source = %q{
p #{hello_world}
}
assert_html '
Hello World from @env
', source
end
def test_escape_interpolation
source = %q{
p \\#{hello_world}
p text1 \\#{hello_world} text2
}
assert_html '
#{hello_world}
text1 #{hello_world} text2
', source
end
def test_complex_interpolation
source = %q{
p Message: #{message('hello', "user #{output_number}")}
}
assert_html '
", source
end
def test_render_with_javascript
# Keep the trailing space behind "javascript: "!
source = %q{
javascript:
$(function() {});
alert('hello')
p Hi
}
assert_html %{
Hi
}, source
end
def test_render_with_opal
begin
# HACK: org-ruby registers itself in Tilt
require 'opal'
rescue LoadError
return
end
source = %q{
opal:
puts 'hello from opal'
}
assert_match '$puts("hello from opal")', render(source)
end
def test_render_with_javascript_with_tabs
source = "javascript:\n\t$(function() {});\n\talert('hello')\np Hi"
assert_html "
Hi
", source
end
def test_render_with_javascript_including_variable
# Keep the trailing space behind "javascript: "!
source = %q{
- func = "alert('hello');"
javascript:
$(function() { #{func} });
}
assert_html %q||, source
end
def test_render_with_javascript_with_explicit_html_comment
Slim::Engine.with_options(js_wrapper: :comment) do
source = "javascript:\n\t$(function() {});\n\talert('hello')\np Hi"
assert_html "
Hi
", source
end
end
def test_render_with_javascript_with_explicit_cdata_comment
Slim::Engine.with_options(js_wrapper: :cdata) do
source = "javascript:\n\t$(function() {});\n\talert('hello')\np Hi"
assert_html "
Hi
", source
end
end
def test_render_with_javascript_with_format_xhtml_comment
Slim::Engine.with_options(js_wrapper: :guess, format: :xhtml) do
source = "javascript:\n\t$(function() {});\n\talert('hello')\np Hi"
assert_html "
Hi
", source
end
end
def test_render_with_javascript_with_format_html_comment
Slim::Engine.with_options(js_wrapper: :guess, format: :html) do
source = "javascript:\n\t$(function() {});\n\talert('hello')\np Hi"
assert_html "
Hi
", source
end
end
def test_render_with_ruby
source = %q{
ruby:
variable = 1 +
2
= variable
}
assert_html '3', source
end
def test_render_with_scss
source = %q{
scss:
$color: #f00;
body { color: $color; }
}
assert_html "", source
end
def test_disabled_embedded_engine
source = %{
ruby:
Embedded Ruby
}
assert_runtime_error 'Embedded engine ruby is disabled', source, enable_engines: [:javascript]
assert_runtime_error 'Embedded engine ruby is disabled', source, enable_engines: %w(javascript)
source = %{
ruby:
Embedded Ruby
}
assert_runtime_error 'Embedded engine ruby is disabled', source, enable_engines: [:javascript]
assert_runtime_error 'Embedded engine ruby is disabled', source, enable_engines: %w(javascript)
source = %{
ruby:
Embedded Ruby
}
assert_runtime_error 'Embedded engine ruby is disabled', source, disable_engines: [:ruby]
assert_runtime_error 'Embedded engine ruby is disabled', source, disable_engines: %w(ruby)
end
def test_enabled_embedded_engine
source = %q{
javascript:
$(function() {});
}
assert_html '', source, disable_engines: [:ruby]
assert_html '', source, disable_engines: %w(ruby)
source = %q{
javascript:
$(function() {});
}
assert_html '', source, enable_engines: [:javascript]
assert_html '', source, enable_engines: %w(javascript)
end
end
slim-3.0.6/test/core/helper.rb 0000644 0000041 0000041 00000007747 12555545227 016262 0 ustar www-data www-data # encoding: utf-8
begin
require 'codeclimate-test-reporter'
CodeClimate::TestReporter.start
rescue LoadError
end
require 'minitest/autorun'
require 'slim'
require 'slim/grammar'
Slim::Engine.after Slim::Parser, Temple::Filters::Validator, grammar: Slim::Grammar
Slim::Engine.before :Pretty, Temple::Filters::Validator
class TestSlim < Minitest::Test
def setup
@env = Env.new
end
def render(source, options = {}, &block)
scope = options.delete(:scope)
locals = options.delete(:locals)
Slim::Template.new(options[:file], options) { source }.render(scope || @env, locals, &block)
end
class HtmlSafeString < String
def html_safe?
true
end
def to_s
self
end
end
def with_html_safe
String.send(:define_method, :html_safe?) { false }
String.send(:define_method, :html_safe) { HtmlSafeString.new(self) }
yield
ensure
String.send(:undef_method, :html_safe?) if String.method_defined?(:html_safe?)
String.send(:undef_method, :html_safe) if String.method_defined?(:html_safe)
end
def assert_html(expected, source, options = {}, &block)
assert_equal expected, render(source, options, &block)
end
def assert_syntax_error(message, source, options = {})
render(source, options)
raise 'Syntax error expected'
rescue Slim::Parser::SyntaxError => ex
assert_equal message, ex.message
message =~ /([^\s]+), Line (\d+)/
assert_backtrace ex, "#{$1}:#{$2}"
end
def assert_ruby_error(error, from, source, options = {})
render(source, options)
raise 'Ruby error expected'
rescue error => ex
assert_backtrace(ex, from)
end
def assert_backtrace(ex, from)
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
# HACK: Rubinius stack trace sometimes has one entry more
if ex.backtrace[0] !~ /^#{Regexp.escape from}/
ex.backtrace[1] =~ /([^\s]+:\d+)/
assert_equal from, $1
end
else
ex.backtrace[0] =~ /([^\s]+:\d+)/
assert_equal from, $1
end
end
def assert_ruby_syntax_error(from, source, options = {})
render(source, options)
raise 'Ruby syntax error expected'
rescue SyntaxError => ex
ex.message =~ /([^\s]+:\d+):/
assert_equal from, $1
end
def assert_runtime_error(message, source, options = {})
render(source, options)
raise Exception, 'Runtime error expected'
rescue RuntimeError => ex
assert_equal message, ex.message
end
end
class Env
attr_reader :var, :x
def initialize
@var = 'instance'
@x = 0
end
def id_helper
"notice"
end
def hash
{a: 'The letter a', b: 'The letter b'}
end
def show_first?(show = false)
show
end
def define_macro(name, &block)
@macro ||= {}
@macro[name.to_s] = block
''
end
def call_macro(name, *args)
@macro[name.to_s].call(*args)
end
def hello_world(text = "Hello World from @env", opts = {})
text << opts.to_a * " " if opts.any?
if block_given?
"#{text} #{yield} #{text}"
else
text
end
end
def message(*args)
args.join(' ')
end
def action_path(*args)
"/action-#{args.join('-')}"
end
def in_keyword
"starts with keyword"
end
def evil_method
""
end
def output_number
1337
end
def succ_x
@x = @x.succ
end
end
class ViewEnv
def output_number
1337
end
def person
[{name: 'Joe'}, {name: 'Jack'}]
end
def people
%w(Andy Fred Daniel).collect{|n| Person.new(n)}
end
def cities
%w{Atlanta Melbourne Karlsruhe}
end
def people_with_locations
array = []
people.each_with_index do |p,i|
p.location = Location.new cities[i]
array << p
end
array
end
end
require 'forwardable'
class Person
extend Forwardable
attr_accessor :name
def initialize(name)
@name = name
end
def location=(location)
@location = location
end
def_delegators :@location, :city
end
class Location
attr_accessor :city
def initialize(city)
@city = city
end
end
slim-3.0.6/test/core/test_html_structure.rb 0000644 0000041 0000041 00000032263 12555545227 021115 0 ustar www-data www-data require 'helper'
class TestSlimHtmlStructure < TestSlim
def test_simple_render
# Keep the trailing space behind "body "!
source = %q{
html
head
title Simple Test Title
body
p Hello World, meet Slim.
}
assert_html 'Simple Test Title
Hello World, meet Slim.
', source
end
def test_relaxed_indentation_of_first_line
source = %q{
p
.content
}
assert_html "", source
end
def test_html_tag_with_text_and_empty_line
source = %q{
p Hello
p World
}
assert_html "
Hello
World
", source
end
def test_html_namespaces
source = %q{
html:body
html:p html:id="test" Text
}
assert_html 'Text', source
end
def test_doctype
source = %q{
doctype 1.1
html
}
assert_html '', source, format: :xhtml
end
def test_doctype_new_syntax
source = %q{
doctype 5
html
}
assert_html '', source, format: :xhtml
end
def test_doctype_new_syntax_html5
source = %q{
doctype html
html
}
assert_html '', source, format: :xhtml
end
def test_render_with_shortcut_attributes
source = %q{
h1#title This is my title
#notice.hello.world
= hello_world
}
assert_html '
This is my title
Hello World from @env
', source
end
def test_render_with_overwritten_default_tag
source = %q{
#notice.hello.world
= hello_world
}
assert_html 'Hello World from @env', source, default_tag: 'section'
end
def test_render_with_custom_shortcut
source = %q{
#notice.hello.world@test
= hello_world
@abc
= hello_world
}
assert_html '
Hello World from @env
Hello World from @env', source, shortcut: {'#' => {attr: 'id'}, '.' => {attr: 'class'}, '@' => {tag: 'section', attr: 'role'}}
end
def test_render_with_text_block
source = %q{
p
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
}
assert_html '
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
', source
end
def test_render_with_text_block_with_subsequent_markup
source = %q{
p
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
p Some more markup
}
assert_html '
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Some more markup
', source
end
def test_render_with_text_block_with_trailing_whitespace
source = %q{
' this is
a link to
a href="link" page
}
assert_html "this is\na link to page", source
end
def test_nested_text
source = %q{
p
|
This is line one.
This is line two.
This is line three.
This is line four.
p This is a new paragraph.
}
assert_html "
This is line one.\n This is line two.\n This is line three.\n This is line four.
This is a new paragraph.
", source
end
def test_nested_text_with_nested_html_one_same_line
source = %q{
p
| This is line one.
This is line two.
span.bold This is a bold line in the paragraph.
| This is more content.
}
assert_html "
This is line one.\n This is line two.This is a bold line in the paragraph. This is more content.
", source
end
def test_nested_text_with_nested_html_one_same_line2
source = %q{
p
|This is line one.
This is line two.
span.bold This is a bold line in the paragraph.
| This is more content.
}
assert_html "
This is line one.\n This is line two.This is a bold line in the paragraph. This is more content.
", source
end
def test_nested_text_with_nested_html
source = %q{
p
|
This is line one.
This is line two.
This is line three.
This is line four.
span.bold This is a bold line in the paragraph.
| This is more content.
}
assert_html "
This is line one.\n This is line two.\n This is line three.\n This is line four.This is a bold line in the paragraph. This is more content.
", source
end
def test_simple_paragraph_with_padding
source = %q{
p There will be 3 spaces in front of this line.
}
assert_html '
There will be 3 spaces in front of this line.
', source
end
def test_paragraph_with_nested_text
source = %q{
p This is line one.
This is line two.
}
assert_html "
This is line one.\n This is line two.
", source
end
def test_paragraph_with_padded_nested_text
source = %q{
p This is line one.
This is line two.
}
assert_html "
This is line one.\n This is line two.
", source
end
def test_paragraph_with_attributes_and_nested_text
source = %q{
p#test class="paragraph" This is line one.
This is line two.
}
assert_html "
This is line one.\nThis is line two.
", source
end
def test_relaxed_text_indentation
source = %q{
p
| text block
text
line3
}
assert_html "
text block\ntext\n line3
", source
end
def test_output_code_with_leading_spaces
source = %q{
p= hello_world
p = hello_world
p = hello_world
}
assert_html '
Hello World from @env
Hello World from @env
Hello World from @env
', source
end
def test_single_quoted_attributes
source = %q{
p class='underscored_class_name' = output_number
}
assert_html '
1337
', source
end
def test_nonstandard_attributes
source = %q{
p id="dashed-id" class="underscored_class_name" = output_number
}
assert_html '
', source, attr_list_delims: {'<' => '>'}, code_attr_delims: { '(' => ')' }
end
def test_closed_tag
source = %q{
closed/
}
assert_html '', source, format: :xhtml
end
def test_attributs_with_parens_and_spaces
source = %q{label{ for='filter' }= hello_world}
assert_html '', source
end
def test_attributs_with_parens_and_spaces2
source = %q{label{ for='filter' } = hello_world}
assert_html '', source
end
def test_attributs_with_multiple_spaces
source = %q{label for='filter' class="test" = hello_world}
assert_html '', source
end
def test_closed_tag_with_attributes
source = %q{
closed id="test" /
}
assert_html '', source, format: :xhtml
end
def test_closed_tag_with_attributes_and_parens
source = %q{
closed(id="test")/
}
assert_html '', source, format: :xhtml
end
def test_render_with_html_comments
source = %q{
p Hello
/! This is a comment
Another comment
p World
}
assert_html "
Hello
World
", source
end
def test_render_with_html_conditional_and_tag
source = %q{
/[ if IE ]
p Get a better browser.
}
assert_html "", source
end
def test_render_with_html_conditional_and_method_output
source = %q{
/[ if IE ]
= message 'hello'
}
assert_html "", source
end
def test_multiline_attributes_with_method
source = %q{
p = output_number
}
Slim::Parser.options[:attr_list_delims].each do |k,v|
str = source.sub('<',k).sub('>',v)
assert_html '
1337
', str
end
end
def test_multiline_attributes_with_text_on_same_line
source = %q{
p THE space modulator
}
Slim::Parser.options[:attr_list_delims].each do |k,v|
str = source.sub('<',k).sub('>',v)
assert_html '
THE space modulator
', str
end
end
def test_multiline_attributes_with_nested_text
source = %q{
p
| THE space modulator
}
Slim::Parser.options[:attr_list_delims].each do |k,v|
str = source.sub('<',k).sub('>',v)
assert_html '
THE space modulator
', str
end
end
def test_multiline_attributes_with_dynamic_attr
source = %q{
p
| THE space modulator
}
Slim::Parser.options[:attr_list_delims].each do |k,v|
str = source.sub('<',k).sub('>',v)
assert_html '
THE space modulator
', str
end
end
def test_multiline_attributes_with_nested_tag
source = %q{
p
span.emphasis THE
| space modulator
}
Slim::Parser.options[:attr_list_delims].each do |k,v|
str = source.sub('<',k).sub('>',v)
assert_html '
THE space modulator
', str
end
end
def test_multiline_attributes_with_nested_text_and_extra_indentation
source = %q{
li< id="myid"
class="myclass"
data-info="myinfo">
a href="link" My Link
}
Slim::Parser.options[:attr_list_delims].each do |k,v|
str = source.sub('<',k).sub('>',v)
assert_html '
}, source
end
def test_block_expansion_class_attributes
source = %q{
.a: .b: #c d
}
assert_html %{
d
}, source
end
def test_block_expansion_nesting
source = %q{
html: body: .content
| Text
}
assert_html %{
Text
}, source
end
def test_eval_attributes_once
source = %q{
input[value=succ_x]
input[value=succ_x]
}
assert_html %{}, source
end
def test_html_line_indicator
source = %q{
head
meta name="keywords" content=hello_world
- if true
#{hello_world}
span = hello_world
}
assert_html '
Hello World from @env
Hello World from @env', source
end
end
slim-3.0.6/test/core/test_code_blocks.rb 0000644 0000041 0000041 00000007237 12555545227 020303 0 ustar www-data www-data require 'helper'
class TestSlimCodeBlocks < TestSlim
def test_render_with_output_code_block
source = %q{
p
= hello_world "Hello Ruby!" do
| Hello from within a block!
}
assert_html '
Hello Ruby! Hello from within a block! Hello Ruby!
', source
end
def test_render_with_output_code_block_without_do
source = %q{
p
= hello_world "Hello Ruby!"
| Hello from within a block!
}
assert_html '
Hello Ruby! Hello from within a block! Hello Ruby!
', source
end
def test_render_with_output_code_within_block
source = %q{
p
= hello_world "Hello Ruby!" do
= hello_world "Hello from within a block!"
}
assert_html '
Hello Ruby! Hello from within a block! Hello Ruby!
', source
end
def test_render_with_output_code_within_block_without_do
source = %q{
p
= hello_world "Hello Ruby!"
= hello_world "Hello from within a block!"
}
assert_html '
Hello Ruby! Hello from within a block! Hello Ruby!
', source
end
def test_render_with_output_code_within_block_2
source = %q{
p
= hello_world "Hello Ruby!" do
= hello_world "Hello from within a block!" do
= hello_world "And another one!"
}
assert_html '
Hello Ruby! Hello from within a block! And another one! Hello from within a block! Hello Ruby!
', source
end
def test_render_with_output_code_within_block_2_without_do
source = %q{
p
= hello_world "Hello Ruby!"
= hello_world "Hello from within a block!"
= hello_world "And another one!"
}
assert_html '
Hello Ruby! Hello from within a block! And another one! Hello from within a block! Hello Ruby!
', source
end
def test_render_with_control_code_loop
source = %q{
p
- 3.times do
| Hey!
}
assert_html '
Hey!Hey!Hey!
', source
end
def test_render_with_control_code_loop_without_do
source = %q{
p
- 3.times
| Hey!
}
assert_html '
Hey!Hey!Hey!
', source
end
def test_captured_code_block_with_conditional
source = %q{
= hello_world "Hello Ruby!" do
- if true
| Hello from within a block!
}
assert_html 'Hello Ruby! Hello from within a block! Hello Ruby!', source
end
def test_captured_code_block_with_conditional_without_do
source = %q{
= hello_world "Hello Ruby!"
- if true
| Hello from within a block!
}
assert_html 'Hello Ruby! Hello from within a block! Hello Ruby!', source
end
def test_if_without_content
source = %q{
- if true
}
assert_html '', source
end
def test_unless_without_content
source = %q{
- unless true
}
assert_html '', source
end
def test_if_with_comment
source = %q{
- if true
/ comment
}
assert_html '', source
end
def test_control_do_with_comment
source = %q{
- hello_world "Hello"
/ comment
}
assert_html '', source
end
def test_output_do_with_comment
source = %q{
= hello_world "Hello"
/ comment
}
assert_html 'Hello', source
end
def test_output_if_without_content
source = %q{
= if true
}
assert_html '', source
end
def test_output_if_with_comment
source = %q{
= if true
/ comment
}
assert_html '', source
end
end
slim-3.0.6/test/core/test_commands.rb 0000644 0000041 0000041 00000014436 12555545227 017634 0 ustar www-data www-data # coding: utf-8
require 'helper'
require 'open3'
require 'tempfile'
class TestSlimCommands < Minitest::Test
# nothing complex
STATIC_TEMPLATE = "p Hello World!\n"
# requires a `name` variable to exist at render time
DYNAMIC_TEMPLATE = "p Hello \#{name}!\n"
# a more complex example
LONG_TEMPLATE = "h1 Hello\np\n | World!\n small Tiny text"
# exception raising example
EXCEPTION_TEMPLATE = '- raise NotImplementedError'
# Temple has this feature...
STRING_FREEZER = RUBY_VERSION >= '2.1' ? '.freeze' : ''
def test_option_help
out, err = exec_slimrb '--help'
assert err.empty?
assert_match /Show this message/, out
end
def test_option_version
out, err = exec_slimrb '--version'
assert err.empty?
assert_match /\ASlim #{Regexp.escape Slim::VERSION}$/, out
end
def test_render
prepare_common_test STATIC_TEMPLATE do |out, err|
assert err.empty?
assert_equal "
Hello World!
\n", out
end
end
# superficial test, we don't want to test Tilt/Temple
def test_compile
prepare_common_test STATIC_TEMPLATE, '--compile' do |out, err|
assert err.empty?
assert_match %r{\"
Hello World!<\/p>\"#{STRING_FREEZER}}, out
end
end
def test_erb
prepare_common_test DYNAMIC_TEMPLATE, '--erb' do |out, err|
assert err.empty?
assert_equal "
Hello <%= ::Temple::Utils.escape_html((name)) %>!
\n", out
end
end
def test_rails
prepare_common_test DYNAMIC_TEMPLATE, '--rails' do |out, err|
assert err.empty?
assert out.include? %Q{@output_buffer = ActiveSupport::SafeBuffer.new;}
assert out.include? %Q{@output_buffer.safe_concat(("
"#{STRING_FREEZER}));}
end
end
def test_pretty
prepare_common_test LONG_TEMPLATE, '--pretty' do |out, err|
assert err.empty?
assert_equal "
\n Hello\n
\n
\n World!Tiny text\n
\n", out
end
end
# We cannot run these two on Travis, because we can't install libyaml.
# See https://github.com/slim-template/slim/issues/576
if ENV['TRAVIS'] && RUBY_ENGINE != 'rbx'
def test_locals_json
data = '{"name":"from slim"}'
prepare_common_test DYNAMIC_TEMPLATE, '--locals', data do |out, err|
assert err.empty?
assert_equal "
Hello from slim!
\n", out
end
end
def test_locals_yaml
data = "name: from slim"
prepare_common_test DYNAMIC_TEMPLATE, '--locals', data do |out, err|
assert err.empty?
assert_equal "
Hello from slim!
\n", out
end
end
end
def test_locals_hash
data = '{name:"from slim"}'
prepare_common_test DYNAMIC_TEMPLATE, '--locals', data do |out, err|
assert err.empty?
assert_equal "
Hello from slim!
\n", out
end
end
def test_require
with_tempfile 'puts "Not in slim"', 'rb' do |lib|
prepare_common_test STATIC_TEMPLATE, '--require', lib, stdin_file: false, file_file: false do |out, err|
assert err.empty?
assert_equal "Not in slim\n
Hello World!
\n", out
end
end
end
def test_error
prepare_common_test EXCEPTION_TEMPLATE, stdin_file: false do |out, err|
assert out.empty?
assert_match /NotImplementedError: NotImplementedError/, err
assert_match /Use --trace for backtrace/, err
end
end
def test_trace_error
prepare_common_test EXCEPTION_TEMPLATE, '--trace', stdin_file: false do |out, err|
assert out.empty?
assert_match /bin\/slimrb/, err
end
end
private
# Whether you call slimrb with a file argument or pass the slim content
# via $stdin; whether you want the output written to $stdout or into
# another file given as argument, the output is the same.
#
# This method prepares a test with this exact behaviour:
#
# It yields the tupel (out, err) once after the `content` was passed
# in via $stdin and once it was passed as a (temporary) file argument.
#
# In effect, this method executes a test (given as block) 4 times:
#
# 1. read from $stdin, write to $stdout
# 2. read from file, write to $stdout
# 3. read from $stdin, write to file
# 4. read from file, write to file
def prepare_common_test(content, *args)
options = Hash === args.last ? args.pop : {}
# case 1. $stdin → $stdout
unless options[:stdin_stdout] == false
out, err = exec_slimrb *args, '--stdin' do |i|
i.write content
end
yield out, err
end
# case 2. file → $stdout
unless options[:file_stdout] == false
with_tempfile content do |in_file|
out, err = exec_slimrb *args, in_file
yield out, err
end
end
# case 3. $stdin → file
unless options[:stdin_file] == false
with_tempfile content do |out_file|
_, err = exec_slimrb *args, '--stdin', out_file do |i|
i.write content
end
yield File.read(out_file), err
end
end
# case 3. file → file
unless options[:file_file] == false
with_tempfile '' do |out_file|
with_tempfile content do |in_file|
_, err = exec_slimrb *args, in_file, out_file do |i|
i.write content
end
yield File.read(out_file), err
end
end
end
end
# Calls bin/slimrb as a subprocess.
#
# Yields $stdin to the caller and returns a tupel (out,err) with the
# contents of $stdout and $stderr.
#
# (I'd like to use Minitest::Assertions#capture_subprecess_io here,
# but then there's no way to insert data via $stdin.)
def exec_slimrb(*args)
out, err = nil, nil
Open3.popen3 'ruby', 'bin/slimrb', *args do |i,o,e,t|
yield i if block_given?
i.close
out, err = o.read, e.read
end
return out, err
end
# Creates a temporary file with the given content and yield the path
# to this file. The file itself is only available inside the block and
# will be deleted afterwards.
def with_tempfile(content=nil, extname='slim')
f = Tempfile.new ['slim', ".#{extname}"]
if content
f.write content
f.flush # ensure content is actually saved to disk
f.rewind
end
yield f.path
ensure
f.close
f.unlink
end
end
slim-3.0.6/test/core/test_ruby_errors.rb 0000644 0000041 0000041 00000007214 12555545227 020404 0 ustar www-data www-data require 'helper'
class TestSlimRubyErrors < TestSlim
def test_multline_attribute
source = %q{
p(data-1=1
data2-=1)
p
= unknown_ruby_method
}
assert_ruby_error NameError, "test.slim:5", source, file: 'test.slim'
end
def test_broken_output_line
source = %q{
p = hello_world + \
hello_world + \
unknown_ruby_method
}
# FIXME: Remove this hack!
# This is actually a jruby issue. Jruby reports a wrong
# line number 1 in this case:
#
# test = 1+\
# unknown_variable
if RUBY_PLATFORM == "java"
assert_ruby_error NameError, "test.slim:2", source, file: 'test.slim'
else
assert_ruby_error NameError, "test.slim:4", source, file: 'test.slim'
end
end
def test_broken_output_line2
source = %q{
p = hello_world + \
hello_world
p Hello
= unknown_ruby_method
}
assert_ruby_error NameError,"(__TEMPLATE__):5", source
end
def test_output_block
source = %q{
p = hello_world "Hello Ruby" do
= unknown_ruby_method
}
assert_ruby_error NameError,"(__TEMPLATE__):3", source
end
def test_output_block2
source = %q{
p = hello_world "Hello Ruby" do
= "Hello from block"
p Hello
= unknown_ruby_method
}
assert_ruby_error NameError, "(__TEMPLATE__):5", source
end
def test_text_block
source = %q{
p Text line 1
Text line 2
= unknown_ruby_method
}
assert_ruby_error NameError,"(__TEMPLATE__):4", source
end
def test_text_block2
source = %q{
|
Text line 1
Text line 2
= unknown_ruby_method
}
assert_ruby_error NameError,"(__TEMPLATE__):5", source
end
def test_comment
source = %q{
/ Comment line 1
Comment line 2
= unknown_ruby_method
}
assert_ruby_error NameError,"(__TEMPLATE__):4", source
end
def test_embedded_erb
source = %q{
erb:
<%= 123 %>
Hello from ERB!
<%#
comment block
%>
<% if true %>
Text
<% end %>
= unknown_ruby_method
}
assert_ruby_error NameError,"(__TEMPLATE__):11", source
end
def test_embedded_ruby1
source = %q{
ruby:
a = 1
b = 2
= a + b
= unknown_ruby_method
}
assert_ruby_error NameError,"(__TEMPLATE__):6", source
end
def test_embedded_ruby2
source = %q{
ruby:
a = 1
unknown_ruby_method
}
assert_ruby_error NameError,"(__TEMPLATE__):4", source
end
def test_embedded_markdown
source = %q{
markdown:
#Header
Hello from #{"Markdown!"}
"Second Line!"
= unknown_ruby_method
}
assert_ruby_error NameError,"(__TEMPLATE__):6", source
end
def test_embedded_javascript
source = %q{
javascript:
alert();
alert();
= unknown_ruby_method
}
assert_ruby_error NameError,"(__TEMPLATE__):5", source
end
def test_invalid_nested_code
source = %q{
p
- test = 123
= "Hello from within a block! "
}
assert_ruby_syntax_error "(__TEMPLATE__):3", source
end
def test_invalid_nested_output
source = %q{
p
= "Hello Ruby!"
= "Hello from within a block! "
}
assert_ruby_syntax_error "(__TEMPLATE__):3", source
end
def test_explicit_end
source = %q{
div
- if show_first?
p The first paragraph
- end
}
assert_runtime_error 'Explicit end statements are forbidden', source
end
def test_multiple_id_attribute
source = %{
#alpha id="beta" Test it
}
assert_runtime_error 'Multiple id attributes specified', source
end
def test_splat_multiple_id_attribute
source = %{
#alpha *{id:"beta"} Test it
}
assert_runtime_error 'Multiple id attributes specified', source
end
# def test_invalid_option
# render('', foobar: 42)
# raise Exception, 'ArgumentError expected'
# rescue ArgumentError => ex
# assert_equal 'Option :foobar is not supported by Slim::Engine', ex.message
# end
end
slim-3.0.6/test/core/test_erb_converter.rb 0000644 0000041 0000041 00000003074 12555545227 020666 0 ustar www-data www-data require 'helper'
require 'slim/erb_converter'
class TestSlimERBConverter < TestSlim
def test_converter
source = %q{
doctype 5
html
head
title Hello World!
/! Meta tags
with long explanatory
multiline comment
meta name="description" content="template language"
/! Stylesheets
link href="style.css" media="screen" rel="stylesheet" type="text/css"
link href="colors.css" media="screen" rel="stylesheet" type="text/css"
/! Javascripts
script src="jquery.js"
script src="jquery.ui.js"
/[if lt IE 9]
script src="old-ie1.js"
script src="old-ie2.js"
sass:
body
background-color: red
body
#container
p Hello
World!
p= "dynamic text with\nnewline"
}
result = %q{
Hello World!
Hello
World!
<%= ::Temple::Utils.escape_html(("dynamic text with\nnewline")) %>
}
assert_equal result, Slim::ERBConverter.new.call(source)
end
end
slim-3.0.6/test/core/test_pretty.rb 0000644 0000041 0000041 00000005664 12555545227 017365 0 ustar www-data www-data require 'helper'
class TestSlimPretty < TestSlim
def setup
super
Slim::Engine.set_options pretty: true
end
def teardown
Slim::Engine.set_options pretty: false
end
def test_pretty
source = %q{
doctype 5
html
head
title Hello World!
/! Meta tags
with long explanatory
multiline comment
meta name="description" content="template language"
/! Stylesheets
link href="style.css" media="screen" rel="stylesheet" type="text/css"
link href="colors.css" media="screen" rel="stylesheet" type="text/css"
/! Javascripts
script src="jquery.js"
script src="jquery.ui.js"
/[if lt IE 9]
script src="old-ie1.js"
script src="old-ie2.js"
sass:
body
background-color: red
body
#container
p Hello
World!
p= "dynamic text with\nnewline"
}
result = %q{
Hello World!
}
assert_html result, source
end
def test_helper_unindent
source = %q{
= define_macro :content
div
a link
html
body
== call_macro :content
}
result = %q{
', source
end
end
slim-3.0.6/test/core/test_html_attributes.rb 0000644 0000041 0000041 00000014451 12555545227 021242 0 ustar www-data www-data require 'helper'
class TestSlimHTMLAttributes < TestSlim
def test_ternary_operation_in_attribute
source = %q{
p id="#{(false ? 'notshown' : 'shown')}" = output_number
}
assert_html '
1337
', source
end
def test_ternary_operation_in_attribute_2
source = %q{
p id=(false ? 'notshown' : 'shown') = output_number
}
assert_html '
1337
', source
end
def test_class_attribute_merging
source = %{
.alpha class="beta" Test it
}
assert_html '
Test it
', source
end
def test_class_attribute_merging_with_nil
source = %{
.alpha class="beta" class=nil class="gamma" Test it
}
assert_html '
Test it
', source
end
def test_class_attribute_merging_with_empty_static
source = %{
.alpha class="beta" class="" class="gamma" Test it
}
assert_html '
Test it
', source
end
def test_id_attribute_merging
source = %{
#alpha id="beta" Test it
}
assert_html '
Test it
', source, merge_attrs: {'class' => ' ', 'id' => '_' }
end
def test_id_attribute_merging2
source = %{
#alpha id="beta" Test it
}
assert_html '
Test it
', source, merge_attrs: {'class' => ' ', 'id' => '-' }
end
def test_boolean_attribute_false
source = %{
- cond=false
option selected=false Text
option selected=cond Text2
}
assert_html '', source
end
def test_boolean_attribute_true
source = %{
- cond=true
option selected=true Text
option selected=cond Text2
}
assert_html '', source
end
def test_boolean_attribute_nil
source = %{
- cond=nil
option selected=nil Text
option selected=cond Text2
}
assert_html '', source
end
def test_boolean_attribute_string2
source = %{
option selected="selected" Text
}
assert_html '', source
end
def test_boolean_attribute_shortcut
source = %{
option(class="clazz" selected) Text
option(selected class="clazz") Text
}
assert_html '', source
end
def test_array_attribute_merging
source = %{
.alpha class="beta" class=[[""], :gamma, nil, :delta, [true, false]]
.alpha class=:beta,:gamma
}
assert_html '', source
end
def test_hyphenated_attribute
source = %{
.alpha data={a: 'alpha', b: 'beta', c_d: 'gamma', c: {e: 'epsilon'}}
}
assert_html '', source
end
def test_splat_without_content
source = %q{
*hash
p*hash
}
assert_html '', source
end
def test_shortcut_splat
source = %q{
*hash This is my title
}
assert_html '
This is my title
', source
end
def test_splat
source = %q{
h1 *hash class=[] This is my title
}
assert_html '
This is my title
', source
end
def test_closed_splat
source = %q{
*hash /
}
assert_html '', source
end
def test_splat_tag_name
source = %q{
*{tag: 'h1', id: 'title'} This is my title
}
assert_html '
This is my title
', source
end
def test_splat_empty_tag_name
source = %q{
*{tag: '', id: 'test'} This is my title
}
assert_html '
This is my title
', source
end
def test_closed_splat_tag
source = %q{
*hash /
}
assert_html '', source
end
def test_splat_with_id_shortcut
source = %q{
#myid*hash This is my title
}
assert_html '
This is my title
', source
end
def test_splat_with_class_shortcut
source = %q{
.myclass*hash This is my title
}
assert_html '
This is my title
', source
end
def test_splat_with_id_and_class_shortcuts
source = %q{
#myid.myclass*hash This is my title
}
assert_html '
This is my title
', source
end
def test_splat_with_class_merging
source = %q{
#myid.myclass *{class: [:secondclass, %w(x y z)]} *hash This is my title
}
assert_html '
This is my title
', source
end
def test_splat_with_boolean_attribute
source = %q{
*{disabled: true, empty1: false, nonempty: '', empty2: nil} This is my title
}
assert_html '
This is my title
', source
end
def test_splat_merging_with_arrays
source = %q{
*{a: 1, b: 2} *[[:c, 3], [:d, 4]] *[[:e, 5], [:f, 6]] This is my title
}
assert_html '
This is my title
', source
end
def test_splat_with_other_attributes
source = %q{
h1 data-id="123" *hash This is my title
}
assert_html '
This is my title
', source
end
def test_attribute_merging
source = %q{
a class=true class=false
a class=false *{class:true}
a class=true
a class=false
}
assert_html '', source
end
def test_static_empty_attribute
source = %q{
p(id="marvin" name="" class="" data-info="Illudium Q-36")= output_number
}
assert_html '
', source
end
def test_weird_attribute
source = %q{
p
img(src='img.png' whatsthis?!)
img src='img.png' whatsthis?!="wtf"
}
assert_html '
', source
end
end
slim-3.0.6/test/core/test_code_escaping.rb 0000644 0000041 0000041 00000007017 12555545227 020613 0 ustar www-data www-data require 'helper'
class TestSlimCodeEscaping < TestSlim
def test_escaping_evil_method
source = %q{
p = evil_method
}
assert_html '
<script>do_something_evil();</script>
', source
end
def test_render_without_html_safe
source = %q{
p = "Hello World\\n, meet \\"Slim\\"."
}
assert_html "
<strong>Hello World\n, meet \"Slim\"</strong>.
", source
end
def test_render_without_html_safe2
source = %q{
p = "Hello World\\n, meet 'Slim'."
}
assert_html "
<strong>Hello World\n, meet 'Slim'</strong>.
", source
end
def test_render_with_html_safe_false
source = %q{
p = "Hello World\\n, meet \\"Slim\\"."
}
with_html_safe do
assert_html "
<strong>Hello World\n, meet \"Slim\"</strong>.
", source, use_html_safe: true
end
end
def test_render_with_html_safe_true
source = %q{
p = "Hello World\\n, meet \\"Slim\\".".html_safe
}
with_html_safe do
assert_html "
Hello World\n, meet \"Slim\".
", source, use_html_safe: true
end
end
def test_render_splat_with_html_safe_true
source = %q{
p *{ title: '&'.html_safe }
}
with_html_safe do
assert_html "", source, use_html_safe: true
end
end
def test_render_splat_with_html_safe_false
source = %q{
p *{ title: '&' }
}
with_html_safe do
assert_html "", source, use_html_safe: true
end
end
def test_render_attribute_with_html_safe_true
source = %q{
p title=('&'.html_safe)
}
with_html_safe do
assert_html "", source, use_html_safe: true
end
end
def test_render_with_disable_escape_false
source = %q{
= "
Hello
"
== "
World
"
}
assert_html "<p>Hello</p>
World
", source
end
def test_render_with_disable_escape_true
source = %q{
= "
Hello
"
== "
World
"
}
assert_html "
Hello
World
", source, disable_escape: true
end
def test_escaping_evil_method_with_pretty
source = %q{
p = evil_method
}
assert_html "
\n <script>do_something_evil();</script>\n
", source, pretty: true
end
def test_render_without_html_safe_with_pretty
source = %q{
p = "Hello World\\n, meet \\"Slim\\"."
}
assert_html "
", template.render { 'Joe' }
end
def test_backtrace_file_and_line_reporting_without_locals
data = File.read(__FILE__).split("\n__END__\n").last
fail unless data[0] == ?h
template = Slim::Template.new('test.slim', 10) { data }
begin
template.render
fail 'should have raised an exception'
rescue => ex
assert_kind_of NameError, ex
assert_backtrace(ex, 'test.slim:12')
end
end
def test_backtrace_file_and_line_reporting_with_locals
data = File.read(__FILE__).split("\n__END__\n").last
fail unless data[0] == ?h
template = Slim::Template.new('test.slim') { data }
begin
res = template.render(Object.new, name: 'Joe', foo: 'bar')
rescue => ex
assert_kind_of MockError, ex
assert_backtrace(ex, 'test.slim:5')
end
end
def test_compiling_template_source_to_a_method
template = Slim::Template.new { |t| "Hello World!" }
template.render
method = template.send(:compiled_method, [])
assert_kind_of UnboundMethod, method
end
def test_passing_locals
template = Slim::Template.new { "p = 'Hey ' + name + '!'\n" }
assert_equal "
Hey Joe!
", template.render(Object.new, name: 'Joe')
end
end
__END__
html
body
h1 = "Hey #{name}"
= raise MockError
p we never get here
slim-3.0.6/test/core/test_code_structure.rb 0000644 0000041 0000041 00000005314 12555545227 021060 0 ustar www-data www-data require 'helper'
class TestSlimCodeStructure < TestSlim
def test_render_with_conditional
source = %q{
div
- if show_first?
p The first paragraph
- else
p The second paragraph
}
assert_html '
The second paragraph
', source
end
def test_render_with_consecutive_conditionals
source = %q{
div
- if show_first? true
p The first paragraph
- if show_first? true
p The second paragraph
}
assert_html '
The first paragraph
The second paragraph
', source
end
def test_render_with_parameterized_conditional
source = %q{
div
- if show_first? false
p The first paragraph
- else
p The second paragraph
}
assert_html '
The second paragraph
', source
end
def test_render_with_when_string_in_condition
source = %q{
- if true
| Hello
- unless 'when' == nil
| world
}
assert_html 'Hello world', source
end
def test_render_with_conditional_and_following_nonconditonal
source = %q{
div
- if true
p The first paragraph
- var = 42
= var
}
assert_html '
The first paragraph
42
', source
end
def test_render_with_inline_condition
source = %q{
p = hello_world if true
}
assert_html '
Hello World from @env
', source
end
def test_render_with_case
source = %q{
p
- case 42
- when 41
| 41
- when 42
| 42
| is the answer
p
- case 41
- when 41
| 41
- when 42
| 42
| is the answer
p
- case 42 when 41
| 41
- when 42
| 42
| is the answer
p
- case 41 when 41
| 41
- when 42
| 42
| is the answer
}
assert_html '
42 is the answer
41 is the answer
42 is the answer
41 is the answer
', source
end
def test_render_with_slim_comments
source = %q{
p Hello
/ This is a comment
Another comment
p World
}
assert_html '
Hello
World
', source
end
def test_render_with_yield
source = %q{
div
== yield :menu
}
assert_html '
This is the menu
', source do
'This is the menu'
end
end
def test_render_with_begin_rescue
source = %q{
- begin
p Begin
- rescue
p Rescue
p After
}
assert_html '
Begin
After
', source
end
def test_render_with_begin_rescue_exception
source = %q{
- begin
p Begin
- raise 'Boom'
p After Boom
- rescue => ex
p = ex.message
p After
}
assert_html '
Begin
Boom
After
', source
end
def test_render_with_begin_rescue_ensure
source = %q{
- begin
p Begin
- raise 'Boom'
p After Boom
- rescue => ex
p = ex.message
- ensure
p Ensure
p After
}
assert_html '
Begin
Boom
Ensure
After
', source
end
end
slim-3.0.6/test/core/test_unicode.rb 0000644 0000041 0000041 00000000633 12555545227 017453 0 ustar www-data www-data # -*- coding: utf-8 -*-
require 'helper'
class TestSlimUnicode < TestSlim
def test_unicode_tags
source = "Статья года"
result = "<Статья>годаСтатья>"
assert_html result, source
end
def test_unicode_attrs
source = "Статья года=123 content"
result = "<Статья года=\"123\">contentСтатья>"
assert_html result, source
end
end
slim-3.0.6/test/literate/ 0000755 0000041 0000041 00000000000 12555545227 015320 5 ustar www-data www-data slim-3.0.6/test/literate/helper.rb 0000644 0000041 0000041 00000000704 12555545227 017125 0 ustar www-data www-data require 'slim'
require 'slim/logic_less'
require 'slim/translator'
require 'slim/grammar'
require 'minitest/autorun'
Slim::Engine.after Slim::Parser, Temple::Filters::Validator, grammar: Slim::Grammar
Slim::Engine.before :Pretty, Temple::Filters::Validator
Slim::Engine.set_options tr: false, logic_less: false
class MiniTest::Spec
def render(source, options = {}, &block)
Slim::Template.new(options) { source }.render(self, &block)
end
end
slim-3.0.6/test/literate/run.rb 0000644 0000041 0000041 00000004624 12555545227 016457 0 ustar www-data www-data require 'temple'
class LiterateTest < Temple::Engine
class Parser < Temple::Parser
def call(lines)
stack = [[:multi]]
until lines.empty?
case lines.shift
when /\A(#+)\s*(.*)\Z/
stack.pop(stack.size - $1.size)
block = [:multi]
stack.last << [:section, $2, block]
stack << block
when /\A~{3,}\s*(\w+)\s*\Z/
lang = $1
code = []
until lines.empty?
case lines.shift
when /\A~{3,}\s*\Z/
break
when /\A.*\Z/
code << $&
end
end
stack.last << [lang.to_sym, code.join("\n")]
when /\A\s*\Z/
when /\A\s*(.*?)\s*Z/
stack.last << [:comment, $1]
end
end
stack.first
end
end
class Compiler < Temple::Filter
def call(exp)
@opts, @in_testcase = {}, false
"require 'helper'\n\n#{compile(exp)}"
end
def on_section(title, body)
old_opts = @opts.dup
raise Temple::FilterError, 'New section between slim and html block' if @in_testcase
"describe #{title.inspect} do\n #{compile(body).gsub("\n", "\n ")}\nend\n"
ensure
@opts = old_opts
end
def on_multi(*exps)
exps.map {|exp| compile(exp) }.join("\n")
end
def on_comment(text)
"#{@in_testcase ? ' ' : ''}# #{text}"
end
def on_slim(code)
raise Temple::FilterError, 'Slim block must be followed by html block' if @in_testcase
@in_testcase = true
"it 'should render' do\n slim = #{code.inspect}"
end
def on_html(code)
raise Temple::FilterError, 'Html block must be preceded by slim block' unless @in_testcase
@in_testcase = false
result = " html = #{code.inspect}\n"
if @opts.empty?
result << " render(slim).must_equal html\nend\n"
else
result << " options = #{@opts.inspect}\n render(slim, options).must_equal html\nend\n"
end
end
def on_options(code)
raise Temple::FilterError, 'Options set inside test case' if @in_testcase
@opts.update(eval("{#{code}}"))
"# #{code.gsub("\n", "\n# ")}"
end
def on(*exp)
raise Temple::InvalidExpression, exp
end
end
use Parser
use Compiler
use(:Evaluator) {|code| eval(code) }
end
Dir.glob(File.join(File.dirname(__FILE__), '*.md')) do |file|
LiterateTest.new.call(File.readlines(file))
end
slim-3.0.6/test/literate/TESTS.md 0000644 0000041 0000041 00000046445 12555545227 016561 0 ustar www-data www-data # Slim test suite
You can run this testsuite with `rake test:literate`.
We use pretty mode in the test suite to make the output more readable. Pretty mode
is enabled by setting the option
~~~ options
:pretty => true
~~~
## Line indicators
In this section we test all line indicators.
### Text `|`
A text blocks starts with the `|` as line indicator.
~~~ slim
| Text block
~~~
renders as
~~~ html
Text block
~~~
Multiple lines can be indented beneath the first text line.
~~~ slim
| Text
block
with
multiple
lines
~~~
renders as
~~~ html
Text
block
with
multiple
lines
~~~
The first line of a text block determines the indentation.
~~~ slim
|
Text
block
with
multiple
lines
~~~
renders as
~~~ html
Text
block
with
multiple
lines
~~~
You can nest text blocks beneath tags.
~~~ slim
body
| Text
~~~
renders as
~~~ html
Text
~~~
You can embed html code in the text which is not escaped.
~~~ slim
| slim-lang.com
~~~
renders as
~~~ html
slim-lang.com
~~~
### Text with trailing white space `'`
A text blocks with trailing white space starts with the `'` as line indicator.
~~~ slim
' Text block
~~~
renders as
~~~ html
Text block
~~~
This is especially useful if you use tags behind a text block.
~~~ slim
' Link to
a href="http://slim-lang.com" slim-lang.com
~~~
renders as
~~~ html
Link to slim-lang.com
~~~
Multiple lines can be indented beneath the first text line.
~~~ slim
' Text
block
with
multiple
lines
~~~
renders as
~~~ html
Text
block
with
multiple
lines
~~~
The first line of a text block determines the indentation.
~~~ slim
'
Text
block
with
multiple
lines
~~~
renders as
~~~ html
Text
block
with
multiple
lines
~~~
### Inline HTML `<`
HTML can be written directly.
~~~ slim
slim-lang.com
~~~
renders as
~~~ html
slim-lang.com
~~~
HTML tags allow nested blocks inside.
~~~ slim
title Example
body
- if true
| yes
- else
| no
~~~
renders as
~~~ html
Example
yes
~~~
### Control code `-`
The dash `-` denotes arbitrary control code.
~~~ slim
- greeting = 'Hello, World!'
- if false
| Not true
- else
= greeting
~~~
renders as
~~~ html
Hello, World!
~~~
Complex code can be broken with backslash `\`.
~~~ slim
- greeting = 'Hello, '+\
\
'World!'
- if false
| Not true
- else
= greeting
~~~
renders as
~~~ html
Hello, World!
~~~
You can also write loops like this
~~~ slim
- items = [{name: 'table', price: 10}, {name: 'chair', price: 5}]
table#items
- for item in items do
tr
td.name = item[:name]
td.price = item[:price]
~~~
which renders as
~~~ html
table
10
chair
5
~~~
The `do` keyword can be omitted.
~~~ slim
- items = [{name: 'table', price: 10}, {name: 'chair', price: 5}]
table#items
- for item in items
tr
td.name = item[:name]
td.price = item[:price]
~~~
which renders as
~~~ html
table
10
chair
5
~~~
### Output `=`
The equal sign `=` produces dynamic output.
~~~ slim
= 7*7
~~~
renders as
~~~ html
49
~~~
Dynamic output is escaped by default.
~~~ slim
= ''
~~~
renders as
~~~ html
<script>evil();</script>
~~~
Long code lines can be broken with `\`.
~~~ slim
= (0..10).map do |i|\
2**i \
end.join(', ')
~~~
renders as
~~~ html
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024
~~~
You don't need the explicit `\` if the line ends with a comma `,`.
~~~ slim
ruby:
def test(*args)
args.join('-')
end
= test('arg1',
'arg2',
'arg3')
~~~
renders as
~~~ html
arg1-arg2-arg3
~~~
You can also disable HTML escaping globally by setting the option
~~~ options
:disable_escape => true
~~~
~~~ slim
= ''
~~~
renders as
~~~ html
~~~
The equal sign with modifier `=>` produces dynamic output with a trailing white space.
~~~ slim
=> 7*7
~~~
renders as
~~~ html
49
~~~
~~~ slim
=< 7*7
~~~
renders as
~~~ html
49
~~~
The legacy syntax `='` is also supported.
~~~ slim
=' 7*7
~~~
renders as
~~~ html
49
~~~
The equal sign with modifier `=<` produces dynamic output with a leading white space.
~~~ slim
=< 7*7
~~~
renders as
~~~ html
49
~~~
The equal sign with modifiers `=<>` produces dynamic output with a leading and trailing white space.
~~~ slim
=<> 7*7
~~~
renders as
~~~ html
49
~~~
### Output without HTML escaping `==`
The double equal sign `==` produces dynamic output without HTML escaping.
~~~ slim
== ''
~~~
renders as
~~~ html
~~~
The option option
~~~ options
:disable_escape => true
~~~
doesn't affect the output of `==`.
~~~ slim
== ''
~~~
renders as
~~~ html
~~~
The double equal sign with modifier `==>` produces dynamic output without HTML escaping and trailing white space.
~~~ slim
==> ''
~~~
renders as
~~~ html
~~~
The legacy syntax `=='` is also supported.
~~~ slim
==' ''
~~~
renders as
~~~ html
~~~
The option option
~~~ options
:disable_escape => true
~~~
doesn't affect the output of `==`.
~~~ slim
==' ''
~~~
renders as
~~~ html
~~~
### Code comment `/`
Code comments begin with `/` and produce no output.
~~~ slim
/ Comment
body
/ Another comment
with
multiple lines
p Hello!
~~~
renders as
~~~ html
Hello!
~~~
### HTML comment `/!`
Code comments begin with `/!`.
~~~ slim
/! Comment
body
/! Another comment
with multiple lines
p Hello!
/!
First line determines indentation
of the comment
~~~
renders as
~~~ html
Hello!
~~~
### IE conditional comment `/[...]`
~~~ slim
/[if IE]
p Get a better browser.
~~~
renders as
~~~ html
~~~
## HTML tags
### Doctype tags
The doctype tag is a special tag which can be used to generate the complex doctypes in a very simple way.
You can output the XML version using the doctype tag.
~~~ slim
doctype xml
doctype xml ISO-8859-1
~~~
renders as
~~~ html
~~~
In XHTML mode the following doctypes are supported:
~~~ slim
doctype html
doctype 5
doctype 1.1
doctype strict
doctype frameset
doctype mobile
doctype basic
doctype transitional
~~~
renders as
~~~ html
~~~
If we activate HTML mode with the option
~~~ options
:format => :html
~~~
the following doctypes are supported:
~~~ slim
doctype html
doctype 5
doctype strict
doctype frameset
doctype transitional
~~~
renders as
~~~ html
~~~
### Closed tags
You can close tags explicitly by appending a trailing `/`.
~~~ slim
div id="not-closed"
.closed/
#closed/
div id="closed"/
~~~
renders as
~~~ html
~~~
Note, that this is usually not necessary since the standard html tags (img, br, ...) are closed automatically.
~~~ slim
img src="image.png"
~~~
renders as
~~~ html
~~~
### Trailing and leading whitespace
You can force a trailing whitespace behind a tag by adding `>`. The legacy syntax with `'` is also supported.
~~~ slim
a#closed> class="test" /
a#closed> class="test"/
a> href='url1' Link1
a< href='url1' Link1
a' href='url2' Link2
~~~
renders as
~~~ html
Link1Link1Link2
~~~
If you combine > and =' only one trailing whitespace is added.
~~~ slim
a> =' 'Text1'
a =' 'Text2'
a> = 'Text3'
a>= 'Text4'
a=> 'Text5'
a<= 'Text6'
a=< 'Text7'
~~~
renders as
~~~ html
Text1Text2Text3Text4Text5Text6Text7
~~~
You can force a leading whitespace before a tag by adding `<`.
~~~ slim
a#closed< class="test" /
a#closed< class="test"/
a< href='url1' Link1
a< href='url2' Link2
~~~
~~~ html
Link1Link2
~~~
You can also combine both.
~~~ slim
a#closed<> class="test" /
a#closed>< class="test"/
a<> href='url1' Link1
a<> href='url2' Link2
~~~
~~~ html
Link1Link2
~~~
### Inline tags
Sometimes you may want to be a little more compact and inline the tags.
~~~ slim
ul
li.first: a href="/first" First
li: a href="/second" Second
~~~
renders as
~~~ html
~~~
For readability, don't forget you can wrap the attributes.
~~~ slim
ul
li.first: a(href="/first") First
li: a(href="/second") Second
~~~
renders as
~~~ html
~~~
### Text content
### Dynamic content `=`
### Attributes
#### Attribute wrapper
If a delimiter makes the syntax more readable for you, you can use the characters `{...}`, `(...)`, `[...]` to wrap the attributes.
~~~ slim
li
a(href="http://slim-lang.com" class="important") Link
li
a[href="http://slim-lang.com" class="important"] Link
li
a{href="http://slim-lang.com" class="important"} Link
~~~
renders as
~~~ html
~~~
If you wrap the attributes, you can spread them across multiple lines:
~~~ slim
a(href="http://slim-lang.com"
class="important") Link
~~~
renders as
~~~ html
Link
~~~
~~~ slim
dl(
itemprop='address'
itemscope
itemtype='http://schema.org/PostalAddress'
)
~~~
renders as
~~~ html
~~~
You may use spaces around the wrappers and assignments:
~~~ slim
h1 id = "logo" Logo
h2 [ id = "tagline" ] Tagline
~~~
renders as
~~~ html
Logo
Tagline
~~~
#### Quoted attributes
You can use single or double quotes for simple text attributes.
~~~ slim
a href="http://slim-lang.com" title='Slim Homepage' Goto the Slim homepage
~~~
renders as
~~~ html
Goto the Slim homepage
~~~
You can use text interpolation in the quoted attributes:
~~~ slim
- url='slim-lang.com'
a href="http://#{url}" Goto the #{url}
a href="{"test"}" Test of quoted text in braces
~~~
renders as
~~~ html
Goto the slim-lang.comTest of quoted text in braces
~~~
The attribute value will be escaped by default. Use == if you want to disable escaping in the attribute.
~~~ slim
li
a href='&' Link
li
a href=="&" Link
~~~
renders as
~~~ html
~~~
You can use newlines in quoted attributes
~~~ slim
a data-title="help" data-content="extremely long help text that goes on
and one and one and then starts over...." Link
~~~
renders as
~~~ html
Link
~~~
You can break quoted attributes with an backslash `\`
~~~ slim
a data-title="help" data-content="extremely long help text that goes on\
and one and one and then starts over...." Link
~~~
renders as
~~~ html
Link
~~~
#### Ruby attributes
Long ruby attributes can be broken with backslash `\`
~~~ slim
a href=1+\
1 Link
~~~
renders as
~~~ html
Link
~~~
You don't need the explicit `\` if the line ends with a comma `,`.
~~~ slim
ruby:
def test(*args)
args.join('-')
end
a href=test('arg1',
'arg2',
'arg3') Link
~~~
renders as
~~~ html
Link
~~~
#### Boolean attributes
The attribute values `true`, `false` and `nil` are interpreted as booleans.
If you use the attribut wrapper you can omit the attribute assigment.
~~~ slim
- true_value1 = ""
- true_value2 = true
input type="text" disabled=true_value1
input type="text" disabled=true_value2
input type="text" disabled="disabled"
input type="text" disabled=true
input(type="text" disabled)
~~~
renders as
~~~ html
~~~
~~~ slim
- false_value1 = false
- false_value2 = nil
input type="text" disabled=false_value1
input type="text" disabled=false_value2
input type="text"
input type="text" disabled=false
input type="text" disabled=nil
~~~
renders as
~~~ html
~~~
If html5 is activated the attributes are written as standalone.
~~~ options
:format => :html
~~~
~~~ slim
- true_value1 = ""
- true_value2 = true
input type="text" disabled=true_value1
input type="text" disabled=true_value2
input type="text" disabled="disabled"
input type="text" disabled=true
input(type="text" disabled)
~~~
renders as
~~~ html
~~~
#### Attribute merging
You can configure attributes to be merged if multiple are given (See option `:merge_attrs`). In the default configuration
this is done for class attributes with the white space as delimiter.
~~~ slim
a.menu class="highlight" href="http://slim-lang.com/" Slim-lang.com
~~~
renders as
~~~ html
Slim-lang.com
~~~
You can also use an `Array` as attribute value and the array elements will be merged using the delimiter.
~~~ slim
- classes = [:alpha, :beta]
span class=["first","highlight"] class=classes First
span class=:second,:highlight class=classes Second
~~~
renders as
~~~ html
FirstSecond
~~~
#### Splat attributes `*`
#### Dynamic tags `*`
You can create completely dynamic tags using the splat attributes. Just create a method which returns a hash
with the :tag key.
~~~ slim
ruby:
def a_unless_current
@page_current ? {tag: 'span'} : {tag: 'a', href: 'http://slim-lang.com/'}
end
- @page_current = true
*a_unless_current Link
- @page_current = false
*a_unless_current Link
~~~
renders as
~~~ html
LinkLink
~~~
### Shortcuts
#### Tag shortcuts
We add tag shortcuts by setting the option `:shortcut`.
~~~ options
:shortcut => {'c' => {tag: 'container'}, 'sec' => {tag:'section'}, '#' => {attr: 'id'}, '.' => {attr: 'class'} }
~~~
~~~ slim
sec: c.content Text
~~~
renders to
~~~ html
Text
~~~
#### Attribute shortcuts
We add `&` to create a shortcut for the input elements with type attribute by setting the option `:shortcut`.
~~~ options
:shortcut => {'&' => {tag: 'input', attr: 'type'}, '#' => {attr: 'id'}, '.' => {attr: 'class'} }
~~~
~~~ slim
&text name="user"
&password name="pw"
&submit.CLASS#ID
~~~
renders to
~~~ html
~~~
This is stupid, but you can also use multiple character shortcuts.
~~~ options
:shortcut => {'&' => {tag: 'input', attr: 'type'}, '#<' => {attr: 'id'}, '#>' => {attr: 'class'} }
~~~
~~~ slim
&text name="user"
&password name="pw"
&submit#>CLASS#
~~~
You can also set multiple attributes per shortcut.
~~~ options
:shortcut => {'.' => {attr: %w(id class)} }
~~~
~~~ slim
.test
~~~
renders to
~~~ html
~~~
Shortcuts can also have multiple characters.
~~~ options
:shortcut => {'.' => {attr: 'class'}, '#' => {attr: 'id'}, '.#' => {attr: %w(class id)} }
~~~
~~~ slim
.#test
.test
#test
~~~
renders to
~~~ html
~~~
#### ID shortcut and class shortcut `.`
ID and class shortcuts can contain dashes.
~~~ slim
.-test text
#test- text
.--a#b- text
.a--test-123#--b text
~~~
renders as
~~~ html
text
text
text
text
~~~
## Text interpolation
Use standard Ruby interpolation. The text will be html escaped by default.
~~~ slim
- user="John Doe "
h1 Welcome #{user}!
~~~
renders as
~~~ html
Welcome John Doe <john@doe.net>!
~~~
## Pretty printing of XML
We can enable XML mode with
~~~ options
:format => :xml
~~~
~~~ slim
doctype xml
document
closed-element/
element(boolean-attribute)
child attribute="value"
| content
~~~
~~~ html
content
~~~
## Embedded engines
## Configuring Slim
## Plugins
slim-3.0.6/test/smart/ 0000755 0000041 0000041 00000000000 12555545227 014635 5 ustar www-data www-data slim-3.0.6/test/smart/test_smart_text.rb 0000644 0000041 0000041 00000007717 12555545227 020427 0 ustar www-data www-data # -*- coding: utf-8 -*-
require 'helper'
require 'slim/smart'
class TestSlimSmartText < TestSlim
def test_explicit_smart_text_recognition
source = %q{
>
a
>
b
>
c
>
d
> e
f
> g
h
i
}
result = %q{a
b
c
d
e
g
h
}
assert_html result, source
end
def test_implicit_smart_text_recognition
source = %q{
p
A
p
B
p
C
p
D
p E
F
p G
H
I
}
result = %q{
A
B
C
D
E
F
G
H
I}
assert_html result, source
end
def test_multi_line_smart_text
source = %q{
p
First line.
Second line.
Third line
with a continuation
and one more.
Fourth line.
}
result = %q{
First line.
Second line.
Third line
with a continuation
and one more.
Fourth line.
}
assert_html result, source
end
def test_smart_text_mixed_with_tags
source = %q{
p
Text
br
>is
strong really
> recognized.
More
b text
.
And
i more
...
span Really
?!?
.bold Really
!!!
#id
#{'Good'}
!
}
result = %q{
Text
is
really
recognized.
More
text.
And
more...
Really?!?
Really
!!!
Good
!}
assert_html result, source
end
def test_smart_text_mixed_with_links
source = %q{
p
Text with
a href="#1" link
.
Text with
a href="#2" another
link
> to somewhere else.
a href="#3"
This link
> goes
elsewhere.
See (
a href="#4" link
)?
}
result = %q{
}
assert_html result, source
end
def test_smart_text_mixed_with_code
source = %q{
p
Try a list
ul
- 2.times do |i|
li
Item: #{i}
> which stops
b here
. Right?
}
result = %q{
Try a list
Item: 0
Item: 1
which stops
here. Right?}
assert_html result, source
end
# Without unicode support, we can't distinguish uppercase and lowercase
# unicode characters reliably. So we only test the basic text, not tag names.
def test_basic_unicode_smart_text
source = %q{
p
是
čip
Čip
Žůžo
šíp
}
result = %q{
是
čip
Čip
Žůžo
šíp
}
assert_html result, source
end
def test_unicode_smart_text
source = %q{
p
是
čip
Čip
Žůžo
šíp
.řek
.
}
result = %q{
是
čip
Čip
Žůžo
šíp
.
}
assert_html result, source
end
end
slim-3.0.6/test/translator/ 0000755 0000041 0000041 00000000000 12555545227 015700 5 ustar www-data www-data slim-3.0.6/test/translator/test_translator.rb 0000644 0000041 0000041 00000005034 12555545227 021457 0 ustar www-data www-data require 'helper'
require 'slim/translator'
class TestSlimTranslator < TestSlim
def setup
super
Slim::Engine.set_options tr: true, tr_fn: 'TestSlimTranslator.tr'
end
def self.tr(s)
s.upcase
end
def self.tr_reverse(s)
s.reverse.gsub(/(\d+)%/, '%\1')
end
def test_no_translation_of_embedded
source = %q{
markdown:
#Header
Hello from #{"Markdown!"}
#{1+2}
* one
* two
}
case Tilt['md'].name.downcase
when /redcarpet/
assert_html "
Header
\n\n
Hello from Markdown!
\n\n
3
\n\n
\n
one
\n
two
\n
\n", source, tr_mode: :dynamic
assert_html "
Header
\n\n
Hello from Markdown!
\n\n
3
\n\n
\n
one
\n
two
\n
\n", source, tr_mode: :static
when /rdiscount/
assert_html "
Header
\n\n
Hello from Markdown!
\n\n
3
\n\n
\n
one
\n
two
\n
\n\n", source, tr_mode: :dynamic
assert_html "
Header
\n\n
Hello from Markdown!
\n\n
3
\n\n
\n
one
\n
two
\n
\n\n", source, tr_mode: :static
when /kramdown/
assert_html "
Header
\n
Hello from Markdown!
\n\n
3
\n\n
\n
one
\n
two
\n
\n", source, tr_mode: :dynamic
assert_html "
Header
\n
Hello from Markdown!
\n\n
3
\n\n
\n
one
\n
two
\n
\n", source, tr_mode: :static
else
raise "Missing test for #{Tilt['md']}"
end
end
def test_no_translation_of_attrs
source = %q{
' this is
a link to
a href="link" page
}
assert_html "THIS IS\nA LINK TO PAGE", source, tr_mode: :dynamic
assert_html "THIS IS\nA LINK TO PAGE", source, tr_mode: :static
end
def test_translation_and_interpolation
source = %q{
p translate #{hello_world} this
second line
third #{1+2} line
}
assert_html "
translate Hello World from @env this\nsecond line\nthird 3 line
", source, tr: false
assert_html "
TRANSLATE Hello World from @env THIS\nSECOND LINE\nTHIRD 3 LINE
", source, tr_mode: :dynamic
assert_html "
TRANSLATE Hello World from @env THIS\nSECOND LINE\nTHIRD 3 LINE
", source, tr_mode: :static
end
def test_translation_reverse
source = %q{
' alpha #{1} beta #{2} gamma #{3}
}
assert_html "3 ammag 2 ateb 1 ahpla ", source, tr_mode: :dynamic, tr_fn: 'TestSlimTranslator.tr_reverse'
assert_html "3 ammag 2 ateb 1 ahpla ", source, tr_mode: :static, tr_fn: 'TestSlimTranslator.tr_reverse'
end
end
slim-3.0.6/test/rails/ 0000755 0000041 0000041 00000000000 12555545227 014621 5 ustar www-data www-data slim-3.0.6/test/rails/Rakefile 0000644 0000041 0000041 00000000411 12555545227 016262 0 ustar www-data www-data # Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require File.expand_path('../config/application', __FILE__)
require 'rake'
Dummy::Application.load_tasks
slim-3.0.6/test/rails/script/ 0000755 0000041 0000041 00000000000 12555545227 016125 5 ustar www-data www-data slim-3.0.6/test/rails/script/rails 0000755 0000041 0000041 00000000447 12555545227 017172 0 ustar www-data www-data #!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'
slim-3.0.6/test/rails/test/ 0000755 0000041 0000041 00000000000 12555545227 015600 5 ustar www-data www-data slim-3.0.6/test/rails/test/test_slim.rb 0000644 0000041 0000041 00000005316 12555545227 020135 0 ustar www-data www-data require File.expand_path('../helper', __FILE__)
class TestSlim < ActionDispatch::IntegrationTest
test "normal view" do
get "/slim/normal"
assert_response :success
assert_template "slim/normal"
assert_template "layouts/application"
assert_html "
Hello Slim!
"
end
test "xml view" do
get "/slim/xml"
assert_response :success
assert_template "slim/xml"
assert_template "layouts/application"
assert_html "
Hello Slim!
"
end
test "helper" do
get "/slim/helper"
assert_response :success
assert_template "slim/helper"
assert_template "layouts/application"
assert_html "
Hello User
"
end
test "normal erb view" do
get "/slim/erb"
assert_html "
Hello Erb!
"
end
test "view without a layout" do
get "/slim/no_layout"
assert_template "slim/no_layout"
assert_html "
Hello Slim without a layout!
", skip_layout: true
end
test "view with variables" do
get "/slim/variables"
assert_html "
Hello Slim with variables!
"
end
test "partial view" do
get "/slim/partial"
assert_html "
Hello Slim!
With a partial!
"
end
if RUBY_ENGINE == 'jruby' && RUBY_ENGINE < '2.2.0'
puts 'Streaming test disabled for JRuby < 9000.',
'See https://github.com/jruby/jruby/issues/1243',
'and https://github.com/jruby/jruby/issues/1789'
else
puts 'Streaming test enabled.'
test "streaming" do
get "/slim/streaming"
output = "2f\r\nDummy\r\nd\r\n\r\n17\r\nHeading set from a view\r\n15\r\n
\r\n53\r\n
Page content
Hello Streaming!
Hello Streaming!
\r\n14\r\n
\r\n0\r\n\r\n"
assert_equal output, @response.body
end
end
test "render integers" do
get "/slim/integers"
assert_html "
1337
"
end
test "render thread_options" do
get "/slim/thread_options", attr: 'role'
assert_html '
Test
'
get "/slim/thread_options", attr: 'id' # Overwriting doesn't work because of caching
assert_html '
Test
'
end
test "content_for" do
get "/slim/content_for"
assert_html "
Page content
Hello Slim!
Hello Slim!
", heading: 'Heading set from a view'
end
test "form_for" do
get "/entries/edit/1"
assert_match %r{action="/entries"}, @response.body
assert_match %r{}, @response.body
assert_xpath '//input[@id="entry_name" and @name="entry[name]" and @type="text"]'
end
test "splat" do
get "/slim/splat"
assert_html "
Hello
"
end
end
slim-3.0.6/test/rails/test/helper.rb 0000644 0000041 0000041 00000001641 12555545227 017406 0 ustar www-data www-data # Configure Rails Envinronment
ENV["RAILS_ENV"] = "test"
require File.expand_path("../../config/environment.rb", __FILE__)
require "rails/test_help"
require "nokogiri"
Rails.backtrace_cleaner.remove_silencers!
class ActionDispatch::IntegrationTest
protected
def assert_xpath(xpath, message="Unable to find '#{xpath}' in response body.")
assert_response :success, "Response type is not :success (code 200..299)."
body = @response.body
assert !body.empty?, "No response body found."
doc = Nokogiri::HTML(body) rescue nil
assert_not_nil doc, "Cannot parse response body."
assert doc.xpath(xpath).size >= 1, message
end
def assert_html(expected, options = {})
expected = "Dummy#{options[:heading]}
#{expected}
" unless options[:skip_layout]
assert_equal expected, @response.body
end
end
slim-3.0.6/test/rails/config/ 0000755 0000041 0000041 00000000000 12555545227 016066 5 ustar www-data www-data slim-3.0.6/test/rails/config/application.rb 0000644 0000041 0000041 00000003543 12555545227 020723 0 ustar www-data www-data require File.expand_path('../boot', __FILE__)
require 'active_model/railtie'
require 'action_controller/railtie'
require 'action_view/railtie'
#require 'active_record/railtie'
#require 'action_mailer/railtie'
require 'slim'
module Dummy
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
# Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
# JavaScript files you want as :defaults (application.js is always included).
# config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
end
end
slim-3.0.6/test/rails/config/initializers/ 0000755 0000041 0000041 00000000000 12555545227 020574 5 ustar www-data www-data slim-3.0.6/test/rails/config/initializers/secret_token.rb 0000644 0000041 0000041 00000001034 12555545227 023604 0 ustar www-data www-data # Be sure to restart your server when you modify this file.
# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
Dummy::Application.config.secret_token = Dummy::Application.config.secret_key_base = '123a9119fb14a410f485f9390286b33f2743b9d348246cf3e4434522078f77c202d7a1fb7e42666dd0844bcb10d0ff3d8b4ee087796269d4c574837948512dbf'
slim-3.0.6/test/rails/config/initializers/session_store.rb 0000644 0000041 0000041 00000000627 12555545227 024025 0 ustar www-data www-data # Be sure to restart your server when you modify this file.
Dummy::Application.config.session_store :cookie_store, key: '_dummy_session'
# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration")
# Dummy::Application.config.session_store :active_record_store
slim-3.0.6/test/rails/config/initializers/mime_types.rb 0000644 0000041 0000041 00000000315 12555545227 023273 0 ustar www-data www-data # Be sure to restart your server when you modify this file.
# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
# Mime::Type.register_alias "text/html", :iphone
slim-3.0.6/test/rails/config/initializers/backtrace_silencers.rb 0000644 0000041 0000041 00000000624 12555545227 025111 0 ustar www-data www-data # Be sure to restart your server when you modify this file.
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!
slim-3.0.6/test/rails/config/initializers/inflections.rb 0000644 0000041 0000041 00000000570 12555545227 023440 0 ustar www-data www-data # Be sure to restart your server when you modify this file.
# Add new inflection rules using the following format
# (all these examples are active by default):
# ActiveSupport::Inflector.inflections do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep )
# end
slim-3.0.6/test/rails/config/boot.rb 0000644 0000041 0000041 00000000417 12555545227 017360 0 ustar www-data www-data require 'rubygems'
gemfile = File.expand_path('../../../../../../Gemfile', __FILE__)
if File.exist?(gemfile)
ENV['BUNDLE_GEMFILE'] = gemfile
require 'bundler'
Bundler.setup(:default, :integration)
end
$:.unshift File.expand_path('../../../../../../lib', __FILE__) slim-3.0.6/test/rails/config/environments/ 0000755 0000041 0000041 00000000000 12555545227 020615 5 ustar www-data www-data slim-3.0.6/test/rails/config/environments/test.rb 0000644 0000041 0000041 00000002645 12555545227 022130 0 ustar www-data www-data Dummy::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Raise exceptions instead of rendering exception templates
config.action_dispatch.show_exceptions = false
# Disable request forgery protection in test environment
config.action_controller.allow_forgery_protection = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
#config.action_mailer.delivery_method = :test
# Use SQL instead of Active Record's schema dumper when creating the test database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
# Print deprecation notices to the stderr
config.active_support.deprecation = :stderr
config.eager_load = false
end
slim-3.0.6/test/rails/config/routes.rb 0000644 0000041 0000041 00000003402 12555545227 017733 0 ustar www-data www-data Dummy::Application.routes.draw do
# The priority is based upon order of creation:
# first created -> highest priority.
resources :entries
# Sample of regular route:
# match 'products/:id' => 'catalog#view'
# Keep in mind you can assign values other than :controller and :action
# Sample of named route:
# match 'products/:id/purchase' => 'catalog#purchase', as: :purchase
# This route can be invoked with purchase_url(id: product.id)
# Sample resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Sample resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Sample resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Sample resource route with more complex sub-resources
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', on: :collection
# end
# end
# Sample resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
# root to: "welcome#index"
# See how all your routes lay out with "rake routes"
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
get ':controller(/:action(/:id(.:format)))'
end
slim-3.0.6/test/rails/config/environment.rb 0000644 0000041 0000041 00000000225 12555545227 020756 0 ustar www-data www-data # Load the rails application
require File.expand_path('../application', __FILE__)
# Initialize the rails application
Dummy::Application.initialize!
slim-3.0.6/test/rails/config/locales/ 0000755 0000041 0000041 00000000000 12555545227 017510 5 ustar www-data www-data slim-3.0.6/test/rails/config/locales/en.yml 0000644 0000041 0000041 00000000325 12555545227 020635 0 ustar www-data www-data # Sample localization file for English. Add more files in this directory for other locales.
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
hello: "Hello world"
slim-3.0.6/test/rails/app/ 0000755 0000041 0000041 00000000000 12555545227 015401 5 ustar www-data www-data slim-3.0.6/test/rails/app/views/ 0000755 0000041 0000041 00000000000 12555545227 016536 5 ustar www-data www-data slim-3.0.6/test/rails/app/views/entries/ 0000755 0000041 0000041 00000000000 12555545227 020207 5 ustar www-data www-data slim-3.0.6/test/rails/app/views/entries/edit.html.slim 0000644 0000041 0000041 00000000100 12555545227 022754 0 ustar www-data www-data = form_for @entry do |f|
label: b Name
= f.text_field :name
slim-3.0.6/test/rails/app/views/slim/ 0000755 0000041 0000041 00000000000 12555545227 017502 5 ustar www-data www-data slim-3.0.6/test/rails/app/views/slim/variables.html.slim 0000644 0000041 0000041 00000000012 12555545227 023274 0 ustar www-data www-data h1= @hello slim-3.0.6/test/rails/app/views/slim/form_for.html.slim 0000644 0000041 0000041 00000000060 12555545227 023140 0 ustar www-data www-data = form_for @entry do |f|
= f.text_field :name
slim-3.0.6/test/rails/app/views/slim/_partial.html.slim 0000644 0000041 0000041 00000000021 12555545227 023117 0 ustar www-data www-data p With a partial! slim-3.0.6/test/rails/app/views/slim/xml.slim 0000644 0000041 0000041 00000000016 12555545227 021165 0 ustar www-data www-data h1 Hello Slim! slim-3.0.6/test/rails/app/views/slim/erb.html.erb 0000644 0000041 0000041 00000000023 12555545227 021702 0 ustar www-data www-data