Fix Rubocop issues
This commit is contained in:
parent
209a3706a5
commit
cb479c9d5e
32
Gemfile
32
Gemfile
|
@ -1,34 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
source "https://rubygems.org"
|
||||
|
||||
eval_gemfile 'Gemfile.devtools'
|
||||
eval_gemfile "Gemfile.devtools"
|
||||
|
||||
gemspec
|
||||
|
||||
group :tools do
|
||||
gem 'hotch'
|
||||
gem 'pry-byebug', platform: :mri
|
||||
gem "hotch"
|
||||
gem "pry-byebug", platform: :mri
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'rack', '>= 2.0.6'
|
||||
gem "rack", ">= 2.0.6"
|
||||
|
||||
gem 'erbse'
|
||||
gem 'erubi'
|
||||
gem 'hamlit'
|
||||
gem 'hamlit-block'
|
||||
gem 'slim', '~> 4.0'
|
||||
gem "erbse"
|
||||
gem "erubi"
|
||||
gem "hamlit"
|
||||
gem "hamlit-block"
|
||||
gem "slim", "~> 4.0"
|
||||
end
|
||||
|
||||
group :benchmarks do
|
||||
gem 'benchmark-ips'
|
||||
gem 'actionview'
|
||||
gem 'actionpack'
|
||||
gem "actionpack"
|
||||
gem "actionview"
|
||||
gem "benchmark-ips"
|
||||
end
|
||||
|
||||
group :docs do
|
||||
gem 'yard'
|
||||
gem 'yard-junk'
|
||||
gem 'redcarpet', platforms: :mri
|
||||
gem "redcarpet", platforms: :mri
|
||||
gem "yard"
|
||||
gem "yard-junk"
|
||||
end
|
||||
|
|
4
Rakefile
4
Rakefile
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'bundler/gem_tasks'
|
||||
require "bundler/gem_tasks"
|
||||
|
||||
require 'rspec/core/rake_task'
|
||||
require "rspec/core/rake_task"
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
|
||||
task default: [:spec]
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'pathname'
|
||||
require 'ostruct'
|
||||
require 'benchmark/ips'
|
||||
require 'dry/view'
|
||||
require 'action_view'
|
||||
require 'action_controller'
|
||||
require "pathname"
|
||||
require "ostruct"
|
||||
require "benchmark/ips"
|
||||
require "dry/view"
|
||||
require "action_view"
|
||||
require "action_controller"
|
||||
|
||||
TEMPLATES_PATHS = Pathname(__FILE__).dirname.join('templates')
|
||||
TEMPLATES_PATHS = Pathname(__FILE__).dirname.join("templates")
|
||||
|
||||
TEMPLATE_LOCALS = { users: [
|
||||
OpenStruct.new(name: 'Jane', email: 'Jane@example.com'),
|
||||
OpenStruct.new(name: 'Teresa', email: 'teresa@example.com')
|
||||
] }
|
||||
TEMPLATE_LOCALS = {
|
||||
users: [
|
||||
OpenStruct.new(name: "Jane", email: "Jane@example.com"),
|
||||
OpenStruct.new(name: "Teresa", email: "teresa@example.com")
|
||||
]
|
||||
}.freeze
|
||||
|
||||
ActionController::Base.view_paths = TEMPLATES_PATHS
|
||||
|
||||
class UsersController < ActionController::Base
|
||||
layout 'app'
|
||||
layout "app"
|
||||
|
||||
attr_reader :users
|
||||
|
||||
|
@ -29,8 +31,8 @@ end
|
|||
|
||||
class DryView < Dry::View
|
||||
config.paths = TEMPLATES_PATHS
|
||||
config.layout = 'app'
|
||||
config.template = 'users'
|
||||
config.layout = "app"
|
||||
config.template = "users"
|
||||
config.default_format = :html
|
||||
|
||||
expose :users
|
||||
|
@ -39,7 +41,10 @@ end
|
|||
action_controller = UsersController.new
|
||||
dry_view = DryView.new
|
||||
|
||||
if (action_controller_output = action_controller.index) != (dry_view_output = dry_view.(TEMPLATE_LOCALS).to_s)
|
||||
action_controller_output = action_controller.index
|
||||
dry_view_output = dry_view.(TEMPLATE_LOCALS).to_s
|
||||
|
||||
if action_controller_output != dry_view_output
|
||||
puts "Output doesn't match:"
|
||||
puts
|
||||
puts "ActionView:\n\n#{action_controller_output}\n"
|
||||
|
@ -47,11 +52,11 @@ if (action_controller_output = action_controller.index) != (dry_view_output = dr
|
|||
end
|
||||
|
||||
Benchmark.ips do |x|
|
||||
x.report('action_controller') do
|
||||
x.report("action_controller") do
|
||||
1000.times { action_controller.index }
|
||||
end
|
||||
|
||||
x.report('dry-view') do
|
||||
x.report("dry-view") do
|
||||
1000.times { dry_view.(TEMPLATE_LOCALS).to_s }
|
||||
end
|
||||
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'hotch'
|
||||
require 'pathname'
|
||||
require 'ostruct'
|
||||
require 'dry/view'
|
||||
require "hotch"
|
||||
require "pathname"
|
||||
require "ostruct"
|
||||
require "dry/view"
|
||||
|
||||
TEMPLATES_PATHS = Pathname(__FILE__).dirname.join('templates')
|
||||
TEMPLATES_PATHS = Pathname(__FILE__).dirname.join("templates")
|
||||
|
||||
TEMPLATE_LOCALS = { users: [
|
||||
OpenStruct.new(name: 'Jane', email: 'Jane@example.com'),
|
||||
OpenStruct.new(name: 'Teresa', email: 'teresa@example.com')
|
||||
] }
|
||||
TEMPLATE_LOCALS = {
|
||||
users: [
|
||||
OpenStruct.new(name: "Jane", email: "Jane@example.com"),
|
||||
OpenStruct.new(name: "Teresa", email: "teresa@example.com")
|
||||
]
|
||||
}.freeze
|
||||
|
||||
class View < Dry::View
|
||||
config.paths = TEMPLATES_PATHS
|
||||
config.layout = 'app'
|
||||
config.template = 'users'
|
||||
config.layout = "app"
|
||||
config.template = "users"
|
||||
|
||||
expose :users
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'bundler/setup'
|
||||
require 'dry-view'
|
||||
require "bundler/setup"
|
||||
require "dry-view"
|
||||
|
||||
require 'pry'
|
||||
require "pry"
|
||||
Pry.start
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'setup_helpers'
|
||||
require_relative "setup_helpers"
|
||||
|
||||
Setup.execute 'bundle'
|
||||
Setup.execute "bundle"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'open3'
|
||||
require "open3"
|
||||
|
||||
module Setup
|
||||
module_function
|
||||
|
@ -18,7 +18,7 @@ module Setup
|
|||
status = wait_thr.value
|
||||
end
|
||||
|
||||
if !status.success?
|
||||
unless status.success?
|
||||
puts "Failed to run #{cmd}"
|
||||
puts err
|
||||
exit 1
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
source "https://rubygems.org"
|
||||
|
||||
gem 'byebug'
|
||||
gem 'dry-view', path: '../..'
|
||||
gem 'dry-web'
|
||||
gem 'sinatra'
|
||||
gem 'slim'
|
||||
gem "byebug"
|
||||
gem "dry-view", path: "../.."
|
||||
gem "dry-web"
|
||||
gem "sinatra"
|
||||
gem "slim"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative './system/boot'
|
||||
require 'example_app/web'
|
||||
require_relative "./system/boot"
|
||||
require "example_app/web"
|
||||
run ExampleApp::Web
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'ostruct'
|
||||
require "ostruct"
|
||||
|
||||
module ExampleApp
|
||||
Article = Struct.new(:slug, :title)
|
||||
|
||||
class ArticleRepo
|
||||
ARTICLES = [
|
||||
{slug: 'together-breakfast', title: 'Together Breakfast'},
|
||||
{slug: 'cat-fingers', title: 'Cat Fingers'},
|
||||
{slug: "together-breakfast", title: "Together Breakfast"},
|
||||
{slug: "cat-fingers", title: "Cat Fingers"}
|
||||
].freeze
|
||||
|
||||
def by_slug!(slug)
|
||||
if (article = ARTICLES.detect { |a| a[:slug] == slug})
|
||||
if (article = ARTICLES.detect { |a| a[:slug] == slug })
|
||||
Article.new(*article.values)
|
||||
else
|
||||
raise "Article with slug +#{slug}+ not found"
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
# auto_register: false
|
||||
|
||||
require 'dry/view'
|
||||
require 'slim'
|
||||
require 'example_app/container'
|
||||
require "dry/view"
|
||||
require "slim"
|
||||
require "example_app/container"
|
||||
|
||||
module ExampleApp
|
||||
class View < Dry::View
|
||||
config.paths = Container.root.join('web/templates')
|
||||
config.layout = 'application'
|
||||
config.paths = Container.root.join("web/templates")
|
||||
config.layout = "application"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../view'
|
||||
require 'dry/view/context'
|
||||
require_relative "../view"
|
||||
require "dry/view/context"
|
||||
|
||||
module ExampleApp
|
||||
class View
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'example_app/import'
|
||||
require 'example_app/view'
|
||||
require "example_app/import"
|
||||
require "example_app/view"
|
||||
|
||||
module ExampleApp
|
||||
module Views
|
||||
module Articles
|
||||
class Index < View
|
||||
include Import['article_repo']
|
||||
include Import["article_repo"]
|
||||
|
||||
config.template = 'articles/index'
|
||||
config.template = "articles/index"
|
||||
|
||||
expose :articles do
|
||||
article_repo.listing
|
||||
|
@ -18,4 +18,3 @@ module ExampleApp
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'example_app/import'
|
||||
require 'example_app/view'
|
||||
require "example_app/import"
|
||||
require "example_app/view"
|
||||
|
||||
module ExampleApp
|
||||
module Views
|
||||
module Articles
|
||||
class Show < View
|
||||
include Import['article_repo']
|
||||
include Import["article_repo"]
|
||||
|
||||
config.template = 'articles/show'
|
||||
config.template = "articles/show"
|
||||
|
||||
expose :article do |slug:|
|
||||
article_repo.by_slug!(slug)
|
||||
|
@ -18,4 +18,3 @@ module ExampleApp
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'sinatra/base'
|
||||
require 'byebug'
|
||||
require "sinatra/base"
|
||||
require "byebug"
|
||||
|
||||
module ExampleApp
|
||||
class Web < Sinatra::Base
|
||||
get '/' do
|
||||
redirect '/articles'
|
||||
get "/" do
|
||||
redirect "/articles"
|
||||
end
|
||||
|
||||
get '/articles' do
|
||||
render_view 'articles.index'
|
||||
get "/articles" do
|
||||
render_view "articles.index"
|
||||
end
|
||||
|
||||
get '/articles/:slug' do |slug|
|
||||
render_view 'articles.show', slug: slug
|
||||
get "/articles/:slug" do |slug|
|
||||
render_view "articles.show", slug: slug
|
||||
end
|
||||
|
||||
helpers do
|
||||
def render_view(identifier, with: {}, **input)
|
||||
container["views.#{identifier}"].(
|
||||
context: view_context(**with),
|
||||
**input,
|
||||
**input
|
||||
).to_s
|
||||
end
|
||||
|
||||
def view_context(**options)
|
||||
container['view.context'].with(view_context_options(**options))
|
||||
container["view.context"].with(view_context_options(**options))
|
||||
end
|
||||
|
||||
def view_context_options(**overrides)
|
||||
{
|
||||
request: request,
|
||||
request: request
|
||||
}.merge(overrides)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'example_app/container'
|
||||
require_relative "example_app/container"
|
||||
|
||||
container = ExampleApp::Container
|
||||
container.finalize!
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/web/container'
|
||||
require 'dry/system/components'
|
||||
require "dry/web/container"
|
||||
require "dry/system/components"
|
||||
|
||||
module ExampleApp
|
||||
class Container < Dry::Web::Container
|
||||
configure do
|
||||
config.name = :example_app
|
||||
config.log_levels = %i[test development production].map { |e| [e, Logger::DEBUG] }.to_h
|
||||
config.default_namespace = 'example_app'
|
||||
config.default_namespace = "example_app"
|
||||
config.auto_register = %w[lib/example_app]
|
||||
end
|
||||
|
||||
load_paths! 'lib'
|
||||
load_paths! "lib"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'container'
|
||||
require_relative "container"
|
||||
|
||||
module ExampleApp
|
||||
Import = Container.injector
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
source "https://rubygems.org"
|
||||
|
||||
ruby '2.6.0'
|
||||
ruby "2.6.0"
|
||||
|
||||
gem 'rails', '~> 5.2.2'
|
||||
gem 'sqlite3'
|
||||
gem 'puma', '~> 3.11'
|
||||
gem "puma", "~> 3.11"
|
||||
gem "rails", "~> 5.2.2"
|
||||
gem "sqlite3"
|
||||
|
||||
gem 'dry-view', path: '../..'
|
||||
gem 'slim'
|
||||
gem "dry-view", path: "../.."
|
||||
gem "slim"
|
||||
|
||||
group :development, :test do
|
||||
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
|
||||
gem "byebug", platforms: %i[mri mingw x64_mingw]
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'web-console', '>= 3.3.0'
|
||||
gem 'listen', '>= 3.0.5', '< 3.2'
|
||||
gem "listen", ">= 3.0.5", "< 3.2"
|
||||
gem "web-console", ">= 3.3.0"
|
||||
end
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
# 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_relative 'config/application'
|
||||
require_relative "config/application"
|
||||
|
||||
Rails.application.load_tasks
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ApplicationView < Dry::View
|
||||
config.paths = Rails.root.join('app/templates')
|
||||
config.paths = Rails.root.join("app/templates")
|
||||
config.default_context = ApplicationViewContext.new
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view/context'
|
||||
require "dry/view/context"
|
||||
|
||||
class ApplicationViewContext < Dry::View::Context
|
||||
def method_missing(name, *args, &block)
|
||||
|
@ -16,7 +16,9 @@ class ApplicationViewContext < Dry::View::Context
|
|||
private
|
||||
|
||||
def respond_to_missing?(name, include_private = false)
|
||||
url_helpers.respond_to?(name, include_private) || helpers.respond_to?(name, include_private) || super
|
||||
url_helpers.respond_to?(name, include_private) ||
|
||||
helpers.respond_to?(name, include_private) ||
|
||||
super
|
||||
end
|
||||
|
||||
def url_helpers
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
module Views
|
||||
module Articles
|
||||
class Index < ApplicationView
|
||||
config.template = 'articles/index'
|
||||
config.template = "articles/index"
|
||||
|
||||
expose :articles
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
module Views
|
||||
module Articles
|
||||
class Show < ApplicationView
|
||||
config.template = 'articles/show'
|
||||
config.template = "articles/show"
|
||||
|
||||
expose :article
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
||||
load Gem.bin_path('bundler', 'bundle')
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
||||
load Gem.bin_path("bundler", "bundle")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
APP_PATH = File.expand_path('../config/application', __dir__)
|
||||
require_relative '../config/boot'
|
||||
require 'rails/commands'
|
||||
APP_PATH = File.expand_path("../config/application", __dir__)
|
||||
require_relative "../config/boot"
|
||||
require "rails/commands"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../config/boot'
|
||||
require 'rake'
|
||||
require_relative "../config/boot"
|
||||
require "rake"
|
||||
Rake.application.run
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'fileutils'
|
||||
include FileUtils
|
||||
|
||||
# path to your application root.
|
||||
APP_ROOT = File.expand_path('..', __dir__)
|
||||
|
||||
def system!(*args)
|
||||
system(*args) || abort("\n== Command #{args} failed ==")
|
||||
end
|
||||
|
||||
chdir APP_ROOT do
|
||||
# This script is a starting point to setup your application.
|
||||
# Add necessary setup steps to this file.
|
||||
|
||||
puts '== Installing dependencies =='
|
||||
system! 'gem install bundler --conservative'
|
||||
system('bundle check') || system!('bundle install')
|
||||
|
||||
# Install JavaScript dependencies if using Yarn
|
||||
# system('bin/yarn')
|
||||
|
||||
# puts "\n== Copying sample files =="
|
||||
# unless File.exist?('config/database.yml')
|
||||
# cp 'config/database.yml.sample', 'config/database.yml'
|
||||
# end
|
||||
|
||||
puts "\n== Preparing database =="
|
||||
system! 'bin/rails db:setup'
|
||||
|
||||
puts "\n== Removing old logs and tempfiles =="
|
||||
system! 'bin/rails log:clear tmp:clear'
|
||||
|
||||
puts "\n== Restarting application server =="
|
||||
system! 'bin/rails restart'
|
||||
end
|
|
@ -1,33 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'fileutils'
|
||||
include FileUtils
|
||||
|
||||
# path to your application root.
|
||||
APP_ROOT = File.expand_path('..', __dir__)
|
||||
|
||||
def system!(*args)
|
||||
system(*args) || abort("\n== Command #{args} failed ==")
|
||||
end
|
||||
|
||||
chdir APP_ROOT do
|
||||
# This script is a way to update your development environment automatically.
|
||||
# Add necessary update steps to this file.
|
||||
|
||||
puts '== Installing dependencies =='
|
||||
system! 'gem install bundler --conservative'
|
||||
system('bundle check') || system!('bundle install')
|
||||
|
||||
# Install JavaScript dependencies if using Yarn
|
||||
# system('bin/yarn')
|
||||
|
||||
puts "\n== Updating database =="
|
||||
system! 'bin/rails db:migrate'
|
||||
|
||||
puts "\n== Removing old logs and tempfiles =="
|
||||
system! 'bin/rails log:clear tmp:clear'
|
||||
|
||||
puts "\n== Restarting application server =="
|
||||
system! 'bin/rails restart'
|
||||
end
|
|
@ -1,13 +1,13 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
APP_ROOT = File.expand_path('..', __dir__)
|
||||
APP_ROOT = File.expand_path("..", __dir__)
|
||||
Dir.chdir(APP_ROOT) do
|
||||
begin
|
||||
exec 'yarnpkg', *ARGV
|
||||
exec "yarnpkg", *ARGV
|
||||
rescue Errno::ENOENT
|
||||
$stderr.puts 'Yarn executable was not detected in the system.'
|
||||
$stderr.puts 'Download Yarn at https://yarnpkg.com/en/docs/install'
|
||||
warn "Yarn executable was not detected in the system."
|
||||
warn "Download Yarn at https://yarnpkg.com/en/docs/install"
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
# This file is used by Rack-based servers to start the application.
|
||||
|
||||
require_relative 'config/environment'
|
||||
require_relative "config/environment"
|
||||
|
||||
run Rails.application
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'boot'
|
||||
require_relative "boot"
|
||||
|
||||
require 'rails'
|
||||
require 'active_model/railtie'
|
||||
require 'active_record/railtie'
|
||||
require 'action_controller/railtie'
|
||||
require 'action_view/railtie'
|
||||
require "rails"
|
||||
require "active_model/railtie"
|
||||
require "active_record/railtie"
|
||||
require "action_controller/railtie"
|
||||
require "action_view/railtie"
|
||||
|
||||
# Require the gems listed in Gemfile, including any gems
|
||||
# you've limited to :test, :development, or :production.
|
||||
|
@ -17,7 +17,7 @@ module DryViewExample
|
|||
config.load_defaults 5.2
|
||||
|
||||
# dry-view setup
|
||||
Rails.application.config.autoload_paths << Rails.root.join('app/views')
|
||||
Rails.application.config.autoload_paths << Rails.root.join("app/views")
|
||||
|
||||
# Remove heinous monkey patch
|
||||
Dry::View::Part.undef_method :to_param
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
||||
|
||||
require 'bundler/setup' # Set up gems listed in the Gemfile.
|
||||
require "bundler/setup" # Set up gems listed in the Gemfile.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Load the Rails application.
|
||||
require_relative 'application'
|
||||
require_relative "application"
|
||||
|
||||
# Initialize the Rails application.
|
||||
Rails.application.initialize!
|
||||
|
|
|
@ -16,12 +16,12 @@ Rails.application.configure do
|
|||
|
||||
# Enable/disable caching. By default caching is disabled.
|
||||
# Run rails dev:cache to toggle caching.
|
||||
if Rails.root.join('tmp', 'caching-dev.txt').exist?
|
||||
if Rails.root.join("tmp", "caching-dev.txt").exist?
|
||||
config.action_controller.perform_caching = true
|
||||
|
||||
config.cache_store = :memory_store
|
||||
config.public_file_server.headers = {
|
||||
'Cache-Control' => "public, max-age=#{2.days.to_i}"
|
||||
"Cache-Control" => "public, max-age=#{2.days.to_i}"
|
||||
}
|
||||
else
|
||||
config.action_controller.perform_caching = false
|
||||
|
@ -38,7 +38,6 @@ Rails.application.configure do
|
|||
# Highlight code that triggered database queries in logs.
|
||||
config.active_record.verbose_query_logs = true
|
||||
|
||||
|
||||
# Raises error for missing translations
|
||||
# config.action_view.raise_on_missing_translations = true
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ Rails.application.configure do
|
|||
|
||||
# Disable serving static files from the `/public` folder by default since
|
||||
# Apache or NGINX already handles this.
|
||||
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
|
||||
config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present?
|
||||
|
||||
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
|
||||
# config.action_controller.asset_host = 'http://assets.example.com'
|
||||
|
@ -39,7 +39,7 @@ Rails.application.configure do
|
|||
config.log_level = :debug
|
||||
|
||||
# Prepend all log lines with the following tags.
|
||||
config.log_tags = [ :request_id ]
|
||||
config.log_tags = [:request_id]
|
||||
|
||||
# Use a different cache store in production.
|
||||
# config.cache_store = :mem_cache_store
|
||||
|
@ -62,7 +62,7 @@ Rails.application.configure do
|
|||
# require 'syslog/logger'
|
||||
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
|
||||
|
||||
if ENV['RAILS_LOG_TO_STDOUT'].present?
|
||||
if ENV["RAILS_LOG_TO_STDOUT"].present?
|
||||
logger = ActiveSupport::Logger.new(STDOUT)
|
||||
logger.formatter = config.log_formatter
|
||||
config.logger = ActiveSupport::TaggedLogging.new(logger)
|
||||
|
|
|
@ -17,7 +17,7 @@ Rails.application.configure do
|
|||
# Configure public file server for tests with Cache-Control for performance.
|
||||
config.public_file_server.enabled = true
|
||||
config.public_file_server.headers = {
|
||||
'Cache-Control' => "public, max-age=#{1.hour.to_i}"
|
||||
"Cache-Control" => "public, max-age=#{1.hour.to_i}"
|
||||
}
|
||||
|
||||
# Show full error reports and disable caching.
|
||||
|
|
|
@ -6,16 +6,16 @@
|
|||
# the maximum value specified for Puma. Default is set to 5 threads for minimum
|
||||
# and maximum; this matches the default thread size of Active Record.
|
||||
#
|
||||
threads_count = ENV.fetch('RAILS_MAX_THREADS') { 5 }
|
||||
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
|
||||
threads threads_count, threads_count
|
||||
|
||||
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
|
||||
#
|
||||
port ENV.fetch('PORT') { 3000 }
|
||||
port ENV.fetch("PORT") { 3000 }
|
||||
|
||||
# Specifies the `environment` that Puma will run in.
|
||||
#
|
||||
environment ENV.fetch('RAILS_ENV') { 'development' }
|
||||
environment ENV.fetch("RAILS_ENV") { "development" }
|
||||
|
||||
# Specifies the number of `workers` to boot in clustered mode.
|
||||
# Workers are forked webserver processes. If using threads and workers together
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
Rails.application.routes.draw do
|
||||
resources :articles, only: %i[index show]
|
||||
root to: 'articles#index'
|
||||
root to: "articles#index"
|
||||
end
|
||||
|
|
|
@ -12,12 +12,10 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2019_01_16_013956) do
|
||||
|
||||
create_table 'articles', force: :cascade do |t|
|
||||
t.string 'title'
|
||||
t.datetime 'created_at', null: false
|
||||
t.datetime 'updated_at', null: false
|
||||
ActiveRecord::Schema.define(version: 20_190_116_013_956) do
|
||||
create_table "articles", force: :cascade do |t|
|
||||
t.string "title"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view'
|
||||
require "dry/view"
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/configurable'
|
||||
require 'dry/core/cache'
|
||||
require 'dry/equalizer'
|
||||
require 'dry/inflector'
|
||||
require "dry/configurable"
|
||||
require "dry/core/cache"
|
||||
require "dry/equalizer"
|
||||
require "dry/inflector"
|
||||
|
||||
require_relative 'view/context'
|
||||
require_relative 'view/exposures'
|
||||
require_relative 'view/errors'
|
||||
require_relative 'view/part_builder'
|
||||
require_relative 'view/path'
|
||||
require_relative 'view/render_environment'
|
||||
require_relative 'view/rendered'
|
||||
require_relative 'view/renderer'
|
||||
require_relative 'view/scope_builder'
|
||||
require_relative "view/context"
|
||||
require_relative "view/exposures"
|
||||
require_relative "view/errors"
|
||||
require_relative "view/part_builder"
|
||||
require_relative "view/path"
|
||||
require_relative "view/render_environment"
|
||||
require_relative "view/rendered"
|
||||
require_relative "view/renderer"
|
||||
require_relative "view/scope_builder"
|
||||
|
||||
# A collection of next-generation Ruby libraries, helping you to write clear,
|
||||
# flexible, and more maintainable Ruby code. Each dry-rb gem fulfils a common
|
||||
|
@ -35,7 +35,7 @@ module Dry
|
|||
# @api public
|
||||
class View
|
||||
# @api private
|
||||
DEFAULT_RENDERER_OPTIONS = { default_encoding: 'utf-8' }.freeze
|
||||
DEFAULT_RENDERER_OPTIONS = {default_encoding: "utf-8"}.freeze
|
||||
|
||||
include Dry::Equalizer(:config, :exposures)
|
||||
|
||||
|
@ -92,7 +92,7 @@ module Dry
|
|||
# @param dir [String] directory name
|
||||
# @api public
|
||||
# @!scope class
|
||||
setting :layouts_dir, 'layouts'
|
||||
setting :layouts_dir, "layouts"
|
||||
|
||||
# @overload config.scope=(scope_class)
|
||||
# Set the scope class to use when rendering the view's template.
|
||||
|
@ -230,8 +230,10 @@ module Dry
|
|||
# @!macro [new] exposure_options
|
||||
# @param options [Hash] the exposure's options
|
||||
# @option options [Boolean] :layout expose this value to the layout (defaults to false)
|
||||
# @option options [Boolean] :decorate decorate this value in a matching Part (defaults to true)
|
||||
# @option options [Symbol, Class] :as an alternative name or class to use when finding a matching Part
|
||||
# @option options [Boolean] :decorate decorate this value in a matching Part (defaults to
|
||||
# true)
|
||||
# @option options [Symbol, Class] :as an alternative name or class to use when finding a
|
||||
# matching Part
|
||||
|
||||
# @overload expose(name, **options, &block)
|
||||
# Define a value to be passed to the template. The return value of the
|
||||
|
@ -315,7 +317,8 @@ module Dry
|
|||
#
|
||||
# @param name [Symbol] name for the exposure
|
||||
# @macro exposure_options
|
||||
# @option options [Boolean] :default a default value to provide if there is no matching input data
|
||||
# @option options [Boolean] :default a default value to provide if there is no matching
|
||||
# input data
|
||||
#
|
||||
# @overload expose(*names, **options)
|
||||
# Define multiple values to pass through from the input data (when there
|
||||
|
@ -326,7 +329,8 @@ module Dry
|
|||
#
|
||||
# @param names [Symbol] names for the exposures
|
||||
# @macro exposure_options
|
||||
# @option options [Boolean] :default a default value to provide if there is no matching input data
|
||||
# @option options [Boolean] :default a default value to provide if there is no matching
|
||||
# input data
|
||||
#
|
||||
# @see https://dry-rb.org/gems/dry-view/exposures/
|
||||
#
|
||||
|
@ -411,7 +415,7 @@ module Dry
|
|||
config.paths,
|
||||
format: format,
|
||||
engine_mapping: config.renderer_engine_mapping,
|
||||
**config.renderer_options,
|
||||
**config.renderer_options
|
||||
)
|
||||
}
|
||||
end
|
||||
|
@ -467,7 +471,10 @@ module Dry
|
|||
|
||||
if layout?
|
||||
layout_env = self.class.layout_env(format: format, context: context)
|
||||
output = env.template(self.class.layout_path, layout_env.scope(config.scope, layout_locals(locals))) { output }
|
||||
output = env.template(
|
||||
self.class.layout_path,
|
||||
layout_env.scope(config.scope, layout_locals(locals))
|
||||
) { output }
|
||||
end
|
||||
|
||||
Rendered.new(output: output, locals: locals)
|
||||
|
@ -477,8 +484,8 @@ module Dry
|
|||
|
||||
# @api private
|
||||
def ensure_config
|
||||
raise UndefinedConfigError.new(:paths) unless Array(config.paths).any?
|
||||
raise UndefinedConfigError.new(:template) unless config.template
|
||||
raise UndefinedConfigError, :paths unless Array(config.paths).any?
|
||||
raise UndefinedConfigError, :template unless config.template
|
||||
end
|
||||
|
||||
# @api private
|
||||
|
@ -501,7 +508,7 @@ module Dry
|
|||
|
||||
# @api private
|
||||
def layout?
|
||||
!!config.layout
|
||||
!!config.layout # rubocop:disable Style/DoubleNegation
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/equalizer'
|
||||
require_relative 'decorated_attributes'
|
||||
require "dry/equalizer"
|
||||
require_relative "decorated_attributes"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
@ -43,7 +43,7 @@ module Dry
|
|||
|
||||
# @api private
|
||||
def for_render_env(render_env)
|
||||
return self if render_env == self._render_env
|
||||
return self if render_env == _render_env
|
||||
|
||||
self.class.new(**_options.merge(render_env: render_env))
|
||||
end
|
||||
|
@ -72,7 +72,7 @@ module Dry
|
|||
def with(**new_options)
|
||||
self.class.new(
|
||||
render_env: _render_env,
|
||||
**_options.merge(new_options),
|
||||
**_options.merge(new_options)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'set'
|
||||
require "set"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
@ -27,7 +27,8 @@ module Dry
|
|||
#
|
||||
# @param names [Array<Symbol>] the attribute names
|
||||
# @param options [Hash] the options to pass to the Part Builder
|
||||
# @option options [Symbol, Class] :as an alternative name or class to use when finding a matching Part
|
||||
# @option options [Symbol, Class] :as an alternative name or class to use when finding a
|
||||
# matching Part
|
||||
#
|
||||
# @api public
|
||||
def decorate(*names, **options)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry-equalizer'
|
||||
require "dry-equalizer"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
@ -10,8 +10,8 @@ module Dry
|
|||
class Exposure
|
||||
include Dry::Equalizer(:name, :proc, :object, :options)
|
||||
|
||||
EXPOSURE_DEPENDENCY_PARAMETER_TYPES = [:req, :opt].freeze
|
||||
INPUT_PARAMETER_TYPES = [:key, :keyreq, :keyrest].freeze
|
||||
EXPOSURE_DEPENDENCY_PARAMETER_TYPES = %i[req opt].freeze
|
||||
INPUT_PARAMETER_TYPES = %i[key keyreq keyrest].freeze
|
||||
|
||||
attr_reader :name
|
||||
attr_reader :proc
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'tsort'
|
||||
require 'dry/equalizer'
|
||||
require 'dry/view/exposure'
|
||||
require "tsort"
|
||||
require "dry/equalizer"
|
||||
require "dry/view/exposure"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
@ -46,8 +46,9 @@ module Dry
|
|||
end
|
||||
|
||||
def call(input)
|
||||
# rubocop:disable Style/MultilineBlockChain
|
||||
tsort.each_with_object({}) { |name, memo|
|
||||
next unless exposure = self[name]
|
||||
next unless (exposure = self[name])
|
||||
|
||||
value = exposure.(input, memo)
|
||||
value = yield(value, exposure) if block_given?
|
||||
|
@ -56,6 +57,7 @@ module Dry
|
|||
}.each_with_object({}) { |(name, value), memo|
|
||||
memo[name] = value unless self[name].private?
|
||||
}
|
||||
# rubocop:enable Style/MultilineBlockChain
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/equalizer'
|
||||
require_relative 'decorated_attributes'
|
||||
require_relative 'render_environment_missing'
|
||||
require "dry/equalizer"
|
||||
require_relative "decorated_attributes"
|
||||
require_relative "render_environment_missing"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
@ -60,7 +60,7 @@ module Dry
|
|||
#
|
||||
# @api private
|
||||
def self.part_name(inflector)
|
||||
name ? inflector.underscore(inflector.demodulize(name)) : 'part'
|
||||
name ? inflector.underscore(inflector.demodulize(name)) : "part"
|
||||
end
|
||||
|
||||
# Returns a new Part instance
|
||||
|
@ -70,7 +70,11 @@ module Dry
|
|||
# @param render_env [RenderEnvironment] render environment
|
||||
#
|
||||
# @api public
|
||||
def initialize(render_env: RenderEnvironmentMissing.new, name: self.class.part_name(render_env.inflector), value:)
|
||||
def initialize(
|
||||
render_env: RenderEnvironmentMissing.new,
|
||||
name: self.class.part_name(render_env.inflector),
|
||||
value:
|
||||
)
|
||||
@_name = name
|
||||
@_value = value
|
||||
@_render_env = render_env
|
||||
|
@ -115,15 +119,18 @@ module Dry
|
|||
# itself responds to `#render`.
|
||||
#
|
||||
# @param partial_name [Symbol, String] partial name
|
||||
# @param as [Symbol] the name for the Part to assume in the partial's locals. Default's to the Part's `_name`.
|
||||
# @param as [Symbol] the name for the Part to assume in the partial's locals. Defaults to
|
||||
# the Part's `_name`.
|
||||
# @param locals [Hash<Symbol, Object>] other locals to provide the partial
|
||||
#
|
||||
# @return [String] rendered partial
|
||||
#
|
||||
# @api public
|
||||
# rubocop:disable Naming/UncommunicativeMethodParamName
|
||||
def _render(partial_name, as: _name, **locals, &block)
|
||||
_render_env.partial(partial_name, _render_env.scope({ as => self }.merge(locals)), &block)
|
||||
_render_env.partial(partial_name, _render_env.scope({as => self}.merge(locals)), &block)
|
||||
end
|
||||
# rubocop:enable Naming/UncommunicativeMethodParamName
|
||||
|
||||
# Builds a new scope with the part included in its locals.
|
||||
#
|
||||
|
@ -133,14 +140,15 @@ module Dry
|
|||
# A convenience alias for `#_scope`. Is available unless the value
|
||||
# itself responds to `#scope`.
|
||||
#
|
||||
# @param scope_name [Symbol, nil] scope name, used by the scope builder to determine the scope class
|
||||
# @param scope_name [Symbol, nil] scope name, used by the scope builder to determine the
|
||||
# scope class
|
||||
# @param locals [Hash<Symbol, Object>] other locals to provide the partial
|
||||
#
|
||||
# @return [Dry::View::Scope] scope
|
||||
#
|
||||
# @api public
|
||||
def _scope(scope_name = nil, **locals)
|
||||
_render_env.scope(scope_name, { _name => self }.merge(locals))
|
||||
_render_env.scope(scope_name, {_name => self}.merge(locals))
|
||||
end
|
||||
|
||||
# Returns a string representation of the value
|
||||
|
@ -168,12 +176,12 @@ module Dry
|
|||
# @param options[Hash<Symbol, Object>] other options to provide when initializing the new part
|
||||
#
|
||||
# @api public
|
||||
def new(klass = (self.class), name: (_name), value: (_value), **options)
|
||||
def new(klass = self.class, name: _name, value: _value, **options)
|
||||
klass.new(
|
||||
name: name,
|
||||
value: value,
|
||||
render_env: _render_env,
|
||||
**options,
|
||||
**options
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/core/cache'
|
||||
require 'dry/equalizer'
|
||||
require_relative 'part'
|
||||
require "dry/core/cache"
|
||||
require "dry/equalizer"
|
||||
require_relative "part"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
@ -54,7 +54,7 @@ module Dry
|
|||
klass.new(
|
||||
name: name,
|
||||
value: value,
|
||||
render_env: render_env,
|
||||
render_env: render_env
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -69,11 +69,13 @@ module Dry
|
|||
build_part(name, arr, **options.merge(as: collection_as))
|
||||
end
|
||||
|
||||
# rubocop:disable Lint/UnusedMethodArgument
|
||||
def collection_options(name:, **options)
|
||||
collection_as = options[:as].is_a?(Array) ? options[:as].first : nil
|
||||
|
||||
options.merge(as: collection_as)
|
||||
end
|
||||
# rubocop:enable Lint/UnusedMethodArgument
|
||||
|
||||
def collection_item_options(name:, **options)
|
||||
singular_name = inflector.singularize(name).to_sym
|
||||
|
@ -90,7 +92,7 @@ module Dry
|
|||
|
||||
options.merge(
|
||||
name: singular_name,
|
||||
as: singular_as,
|
||||
as: singular_as
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -106,6 +108,7 @@ module Dry
|
|||
end
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/PerceivedComplexity
|
||||
def resolve_part_class(name:, fallback_class:)
|
||||
return fallback_class unless namespace
|
||||
|
||||
|
@ -114,7 +117,7 @@ module Dry
|
|||
# Give autoloaders a chance to act
|
||||
begin
|
||||
klass = namespace.const_get(name)
|
||||
rescue NameError
|
||||
rescue NameError # rubocop:disable Lint/HandleExceptions
|
||||
end
|
||||
|
||||
if !klass && namespace.const_defined?(name, false)
|
||||
|
@ -127,6 +130,7 @@ module Dry
|
|||
fallback_class
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/PerceivedComplexity
|
||||
|
||||
def inflector
|
||||
render_env.inflector
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'pathname'
|
||||
require 'dry/core/cache'
|
||||
require "pathname"
|
||||
require "dry/core/cache"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
@ -61,7 +61,7 @@ module Dry
|
|||
end
|
||||
|
||||
def lookup_in_parent_dir(name, format, child_dirs:)
|
||||
!root? && chdir('..').lookup(name, format, child_dirs: child_dirs, parent_dir: true)
|
||||
!root? && chdir("..").lookup(name, format, child_dirs: child_dirs, parent_dir: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/equalizer'
|
||||
require "dry/equalizer"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
@ -12,7 +12,7 @@ module Dry
|
|||
inflector: config.inflector,
|
||||
context: context,
|
||||
scope_builder: config.scope_builder.new(namespace: config.scope_namespace),
|
||||
part_builder: config.part_builder.new(namespace: config.part_namespace),
|
||||
part_builder: config.part_builder.new(namespace: config.part_namespace)
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -36,7 +36,7 @@ module Dry
|
|||
part_builder.(name, value, **options)
|
||||
end
|
||||
|
||||
def scope(name = nil, locals)
|
||||
def scope(name = nil, locals) # rubocop:disable Style/OptionalArguments
|
||||
scope_builder.(name, locals)
|
||||
end
|
||||
|
||||
|
@ -54,7 +54,7 @@ module Dry
|
|||
inflector: inflector,
|
||||
context: context,
|
||||
scope_builder: scope_builder,
|
||||
part_builder: part_builder,
|
||||
part_builder: part_builder
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/inflector'
|
||||
require "dry/inflector"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
@ -8,7 +8,7 @@ module Dry
|
|||
class RenderEnvironmentMissing
|
||||
class MissingEnvironmentError < StandardError
|
||||
def message
|
||||
'a +render_env+ must be provided'
|
||||
"a +render_env+ must be provided"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -20,19 +20,19 @@ module Dry
|
|||
raise MissingEnvironmentError
|
||||
end
|
||||
|
||||
def part(name, value, **options)
|
||||
def part(_name, _value, **_options)
|
||||
raise MissingEnvironmentError
|
||||
end
|
||||
|
||||
def scope(name = nil, locals)
|
||||
def scope(_name = nil, _locals) # rubocop:disable Style/OptionalArguments
|
||||
raise MissingEnvironmentError
|
||||
end
|
||||
|
||||
def template(name, scope, &block)
|
||||
def template(_name, _scope)
|
||||
raise MissingEnvironmentError
|
||||
end
|
||||
|
||||
def partial(name, scope, &block)
|
||||
def partial(_name, _scope)
|
||||
raise MissingEnvironmentError
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/equalizer'
|
||||
require "dry/equalizer"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/core/cache'
|
||||
require 'dry/equalizer'
|
||||
require_relative 'errors'
|
||||
require_relative 'tilt'
|
||||
require "dry/core/cache"
|
||||
require "dry/equalizer"
|
||||
require_relative "errors"
|
||||
require_relative "tilt"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
# @api private
|
||||
class Renderer
|
||||
PARTIAL_PREFIX = '_'
|
||||
PATH_DELIMITER = '/'
|
||||
PARTIAL_PREFIX = "_"
|
||||
PATH_DELIMITER = "/"
|
||||
|
||||
extend Dry::Core::Cache
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/equalizer'
|
||||
require 'dry/core/constants'
|
||||
require_relative 'render_environment_missing'
|
||||
require "dry/equalizer"
|
||||
require "dry/core/constants"
|
||||
require_relative "render_environment_missing"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
@ -59,7 +59,11 @@ module Dry
|
|||
# @return [Scope]
|
||||
#
|
||||
# @api public
|
||||
def initialize(name: nil, locals: Dry::Core::Constants::EMPTY_HASH, render_env: RenderEnvironmentMissing.new)
|
||||
def initialize(
|
||||
name: nil,
|
||||
locals: Dry::Core::Constants::EMPTY_HASH,
|
||||
render_env: RenderEnvironmentMissing.new
|
||||
)
|
||||
@_name = name
|
||||
@_locals = locals
|
||||
@_render_env = render_env
|
||||
|
@ -83,9 +87,14 @@ module Dry
|
|||
# @api public
|
||||
def render(partial_name = nil, **locals, &block)
|
||||
partial_name ||= _name
|
||||
raise ArgumentError, '+partial_name+ must be provided for unnamed scopes' unless partial_name
|
||||
|
||||
partial_name = _inflector.underscore(_inflector.demodulize(partial_name.to_s)) if partial_name.is_a?(Class)
|
||||
unless partial_name
|
||||
raise ArgumentError, "+partial_name+ must be provided for unnamed scopes"
|
||||
end
|
||||
|
||||
if partial_name.is_a?(Class)
|
||||
partial_name = _inflector.underscore(_inflector.demodulize(partial_name.to_s))
|
||||
end
|
||||
|
||||
_render_env.partial(partial_name, _render_scope(locals), &block)
|
||||
end
|
||||
|
@ -153,7 +162,10 @@ module Dry
|
|||
end
|
||||
|
||||
def respond_to_missing?(name, include_private = false)
|
||||
_locals.key?(name) || _render_env.context.respond_to?(name) || CONVENIENCE_METHODS.include?(name) || super
|
||||
_locals.key?(name) ||
|
||||
_render_env.context.respond_to?(name) ||
|
||||
CONVENIENCE_METHODS.include?(name) ||
|
||||
super
|
||||
end
|
||||
|
||||
def _render_scope(**locals)
|
||||
|
@ -163,7 +175,7 @@ module Dry
|
|||
self.class.new(
|
||||
# FIXME: what about `name`?
|
||||
locals: locals,
|
||||
render_env: _render_env,
|
||||
render_env: _render_env
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/core/cache'
|
||||
require 'dry/equalizer'
|
||||
require_relative 'scope'
|
||||
require "dry/core/cache"
|
||||
require "dry/equalizer"
|
||||
require_relative "scope"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
@ -46,11 +46,11 @@ module Dry
|
|||
# @return [Dry::View::Scope]
|
||||
#
|
||||
# @api private
|
||||
def call(name = nil, locals)
|
||||
def call(name = nil, locals) # rubocop:disable Style/OptionalArguments
|
||||
scope_class(name).new(
|
||||
name: name,
|
||||
locals: locals,
|
||||
render_env: render_env,
|
||||
render_env: render_env
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -76,7 +76,7 @@ module Dry
|
|||
# Give autoloaders a chance to act
|
||||
begin
|
||||
klass = namespace.const_get(name)
|
||||
rescue NameError
|
||||
rescue NameError # rubocop:disable Lint/HandleExceptions
|
||||
end
|
||||
|
||||
if !klass && namespace.const_defined?(name, false)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/core/cache'
|
||||
require 'tilt'
|
||||
require "dry/core/cache"
|
||||
require "tilt"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
@ -11,7 +11,7 @@ module Dry
|
|||
|
||||
class << self
|
||||
def [](path, mapping, **options)
|
||||
ext = File.extname(path).sub(%r{^.}, '').to_sym
|
||||
ext = File.extname(path).sub(/^./, "").to_sym
|
||||
activate_adapter ext
|
||||
|
||||
with_mapping(mapping).new(path, **options)
|
||||
|
@ -74,5 +74,5 @@ module Dry
|
|||
end
|
||||
end
|
||||
|
||||
require_relative 'tilt/erb'
|
||||
require_relative 'tilt/haml'
|
||||
require_relative "tilt/erb"
|
||||
require_relative "tilt/haml"
|
||||
|
|
|
@ -5,7 +5,7 @@ module Dry
|
|||
module Tilt
|
||||
module ERB
|
||||
def self.requirements
|
||||
['dry/view/tilt/erbse', <<~ERROR]
|
||||
["dry/view/tilt/erbse", <<~ERROR]
|
||||
dry-view requires erbse for full compatibility when rendering .erb templates (e.g. implicitly capturing block content when yielding)
|
||||
|
||||
To ignore this and use another engine for .erb templates, deregister this adapter before calling your views:
|
||||
|
@ -15,7 +15,7 @@ module Dry
|
|||
end
|
||||
|
||||
def self.activate
|
||||
Tilt.default_mapping.register ErbseTemplate, 'erb'
|
||||
Tilt.default_mapping.register ErbseTemplate, "erb"
|
||||
self
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'tilt/template'
|
||||
require 'erbse'
|
||||
require "tilt/template"
|
||||
require "erbse"
|
||||
|
||||
module Dry
|
||||
class View
|
||||
|
@ -12,7 +12,7 @@ module Dry
|
|||
@template = ::Erbse::Engine.new
|
||||
end
|
||||
|
||||
def precompiled_template(locals)
|
||||
def precompiled_template(_locals)
|
||||
@template.call(data)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ module Dry
|
|||
module Tilt
|
||||
module Haml
|
||||
def self.requirements
|
||||
['hamlit/block', <<~ERROR]
|
||||
["hamlit/block", <<~ERROR]
|
||||
dry-view requires hamlit-block for full compatibility when rendering .haml templates (e.g. implicitly capturing block content when yielding)
|
||||
|
||||
To ignore this and use another engine for .haml templates, dereigster this adapter before calling your views:
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
module Dry
|
||||
class View
|
||||
# @api private
|
||||
VERSION = '0.7.0'
|
||||
VERSION = "0.7.0"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view'
|
||||
require 'dry/view/context'
|
||||
require 'dry/view/part'
|
||||
require "dry/view"
|
||||
require "dry/view/context"
|
||||
require "dry/view/part"
|
||||
|
||||
RSpec.describe 'Context' do
|
||||
it 'Provides decorated attributes for use in templates and parts' do
|
||||
RSpec.describe "Context" do
|
||||
it "Provides decorated attributes for use in templates and parts" do
|
||||
module Test
|
||||
class Assets
|
||||
def [](path)
|
||||
|
@ -34,15 +34,15 @@ RSpec.describe 'Context' do
|
|||
|
||||
class User < Dry::View::Part
|
||||
def image_tag
|
||||
value[:image_url] || context.assets.image_tag('default.png')
|
||||
value[:image_url] || context.assets.image_tag("default.png")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = FIXTURES_PATH.join('integration/context')
|
||||
config.template = 'decorated_attributes'
|
||||
config.paths = FIXTURES_PATH.join("integration/context")
|
||||
config.template = "decorated_attributes"
|
||||
config.part_namespace = Test::Parts
|
||||
|
||||
expose :user
|
||||
|
@ -51,11 +51,11 @@ RSpec.describe 'Context' do
|
|||
context = Test::Context.new(assets: Test::Assets.new)
|
||||
|
||||
output = view.(
|
||||
user: { image_url: nil },
|
||||
context: context,
|
||||
user: {image_url: nil},
|
||||
context: context
|
||||
).to_s
|
||||
|
||||
expect(output.gsub("\n", '')).to eq <<~HTML.gsub("\n", '')
|
||||
expect(output.gsub("\n", "")).to eq <<~HTML.gsub("\n", "")
|
||||
<img src="hashed/path/to/hello.png">
|
||||
<div class="user">
|
||||
<img src="hashed/path/to/default.png">
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view'
|
||||
require 'dry/view/context'
|
||||
require 'dry/view/part'
|
||||
require "dry/view"
|
||||
require "dry/view/context"
|
||||
require "dry/view/part"
|
||||
|
||||
RSpec.describe 'exposures' do
|
||||
RSpec.describe "exposures" do
|
||||
let(:context) {
|
||||
Class.new(Dry::View::Context) do
|
||||
def title
|
||||
'dry-view rocks!'
|
||||
"dry-view rocks!"
|
||||
end
|
||||
|
||||
def assets
|
||||
|
@ -17,11 +17,11 @@ RSpec.describe 'exposures' do
|
|||
end.new
|
||||
}
|
||||
|
||||
it 'uses exposures with blocks to build view locals' do
|
||||
it "uses exposures with blocks to build view locals" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'users'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "users"
|
||||
config.default_format = :html
|
||||
|
||||
expose :users do |users:|
|
||||
|
@ -32,8 +32,8 @@ RSpec.describe 'exposures' do
|
|||
end.new
|
||||
|
||||
users = [
|
||||
{ name: 'Jane', email: 'jane@doe.org' },
|
||||
{ name: 'Joe', email: 'joe@doe.org' }
|
||||
{name: "Jane", email: "jane@doe.org"},
|
||||
{name: "Joe", email: "joe@doe.org"}
|
||||
]
|
||||
|
||||
expect(view.(users: users, context: context).to_s).to eql(
|
||||
|
@ -41,18 +41,18 @@ RSpec.describe 'exposures' do
|
|||
)
|
||||
end
|
||||
|
||||
it 'gives the exposure blocks access to the view instance' do
|
||||
it "gives the exposure blocks access to the view instance" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'users'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "users"
|
||||
config.default_format = :html
|
||||
|
||||
attr_reader :prefix
|
||||
|
||||
def initialize
|
||||
super
|
||||
@prefix = 'My friend '
|
||||
@prefix = "My friend "
|
||||
end
|
||||
|
||||
expose :users do |users:|
|
||||
|
@ -63,8 +63,8 @@ RSpec.describe 'exposures' do
|
|||
end.new
|
||||
|
||||
users = [
|
||||
{ name: 'Jane', email: 'jane@doe.org' },
|
||||
{ name: 'Joe', email: 'joe@doe.org' }
|
||||
{name: "Jane", email: "jane@doe.org"},
|
||||
{name: "Joe", email: "joe@doe.org"}
|
||||
]
|
||||
|
||||
expect(view.(users: users, context: context).to_s).to eql(
|
||||
|
@ -72,11 +72,11 @@ RSpec.describe 'exposures' do
|
|||
)
|
||||
end
|
||||
|
||||
it 'supports instance methods as exposures' do
|
||||
it "supports instance methods as exposures" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'users'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "users"
|
||||
config.default_format = :html
|
||||
|
||||
expose :users
|
||||
|
@ -91,8 +91,8 @@ RSpec.describe 'exposures' do
|
|||
end.new
|
||||
|
||||
users = [
|
||||
{ name: 'Jane', email: 'jane@doe.org' },
|
||||
{ name: 'Joe', email: 'joe@doe.org' }
|
||||
{name: "Jane", email: "jane@doe.org"},
|
||||
{name: "Joe", email: "joe@doe.org"}
|
||||
]
|
||||
|
||||
expect(view.(users: users, context: context).to_s).to eql(
|
||||
|
@ -100,19 +100,19 @@ RSpec.describe 'exposures' do
|
|||
)
|
||||
end
|
||||
|
||||
it 'passes matching input data if no proc or instance method is available' do
|
||||
it "passes matching input data if no proc or instance method is available" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'users'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "users"
|
||||
config.default_format = :html
|
||||
|
||||
expose :users
|
||||
end.new
|
||||
|
||||
users = [
|
||||
{ name: 'Jane', email: 'jane@doe.org' },
|
||||
{ name: 'Joe', email: 'joe@doe.org' }
|
||||
{name: "Jane", email: "jane@doe.org"},
|
||||
{name: "Joe", email: "joe@doe.org"}
|
||||
]
|
||||
|
||||
expect(view.(users: users, context: context).to_s).to eql(
|
||||
|
@ -120,14 +120,14 @@ RSpec.describe 'exposures' do
|
|||
)
|
||||
end
|
||||
|
||||
it 'using default values' do
|
||||
it "using default values" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'users'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "users"
|
||||
config.default_format = :html
|
||||
|
||||
expose :users, default: [{ name: 'John', email: 'john@william.org' }]
|
||||
expose :users, default: [{name: "John", email: "john@william.org"}]
|
||||
end.new
|
||||
|
||||
expect(view.(context: context).to_s).to eql(
|
||||
|
@ -135,26 +135,26 @@ RSpec.describe 'exposures' do
|
|||
)
|
||||
end
|
||||
|
||||
it 'having default values but passing nil as value for exposure' do
|
||||
it "having default values but passing nil as value for exposure" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'greeting'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "greeting"
|
||||
config.default_format = :html
|
||||
|
||||
expose :greeting, default: 'Hello Dry-rb'
|
||||
expose :greeting, default: "Hello Dry-rb"
|
||||
end.new
|
||||
|
||||
expect(view.(greeting: nil, context: context).to_s).to eql(
|
||||
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><p></p></body></html>'
|
||||
"<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><p></p></body></html>"
|
||||
)
|
||||
end
|
||||
|
||||
it 'allows exposures to depend on each other' do
|
||||
it "allows exposures to depend on each other" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'users_with_count'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "users_with_count"
|
||||
config.default_format = :html
|
||||
|
||||
expose :users
|
||||
|
@ -165,8 +165,8 @@ RSpec.describe 'exposures' do
|
|||
end.new
|
||||
|
||||
users = [
|
||||
{ name: 'Jane', email: 'jane@doe.org' },
|
||||
{ name: 'Joe', email: 'joe@doe.org' }
|
||||
{name: "Jane", email: "jane@doe.org"},
|
||||
{name: "Joe", email: "joe@doe.org"}
|
||||
]
|
||||
|
||||
expect(view.(users: users, context: context).to_s).to eql(
|
||||
|
@ -174,7 +174,7 @@ RSpec.describe 'exposures' do
|
|||
)
|
||||
end
|
||||
|
||||
it 'wraps exposures in view parts before they are supplied as dependencies' do
|
||||
it "wraps exposures in view parts before they are supplied as dependencies" do
|
||||
module Test
|
||||
class UserPart < Dry::View::Part
|
||||
def display_name
|
||||
|
@ -184,9 +184,9 @@ RSpec.describe 'exposures' do
|
|||
end
|
||||
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'users_with_count'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "users_with_count"
|
||||
config.default_format = :html
|
||||
|
||||
expose :users, as: Test::UserPart
|
||||
|
@ -201,8 +201,8 @@ RSpec.describe 'exposures' do
|
|||
end.new
|
||||
|
||||
users = [
|
||||
{ name: 'Jane', email: 'jane@doe.org' },
|
||||
{ name: 'Joe', email: 'joe@doe.org' }
|
||||
{name: "Jane", email: "jane@doe.org"},
|
||||
{name: "Joe", email: "joe@doe.org"}
|
||||
]
|
||||
|
||||
rendered = view.(users: users, context: context)
|
||||
|
@ -210,17 +210,17 @@ RSpec.describe 'exposures' do
|
|||
expect(rendered[:users]).to be_a(Dry::View::Part)
|
||||
|
||||
expect(rendered[:users][0]).to be_a(Test::UserPart)
|
||||
expect(rendered[:users][0].value).to eq(name: 'Jane', email: 'jane@doe.org')
|
||||
expect(rendered[:users][0].value).to eq(name: "Jane", email: "jane@doe.org")
|
||||
|
||||
expect(rendered[:article]).to be_a(Dry::View::Part)
|
||||
expect(rendered[:article].to_s).to eq 'Great article from User: Jane'
|
||||
expect(rendered[:article].to_s).to eq "Great article from User: Jane"
|
||||
end
|
||||
|
||||
it 'allows exposures to depend on each other while still using keywords args to access input data' do
|
||||
it "allows exposures to depend on each other while still using keywords args to access input data" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'greeting'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "greeting"
|
||||
config.default_format = :html
|
||||
|
||||
expose :greeting do |prefix, greeting:|
|
||||
|
@ -228,41 +228,41 @@ RSpec.describe 'exposures' do
|
|||
end
|
||||
|
||||
expose :prefix do
|
||||
'Hello'
|
||||
"Hello"
|
||||
end
|
||||
end.new
|
||||
|
||||
expect(view.(greeting: 'From dry-view internals', context: context).to_s).to eql(
|
||||
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><p>Hello From dry-view internals</p></body></html>'
|
||||
expect(view.(greeting: "From dry-view internals", context: context).to_s).to eql(
|
||||
"<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><p>Hello From dry-view internals</p></body></html>"
|
||||
)
|
||||
end
|
||||
|
||||
it 'supports default values for keyword arguments' do
|
||||
it "supports default values for keyword arguments" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'greeting'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "greeting"
|
||||
config.default_format = :html
|
||||
|
||||
expose :greeting do |prefix, greeting: 'From the defaults'|
|
||||
expose :greeting do |prefix, greeting: "From the defaults"|
|
||||
"#{prefix} #{greeting}"
|
||||
end
|
||||
|
||||
expose :prefix do
|
||||
'Hello'
|
||||
"Hello"
|
||||
end
|
||||
end.new
|
||||
|
||||
expect(view.(context: context).to_s).to eql(
|
||||
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><p>Hello From the defaults</p></body></html>'
|
||||
"<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><p>Hello From the defaults</p></body></html>"
|
||||
)
|
||||
end
|
||||
|
||||
it 'only passes keywords arguments that are needed in the block and allows for default values' do
|
||||
it "only passes keywords arguments that are needed in the block and allows for default values" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'edit'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "edit"
|
||||
config.default_format = :html
|
||||
|
||||
expose :pretty_id do |id:|
|
||||
|
@ -275,15 +275,15 @@ RSpec.describe 'exposures' do
|
|||
end.new
|
||||
|
||||
expect(view.(id: 1, context: context).to_s).to eql(
|
||||
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><h1>Edit</h1><p>No Errors</p><p>Beautiful 1</p></body></html>'
|
||||
"<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><h1>Edit</h1><p>No Errors</p><p>Beautiful 1</p></body></html>"
|
||||
)
|
||||
end
|
||||
|
||||
it 'supports defining multiple exposures at once' do
|
||||
it "supports defining multiple exposures at once" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'users_with_count'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "users_with_count"
|
||||
config.default_format = :html
|
||||
|
||||
expose :users, :users_count
|
||||
|
@ -296,8 +296,8 @@ RSpec.describe 'exposures' do
|
|||
end.new
|
||||
|
||||
users = [
|
||||
{ name: 'Jane', email: 'jane@doe.org' },
|
||||
{ name: 'Joe', email: 'joe@doe.org' }
|
||||
{name: "Jane", email: "jane@doe.org"},
|
||||
{name: "Joe", email: "joe@doe.org"}
|
||||
]
|
||||
|
||||
expect(view.(users: users, context: context).to_s).to eql(
|
||||
|
@ -305,15 +305,15 @@ RSpec.describe 'exposures' do
|
|||
)
|
||||
end
|
||||
|
||||
it 'allows exposures to be hidden from the view' do
|
||||
it "allows exposures to be hidden from the view" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'users_with_count'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "users_with_count"
|
||||
config.default_format = :html
|
||||
|
||||
private_expose :prefix do
|
||||
'COUNT: '
|
||||
"COUNT: "
|
||||
end
|
||||
|
||||
expose :users
|
||||
|
@ -324,11 +324,11 @@ RSpec.describe 'exposures' do
|
|||
end.new
|
||||
|
||||
users = [
|
||||
{ name: 'Jane', email: 'jane@doe.org' },
|
||||
{ name: 'Joe', email: 'joe@doe.org' }
|
||||
{name: "Jane", email: "jane@doe.org"},
|
||||
{name: "Joe", email: "joe@doe.org"}
|
||||
]
|
||||
|
||||
input = { users: users, context: context }
|
||||
input = {users: users, context: context}
|
||||
|
||||
expect(view.(input).to_s).to eql(
|
||||
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><ul><li>Jane (jane@doe.org)</li><li>Joe (joe@doe.org)</li></ul><div class="count">COUNT: 2 users</div></body></html>'
|
||||
|
@ -338,15 +338,15 @@ RSpec.describe 'exposures' do
|
|||
expect(view.(input).locals).not_to include(:prefix)
|
||||
end
|
||||
|
||||
it 'inherit exposures from parent class' do
|
||||
it "inherit exposures from parent class" do
|
||||
parent = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'users_with_count_inherit'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "users_with_count_inherit"
|
||||
config.default_format = :html
|
||||
|
||||
private_expose :prefix do
|
||||
'COUNT: '
|
||||
"COUNT: "
|
||||
end
|
||||
|
||||
expose :users
|
||||
|
@ -358,16 +358,16 @@ RSpec.describe 'exposures' do
|
|||
|
||||
child = Class.new(parent) do
|
||||
expose :child_expose do
|
||||
'Child expose'
|
||||
"Child expose"
|
||||
end
|
||||
end.new
|
||||
|
||||
users = [
|
||||
{ name: 'Jane', email: 'jane@doe.org' },
|
||||
{ name: 'Joe', email: 'joe@doe.org' }
|
||||
{name: "Jane", email: "jane@doe.org"},
|
||||
{name: "Joe", email: "joe@doe.org"}
|
||||
]
|
||||
|
||||
input = { users: users, context: context }
|
||||
input = {users: users, context: context}
|
||||
|
||||
expect(child.(input).to_s).to eql(
|
||||
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><ul><li>Jane (jane@doe.org)</li><li>Joe (joe@doe.org)</li></ul><div class="count">COUNT: 2 users</div><div class="inherit">Child expose</div></body></html>'
|
||||
|
@ -377,15 +377,15 @@ RSpec.describe 'exposures' do
|
|||
expect(child.(input).locals).not_to include(:prefix)
|
||||
end
|
||||
|
||||
it 'inherit exposures from parent class and allow to override them' do
|
||||
it "inherit exposures from parent class and allow to override them" do
|
||||
parent = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'users_with_count_inherit'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "users_with_count_inherit"
|
||||
config.default_format = :html
|
||||
|
||||
private_expose :prefix do
|
||||
'COUNT: '
|
||||
"COUNT: "
|
||||
end
|
||||
|
||||
expose :users
|
||||
|
@ -397,7 +397,7 @@ RSpec.describe 'exposures' do
|
|||
|
||||
child = Class.new(parent) do
|
||||
expose :child_expose do
|
||||
'Child expose'
|
||||
"Child expose"
|
||||
end
|
||||
|
||||
expose :users_count do |prefix, users:|
|
||||
|
@ -406,11 +406,11 @@ RSpec.describe 'exposures' do
|
|||
end.new
|
||||
|
||||
users = [
|
||||
{ name: 'Jane', email: 'jane@doe.org' },
|
||||
{ name: 'Joe', email: 'joe@doe.org' }
|
||||
{name: "Jane", email: "jane@doe.org"},
|
||||
{name: "Joe", email: "joe@doe.org"}
|
||||
]
|
||||
|
||||
input = { users: users, context: context }
|
||||
input = {users: users, context: context}
|
||||
|
||||
expect(child.(input).to_s).to eql(
|
||||
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><ul><li>Jane (jane@doe.org)</li><li>Joe (joe@doe.org)</li></ul><div class="count">COUNT: 2 users overrided</div><div class="inherit">Child expose</div></body></html>'
|
||||
|
@ -420,11 +420,11 @@ RSpec.describe 'exposures' do
|
|||
expect(child.(input).locals).not_to include(:prefix)
|
||||
end
|
||||
|
||||
it 'makes exposures available to layout' do
|
||||
it "makes exposures available to layout" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app_with_users'
|
||||
config.template = 'users'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app_with_users"
|
||||
config.template = "users"
|
||||
config.default_format = :html
|
||||
|
||||
expose :users_count, layout: true
|
||||
|
@ -433,8 +433,8 @@ RSpec.describe 'exposures' do
|
|||
end.new
|
||||
|
||||
users = [
|
||||
{ name: 'Jane', email: 'jane@doe.org' },
|
||||
{ name: 'Joe', email: 'joe@doe.org' }
|
||||
{name: "Jane", email: "jane@doe.org"},
|
||||
{name: "Joe", email: "joe@doe.org"}
|
||||
]
|
||||
|
||||
expect(view.(users: users, users_count: users.size, context: context).to_s).to eql(
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/core/inflector'
|
||||
require 'dry/view/scope_builder'
|
||||
require "dry/core/inflector"
|
||||
require "dry/view/scope_builder"
|
||||
|
||||
RSpec.describe 'Part / Decorated attributes' do
|
||||
RSpec.describe "Part / Decorated attributes" do
|
||||
let(:article_class) {
|
||||
Class.new do
|
||||
attr_reader :title, :author, :comments
|
||||
|
@ -37,16 +37,16 @@ RSpec.describe 'Part / Decorated attributes' do
|
|||
end
|
||||
}
|
||||
|
||||
let (:author) {
|
||||
author_class.new(name: 'Jane Doe')
|
||||
let(:author) {
|
||||
author_class.new(name: "Jane Doe")
|
||||
}
|
||||
|
||||
let(:article) {
|
||||
article_class.new(
|
||||
title: 'Hello world',
|
||||
title: "Hello world",
|
||||
author: author,
|
||||
comments: [
|
||||
comment_class.new(author: author_class.new(name: 'Sue Smith'), body: 'Great article')
|
||||
comment_class.new(author: author_class.new(name: "Sue Smith"), body: "Great article")
|
||||
]
|
||||
)
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ RSpec.describe 'Part / Decorated attributes' do
|
|||
article_part_class.new(
|
||||
name: :article,
|
||||
value: article,
|
||||
render_env: render_env,
|
||||
render_env: render_env
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -65,15 +65,15 @@ RSpec.describe 'Part / Decorated attributes' do
|
|||
inflector: Dry::Inflector.new,
|
||||
context: Dry::View::Context.new,
|
||||
scope_builder: Dry::View::ScopeBuilder.new,
|
||||
part_builder: part_builder,
|
||||
part_builder: part_builder
|
||||
)
|
||||
}
|
||||
|
||||
describe 'using default part builder' do
|
||||
describe "using default part builder" do
|
||||
let(:part_builder) { Dry::View::PartBuilder.new }
|
||||
|
||||
describe 'decorating without options' do
|
||||
describe 'multiple declarations' do
|
||||
describe "decorating without options" do
|
||||
describe "multiple declarations" do
|
||||
let(:article_part_class) {
|
||||
Class.new(Dry::View::Part) do
|
||||
decorate :author
|
||||
|
@ -81,43 +81,43 @@ RSpec.describe 'Part / Decorated attributes' do
|
|||
end
|
||||
}
|
||||
|
||||
it 'decorates attributes with the standard Dry::View::Part class' do
|
||||
it "decorates attributes with the standard Dry::View::Part class" do
|
||||
expect(article_part.author).to be_a Dry::View::Part
|
||||
expect(article_part.comments[0]).to be_a Dry::View::Part
|
||||
end
|
||||
|
||||
context 'falsey values' do
|
||||
context "falsey values" do
|
||||
let(:author) { nil }
|
||||
|
||||
it 'does not decorate the attributes' do
|
||||
it "does not decorate the attributes" do
|
||||
expect(article_part.author).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'single declaration' do
|
||||
describe "single declaration" do
|
||||
let(:article_part_class) {
|
||||
Class.new(Dry::View::Part) do
|
||||
decorate :author, :comments
|
||||
end
|
||||
}
|
||||
|
||||
it 'decorates attributes with the standard Dry::View::Part class' do
|
||||
it "decorates attributes with the standard Dry::View::Part class" do
|
||||
expect(article_part.author).to be_a Dry::View::Part
|
||||
expect(article_part.comments[0]).to be_a Dry::View::Part
|
||||
end
|
||||
|
||||
context 'falsey values' do
|
||||
context "falsey values" do
|
||||
let(:author) { nil }
|
||||
|
||||
it 'does not decorate the attributes' do
|
||||
it "does not decorate the attributes" do
|
||||
expect(article_part.author).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'decorating with part class specified' do
|
||||
describe "decorating with part class specified" do
|
||||
before do
|
||||
module Test
|
||||
class AuthorPart < Dry::View::Part
|
||||
|
@ -135,22 +135,22 @@ RSpec.describe 'Part / Decorated attributes' do
|
|||
end
|
||||
}
|
||||
|
||||
it 'deorates attributes with the specified part class' do
|
||||
it "deorates attributes with the specified part class" do
|
||||
expect(article_part.author).to be_a Test::AuthorPart
|
||||
expect(article_part.comments[0]).to be_a Test::CommentPart
|
||||
end
|
||||
|
||||
context 'falsey values' do
|
||||
context "falsey values" do
|
||||
let(:author) { nil }
|
||||
|
||||
it 'does not decorate the attributes' do
|
||||
it "does not decorate the attributes" do
|
||||
expect(article_part.author).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'using custom part builder' do
|
||||
describe "using custom part builder" do
|
||||
let(:article_part_class) {
|
||||
Class.new(Dry::View::Part) do
|
||||
decorate :author
|
||||
|
@ -183,16 +183,16 @@ RSpec.describe 'Part / Decorated attributes' do
|
|||
end
|
||||
end
|
||||
|
||||
it 'deorates attributes using the custom part builder' do
|
||||
it "deorates attributes using the custom part builder" do
|
||||
expect(article_part.author).to be_a Test::AuthorPart
|
||||
expect(article_part.comments[0]).to be_a Test::CommentPart
|
||||
expect(article_part.comments[0].author).to be_a Test::AuthorPart
|
||||
end
|
||||
|
||||
context 'falsey values' do
|
||||
context "falsey values" do
|
||||
let(:author) { nil }
|
||||
|
||||
it 'does not decorate the attributes' do
|
||||
it "does not decorate the attributes" do
|
||||
expect(article_part.author).to be_nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe 'part builder' do
|
||||
RSpec.describe "part builder" do
|
||||
before do
|
||||
module Test
|
||||
class Custom < Dry::View::Part
|
||||
|
@ -19,12 +19,12 @@ RSpec.describe 'part builder' do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'default decorator' do
|
||||
it 'looks up classes from a part namespace' do
|
||||
describe "default decorator" do
|
||||
it "looks up classes from a part namespace" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = nil
|
||||
config.template = 'decorated_parts'
|
||||
config.template = "decorated_parts"
|
||||
config.part_namespace = Test
|
||||
|
||||
expose :customs
|
||||
|
@ -32,46 +32,46 @@ RSpec.describe 'part builder' do
|
|||
expose :ordinary
|
||||
end.new
|
||||
|
||||
expect(view.(customs: ['many things'], custom: 'custom thing', ordinary: 'ordinary thing').to_s).to eql(
|
||||
'<p>Custom part wrapping many things</p><p>Custom part wrapping custom thing</p><p>ordinary thing</p>'
|
||||
expect(view.(customs: ["many things"], custom: "custom thing", ordinary: "ordinary thing").to_s).to eql(
|
||||
"<p>Custom part wrapping many things</p><p>Custom part wrapping custom thing</p><p>ordinary thing</p>"
|
||||
)
|
||||
end
|
||||
|
||||
it 'supports wrapping array memebers in custom part classes provided to exposure :as option' do
|
||||
it "supports wrapping array memebers in custom part classes provided to exposure :as option" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = nil
|
||||
config.template = 'decorated_parts'
|
||||
config.template = "decorated_parts"
|
||||
|
||||
expose :customs, as: Test::CustomPart
|
||||
expose :custom, as: Test::CustomPart
|
||||
expose :ordinary
|
||||
end.new
|
||||
|
||||
expect(view.(customs: ['many things'], custom: 'custom thing', ordinary: 'ordinary thing').to_s).to eql(
|
||||
'<p>Custom part wrapping many things</p><p>Custom part wrapping custom thing</p><p>ordinary thing</p>'
|
||||
expect(view.(customs: ["many things"], custom: "custom thing", ordinary: "ordinary thing").to_s).to eql(
|
||||
"<p>Custom part wrapping many things</p><p>Custom part wrapping custom thing</p><p>ordinary thing</p>"
|
||||
)
|
||||
end
|
||||
|
||||
it 'supports wrapping an array and its members in custom part classes provided to exposure :as option as a hash' do
|
||||
it "supports wrapping an array and its members in custom part classes provided to exposure :as option as a hash" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = nil
|
||||
config.template = 'decorated_parts'
|
||||
config.template = "decorated_parts"
|
||||
|
||||
expose :customs, as: [Test::CustomArrayPart, Test::CustomPart]
|
||||
expose :custom, as: Test::CustomPart
|
||||
expose :ordinary
|
||||
end.new
|
||||
|
||||
expect(view.(customs: ['many things'], custom: 'custom thing', ordinary: 'ordinary thing').to_s).to eql(
|
||||
'<p>Custom part wrapping many things</p><p>Custom part wrapping many things</p><p>Custom part wrapping custom thing</p><p>ordinary thing</p>'
|
||||
expect(view.(customs: ["many things"], custom: "custom thing", ordinary: "ordinary thing").to_s).to eql(
|
||||
"<p>Custom part wrapping many things</p><p>Custom part wrapping many things</p><p>Custom part wrapping custom thing</p><p>ordinary thing</p>"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'custom decorator and part classes' do
|
||||
it 'supports wrapping in custom parts based on exposure names' do
|
||||
describe "custom decorator and part classes" do
|
||||
it "supports wrapping in custom parts based on exposure names" do
|
||||
part_builder = Class.new(Dry::View::PartBuilder) do
|
||||
def part_class(name:, **options)
|
||||
name == :custom ? Test::CustomPart : super
|
||||
|
@ -80,15 +80,15 @@ RSpec.describe 'part builder' do
|
|||
|
||||
view = Class.new(Dry::View) do
|
||||
config.part_builder = part_builder
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = nil
|
||||
config.template = 'decorated_parts'
|
||||
config.template = "decorated_parts"
|
||||
|
||||
expose :customs, :custom, :ordinary
|
||||
end.new
|
||||
|
||||
expect(view.(customs: ['many things'], custom: 'custom thing', ordinary: 'ordinary thing').to_s).to eql(
|
||||
'<p>Custom part wrapping many things</p><p>Custom part wrapping custom thing</p><p>ordinary thing</p>'
|
||||
expect(view.(customs: ["many things"], custom: "custom thing", ordinary: "ordinary thing").to_s).to eql(
|
||||
"<p>Custom part wrapping many things</p><p>Custom part wrapping custom thing</p><p>ordinary thing</p>"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view/part'
|
||||
require 'dry/view/scope'
|
||||
require "dry/view/part"
|
||||
require "dry/view/scope"
|
||||
|
||||
RSpec.describe 'Scopes' do
|
||||
RSpec.describe "Scopes" do
|
||||
let(:base_view) {
|
||||
Class.new(Dry::View) do
|
||||
config.paths = FIXTURES_PATH.join('integration/scopes')
|
||||
config.paths = FIXTURES_PATH.join("integration/scopes")
|
||||
end
|
||||
}
|
||||
|
||||
specify 'Custom scope for a view' do
|
||||
specify "Custom scope for a view" do
|
||||
module Test
|
||||
class ControllerScope < Dry::View::Scope
|
||||
def hello
|
||||
|
@ -20,110 +20,110 @@ RSpec.describe 'Scopes' do
|
|||
end
|
||||
|
||||
view = Class.new(base_view) do
|
||||
config.template = 'custom_view_scope'
|
||||
config.template = "custom_view_scope"
|
||||
config.scope = Test::ControllerScope
|
||||
|
||||
expose :text
|
||||
end.new
|
||||
|
||||
expect(view.(text: 'world').to_s).to eq 'Hello world!'
|
||||
expect(view.(text: "world").to_s).to eq "Hello world!"
|
||||
end
|
||||
|
||||
specify 'Rendering a partial via an anonymous scope' do
|
||||
specify "Rendering a partial via an anonymous scope" do
|
||||
view = Class.new(base_view) do
|
||||
config.template = 'anonymous_scope'
|
||||
config.template = "anonymous_scope"
|
||||
|
||||
expose :text
|
||||
end.new
|
||||
|
||||
expect(view.(text: 'Hello').to_s).to eq 'Greeting: Hello'
|
||||
expect(view.(text: "Hello").to_s).to eq "Greeting: Hello"
|
||||
end
|
||||
|
||||
specify 'Rendering a partial implicitly via a custom named scope' do
|
||||
specify "Rendering a partial implicitly via a custom named scope" do
|
||||
module Test::Scopes
|
||||
class Greeting < Dry::View::Scope
|
||||
def greeting
|
||||
_locals[:greeting].upcase + '!'
|
||||
_locals[:greeting].upcase + "!"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
view = Class.new(base_view) do
|
||||
config.scope_namespace = Test::Scopes
|
||||
config.template = 'named_scope_with_implicit_render'
|
||||
config.template = "named_scope_with_implicit_render"
|
||||
|
||||
expose :text
|
||||
end.new
|
||||
|
||||
expect(view.(text: 'Hello').to_s).to eq 'Greeting: HELLO!'
|
||||
expect(view.(text: "Hello").to_s).to eq "Greeting: HELLO!"
|
||||
end
|
||||
|
||||
specify 'Rendering a partial implicitly via a custom named scope (provided via a class)' do
|
||||
specify "Rendering a partial implicitly via a custom named scope (provided via a class)" do
|
||||
module Test::Scopes
|
||||
class Greeting < Dry::View::Scope
|
||||
def greeting
|
||||
_locals[:greeting].upcase + '!'
|
||||
_locals[:greeting].upcase + "!"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
view = Class.new(base_view) do
|
||||
config.scope_namespace = Test::Scopes
|
||||
config.template = 'class_named_scope_with_implicit_render'
|
||||
config.template = "class_named_scope_with_implicit_render"
|
||||
|
||||
expose :text
|
||||
end.new
|
||||
|
||||
expect(view.(text: 'Hello').to_s).to eq 'Greeting: HELLO!'
|
||||
expect(view.(text: "Hello").to_s).to eq "Greeting: HELLO!"
|
||||
end
|
||||
|
||||
specify 'Raising an error when an unnamed partial cannot be rendered implicitly' do
|
||||
specify "Raising an error when an unnamed partial cannot be rendered implicitly" do
|
||||
view = Class.new(base_view) do
|
||||
config.template = 'unnamed_named_scope_with_implicit_render'
|
||||
config.template = "unnamed_named_scope_with_implicit_render"
|
||||
end.new
|
||||
|
||||
expect { view.().to_s }.to raise_error ArgumentError, '+partial_name+ must be provided for unnamed scopes'
|
||||
expect { view.().to_s }.to raise_error ArgumentError, "+partial_name+ must be provided for unnamed scopes"
|
||||
end
|
||||
|
||||
specify 'Rendering a partial explicitly via a custom named scope' do
|
||||
specify "Rendering a partial explicitly via a custom named scope" do
|
||||
module Test::Scopes
|
||||
class Greeting < Dry::View::Scope
|
||||
def greeting
|
||||
_locals[:greeting].upcase + '!'
|
||||
_locals[:greeting].upcase + "!"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
view = Class.new(base_view) do
|
||||
config.scope_namespace = Test::Scopes
|
||||
config.template = 'named_scope_with_explicit_render'
|
||||
config.template = "named_scope_with_explicit_render"
|
||||
|
||||
expose :text
|
||||
end.new
|
||||
|
||||
expect(view.(text: 'Hello').to_s).to eq 'Holler: HELLO!'
|
||||
expect(view.(text: "Hello").to_s).to eq "Holler: HELLO!"
|
||||
end
|
||||
|
||||
specify 'Custom named scope providing defaults for missing locals' do
|
||||
specify "Custom named scope providing defaults for missing locals" do
|
||||
module Test::Scopes
|
||||
class Greeting < Dry::View::Scope
|
||||
def greeting
|
||||
_locals.fetch(:greeting) { 'Howdy' }
|
||||
_locals.fetch(:greeting) { "Howdy" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
view = Class.new(base_view) do
|
||||
config.scope_namespace = Test::Scopes
|
||||
config.template = 'named_scope_with_defaults'
|
||||
config.template = "named_scope_with_defaults"
|
||||
|
||||
expose :text
|
||||
end.new
|
||||
|
||||
expect(view.().to_s).to eq 'Greeting: Howdy'
|
||||
expect(view.().to_s).to eq "Greeting: Howdy"
|
||||
end
|
||||
|
||||
specify 'Creating a custom scope from a view part' do
|
||||
specify "Creating a custom scope from a view part" do
|
||||
module Test::Parts
|
||||
class Message < Dry::View::Part
|
||||
def greeting
|
||||
|
@ -135,7 +135,7 @@ RSpec.describe 'Scopes' do
|
|||
module Test::Scopes
|
||||
class Greeting < Dry::View::Scope
|
||||
def greeting
|
||||
_locals[:greeting] + '!'
|
||||
_locals[:greeting] + "!"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -143,11 +143,11 @@ RSpec.describe 'Scopes' do
|
|||
view = Class.new(base_view) do
|
||||
config.part_namespace = Test::Parts
|
||||
config.scope_namespace = Test::Scopes
|
||||
config.template = 'scope_from_part'
|
||||
config.template = "scope_from_part"
|
||||
|
||||
expose :message
|
||||
end.new
|
||||
|
||||
expect(view.(message: { text: 'Hello from a part' }).to_s).to eq 'Greeting: Hello from a part!'
|
||||
expect(view.(message: {text: "Hello from a part"}).to_s).to eq "Greeting: Hello from a part!"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view'
|
||||
require 'dry/view/context'
|
||||
require "dry/view"
|
||||
require "dry/view/context"
|
||||
|
||||
RSpec.describe 'Template engines / erb (using erbse as default engine)' do
|
||||
RSpec.describe "Template engines / erb (using erbse as default engine)" do
|
||||
let(:base_view) {
|
||||
Class.new(Dry::View) do
|
||||
config.paths = FIXTURES_PATH.join('integration/template_engines/erbse')
|
||||
config.paths = FIXTURES_PATH.join("integration/template_engines/erbse")
|
||||
end
|
||||
}
|
||||
|
||||
context 'with erbse available' do
|
||||
it 'supports partials that yield' do
|
||||
context "with erbse available" do
|
||||
it "supports partials that yield" do
|
||||
view = Class.new(base_view) do
|
||||
config.template = 'render_and_yield'
|
||||
config.template = "render_and_yield"
|
||||
end.new
|
||||
|
||||
expect(view.().to_s.gsub(/\n\s*/m, '')).to eq '<wrapper> Yielded</wrapper>'
|
||||
expect(view.().to_s.gsub(/\n\s*/m, "")).to eq "<wrapper> Yielded</wrapper>"
|
||||
end
|
||||
|
||||
it 'supports context methods that yield' do
|
||||
it "supports context methods that yield" do
|
||||
context = Class.new(Dry::View::Context) do
|
||||
def wrapper
|
||||
"<wrapper>#{yield}</wrapper>"
|
||||
|
@ -28,19 +28,19 @@ RSpec.describe 'Template engines / erb (using erbse as default engine)' do
|
|||
|
||||
view = Class.new(base_view) do
|
||||
config.default_context = context
|
||||
config.template = 'method_with_yield'
|
||||
config.template = "method_with_yield"
|
||||
end.new
|
||||
|
||||
expect(view.().to_s.gsub(/\n\s*/m, '')).to eq '<wrapper> Yielded</wrapper>'
|
||||
expect(view.().to_s.gsub(/\n\s*/m, "")).to eq "<wrapper> Yielded</wrapper>"
|
||||
end
|
||||
end
|
||||
|
||||
context 'with erbse not available' do
|
||||
context "with erbse not available" do
|
||||
before do
|
||||
@load_path = $LOAD_PATH.dup
|
||||
@loaded_features = $LOADED_FEATURES.dup
|
||||
|
||||
$LOAD_PATH.reject! { |path| path =~ %r{erbse} }
|
||||
$LOAD_PATH.reject! { |path| path =~ /erbse/ }
|
||||
$LOADED_FEATURES.reject! { |path| path =~ %r{erbse|dry/view/tilt/erbse} }
|
||||
|
||||
Dry::View::Tilt.cache.clear
|
||||
|
@ -53,23 +53,23 @@ RSpec.describe 'Template engines / erb (using erbse as default engine)' do
|
|||
Dry::View::Tilt.register_adapter :erb, Dry::View::Tilt::ERB
|
||||
end
|
||||
|
||||
it 'raises an error explaining the erbse requirement' do
|
||||
it "raises an error explaining the erbse requirement" do
|
||||
view = Class.new(base_view) do
|
||||
config.template = 'render_and_yield'
|
||||
config.template = "render_and_yield"
|
||||
end.new
|
||||
|
||||
expect { view.() }.to raise_error(LoadError, %r{dry-view requires erbse}m)
|
||||
expect { view.() }.to raise_error(LoadError, /dry-view requires erbse/m)
|
||||
end
|
||||
|
||||
it 'allows deregistering the adapter to avoid the load error and accept rendering via a less-compatible erb engine' do
|
||||
it "allows deregistering the adapter to avoid the load error and accept rendering via a less-compatible erb engine" do
|
||||
view = Class.new(base_view) do
|
||||
config.template = 'plain_erb'
|
||||
config.template = "plain_erb"
|
||||
end.new
|
||||
|
||||
Dry::View::Tilt.deregister_adapter :erb
|
||||
|
||||
expect { view.() }.not_to raise_error
|
||||
expect(view.().to_s.strip).to eq 'Hello'
|
||||
expect(view.().to_s.strip).to eq "Hello"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'erubi'
|
||||
require 'erubi/capture_end'
|
||||
require 'tilt/erubi'
|
||||
require "erubi"
|
||||
require "erubi/capture_end"
|
||||
require "tilt/erubi"
|
||||
|
||||
require 'dry/view'
|
||||
require 'dry/view/context'
|
||||
require "dry/view"
|
||||
require "dry/view/context"
|
||||
|
||||
RSpec.describe 'Template engines / erb (using erubi via an explict engine mapping)' do
|
||||
RSpec.describe "Template engines / erb (using erubi via an explict engine mapping)" do
|
||||
let(:base_view) {
|
||||
Class.new(Dry::View) do
|
||||
config.paths = FIXTURES_PATH.join('integration/template_engines/erubi')
|
||||
config.renderer_engine_mapping = { erb: Tilt::ErubiTemplate }
|
||||
config.renderer_options = { engine_class: Erubi::CaptureEndEngine }
|
||||
config.paths = FIXTURES_PATH.join("integration/template_engines/erubi")
|
||||
config.renderer_engine_mapping = {erb: Tilt::ErubiTemplate}
|
||||
config.renderer_options = {engine_class: Erubi::CaptureEndEngine}
|
||||
end
|
||||
}
|
||||
|
||||
it 'supports partials that yield' do
|
||||
it "supports partials that yield" do
|
||||
view = Class.new(base_view) do
|
||||
config.template = 'render_and_yield'
|
||||
config.template = "render_and_yield"
|
||||
end.new
|
||||
|
||||
expect(view.().to_s.gsub(/\n\s*/m, '')).to eq '<wrapper>Yielded</wrapper>'
|
||||
expect(view.().to_s.gsub(/\n\s*/m, "")).to eq "<wrapper>Yielded</wrapper>"
|
||||
end
|
||||
|
||||
it 'supports context methods that yield' do
|
||||
it "supports context methods that yield" do
|
||||
context = Class.new(Dry::View::Context) do
|
||||
def wrapper
|
||||
"<wrapper>#{yield}</wrapper>"
|
||||
|
@ -33,9 +33,9 @@ RSpec.describe 'Template engines / erb (using erubi via an explict engine mappin
|
|||
|
||||
view = Class.new(base_view) do
|
||||
config.default_context = context
|
||||
config.template = 'method_with_yield'
|
||||
config.template = "method_with_yield"
|
||||
end.new
|
||||
|
||||
expect(view.().to_s.gsub(/\n\s*/m, '')).to eq '<wrapper>Yielded</wrapper>'
|
||||
expect(view.().to_s.gsub(/\n\s*/m, "")).to eq "<wrapper>Yielded</wrapper>"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view'
|
||||
require 'dry/view/context'
|
||||
require "dry/view"
|
||||
require "dry/view/context"
|
||||
|
||||
RSpec.describe 'Template engines / haml (using hamlit-block as default engine)' do
|
||||
RSpec.describe "Template engines / haml (using hamlit-block as default engine)" do
|
||||
let(:base_view) {
|
||||
Class.new(Dry::View) do
|
||||
config.paths = FIXTURES_PATH.join('integration/template_engines/hamlit')
|
||||
config.paths = FIXTURES_PATH.join("integration/template_engines/hamlit")
|
||||
end
|
||||
}
|
||||
|
||||
context 'with hamlit-block available' do
|
||||
it 'supports partials that yield' do
|
||||
context "with hamlit-block available" do
|
||||
it "supports partials that yield" do
|
||||
view = Class.new(base_view) do
|
||||
config.template = 'render_and_yield'
|
||||
config.template = "render_and_yield"
|
||||
end.new
|
||||
|
||||
expect(view.().to_s.gsub(/\n\s*/m, '')).to eq '<wrapper>Yielded</wrapper>'
|
||||
expect(view.().to_s.gsub(/\n\s*/m, "")).to eq "<wrapper>Yielded</wrapper>"
|
||||
end
|
||||
|
||||
it 'supports methods that yield' do
|
||||
it "supports methods that yield" do
|
||||
context = Class.new(Dry::View::Context) do
|
||||
def wrapper(&block)
|
||||
def wrapper
|
||||
"<wrapper>#{yield}</wrapper>"
|
||||
end
|
||||
end.new
|
||||
|
||||
view = Class.new(base_view) do
|
||||
config.default_context = context
|
||||
config.template = 'method_with_yield'
|
||||
config.template = "method_with_yield"
|
||||
end.new
|
||||
|
||||
expect(view.().to_s.gsub(/\n\s*/m, '')).to eq '<wrapper>Yielded</wrapper>'
|
||||
expect(view.().to_s.gsub(/\n\s*/m, "")).to eq "<wrapper>Yielded</wrapper>"
|
||||
end
|
||||
end
|
||||
|
||||
context 'with hamlit-block not available' do
|
||||
context "with hamlit-block not available" do
|
||||
before do
|
||||
@load_path = $LOAD_PATH.dup
|
||||
@loaded_features = $LOADED_FEATURES.dup
|
||||
|
@ -52,12 +52,12 @@ RSpec.describe 'Template engines / haml (using hamlit-block as default engine)'
|
|||
$LOADED_FEATURES.replace @loaded_features
|
||||
end
|
||||
|
||||
it 'raises an error explaining the hamlit-block requirement' do
|
||||
it "raises an error explaining the hamlit-block requirement" do
|
||||
view = Class.new(base_view) do
|
||||
config.template = 'render_and_yield'
|
||||
config.template = "render_and_yield"
|
||||
end.new
|
||||
|
||||
expect { view.() }.to raise_error(LoadError, %r{dry-view requires hamlit-block}m)
|
||||
expect { view.() }.to raise_error(LoadError, /dry-view requires hamlit-block/m)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'slim'
|
||||
require 'dry/view'
|
||||
require 'dry/view/context'
|
||||
require "slim"
|
||||
require "dry/view"
|
||||
require "dry/view/context"
|
||||
|
||||
RSpec.describe 'Template engines / slim' do
|
||||
RSpec.describe "Template engines / slim" do
|
||||
let(:base_view) {
|
||||
Class.new(Dry::View) do
|
||||
config.paths = FIXTURES_PATH.join('integration/template_engines/slim')
|
||||
config.paths = FIXTURES_PATH.join("integration/template_engines/slim")
|
||||
end
|
||||
}
|
||||
|
||||
it 'supports partials that yield' do
|
||||
it "supports partials that yield" do
|
||||
view = Class.new(base_view) do
|
||||
config.template = 'render_and_yield'
|
||||
config.template = "render_and_yield"
|
||||
end.new
|
||||
|
||||
expect(view.().to_s).to eq '<wrapper>Yielded</wrapper>'
|
||||
expect(view.().to_s).to eq "<wrapper>Yielded</wrapper>"
|
||||
end
|
||||
|
||||
it 'supports context methods that yield' do
|
||||
it "supports context methods that yield" do
|
||||
context = Class.new(Dry::View::Context) do
|
||||
def wrapper
|
||||
"<wrapper>#{yield}</wrapper>"
|
||||
|
@ -28,9 +28,9 @@ RSpec.describe 'Template engines / slim' do
|
|||
|
||||
view = Class.new(base_view) do
|
||||
config.default_context = context
|
||||
config.template = 'method_with_yield'
|
||||
config.template = "method_with_yield"
|
||||
end.new
|
||||
|
||||
expect(view.().to_s).to eq '<wrapper>Yielded</wrapper>'
|
||||
expect(view.().to_s).to eq "<wrapper>Yielded</wrapper>"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe 'Testing / parts' do
|
||||
RSpec.describe "Testing / parts" do
|
||||
let(:part_class) {
|
||||
Class.new(Dry::View::Part) do
|
||||
end
|
||||
|
@ -9,21 +9,21 @@ RSpec.describe 'Testing / parts' do
|
|||
specify "Parts can be unit tested without name or rendering (for testing methods that don't require them)" do
|
||||
part_class = Class.new(Dry::View::Part) do
|
||||
def breaking_news_title
|
||||
title + '!'
|
||||
title + "!"
|
||||
end
|
||||
end
|
||||
|
||||
article = Struct.new(:title).new('Giant Hand Threatens Beach City')
|
||||
article = Struct.new(:title).new("Giant Hand Threatens Beach City")
|
||||
|
||||
article_part = part_class.new(value: article)
|
||||
|
||||
expect(article_part.breaking_news_title).to eq 'Giant Hand Threatens Beach City!'
|
||||
expect(article_part.breaking_news_title).to eq "Giant Hand Threatens Beach City!"
|
||||
end
|
||||
|
||||
specify 'Parts can be unit tested with a rendering from a view class' do
|
||||
specify "Parts can be unit tested with a rendering from a view class" do
|
||||
view_class = Class.new(Dry::View) do
|
||||
config.paths = FIXTURES_PATH.join('integration/testing')
|
||||
config.template = 'view'
|
||||
config.paths = FIXTURES_PATH.join("integration/testing")
|
||||
config.template = "view"
|
||||
end
|
||||
|
||||
part_class = Class.new(Dry::View::Part) do
|
||||
|
@ -32,12 +32,12 @@ RSpec.describe 'Testing / parts' do
|
|||
end
|
||||
end
|
||||
|
||||
article = Struct.new(:title).new('A Guide to Beach City Funland')
|
||||
article = Struct.new(:title).new("A Guide to Beach City Funland")
|
||||
|
||||
article_part = part_class.new(
|
||||
name: :article,
|
||||
value: article,
|
||||
render_env: view_class.template_env,
|
||||
render_env: view_class.template_env
|
||||
)
|
||||
|
||||
expect(article_part.feature_box).to eq %(
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view'
|
||||
require 'dry/view/context'
|
||||
require "dry/view"
|
||||
require "dry/view/context"
|
||||
|
||||
RSpec.describe 'View / errors' do
|
||||
specify 'Raising an error when paths are not configured' do
|
||||
RSpec.describe "View / errors" do
|
||||
specify "Raising an error when paths are not configured" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.template = 'hello'
|
||||
config.template = "hello"
|
||||
end.new
|
||||
|
||||
expect { view.() }.to raise_error(Dry::View::UndefinedConfigError, 'no +paths+ configured')
|
||||
expect { view.() }.to raise_error(Dry::View::UndefinedConfigError, "no +paths+ configured")
|
||||
end
|
||||
|
||||
specify 'Raising an error when template is not configured' do
|
||||
specify "Raising an error when template is not configured" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = FIXTURES_PATH.join('integration/errors')
|
||||
config.paths = FIXTURES_PATH.join("integration/errors")
|
||||
end.new
|
||||
|
||||
expect { view.() }.to raise_error(Dry::View::UndefinedConfigError, 'no +template+ configured')
|
||||
expect { view.() }.to raise_error(Dry::View::UndefinedConfigError, "no +template+ configured")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view'
|
||||
require 'dry/view/context'
|
||||
require "dry/view"
|
||||
require "dry/view/context"
|
||||
|
||||
RSpec.describe 'View / exposures' do
|
||||
specify 'exposures have access to context' do
|
||||
RSpec.describe "View / exposures" do
|
||||
specify "exposures have access to context" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.template = 'greeting'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.template = "greeting"
|
||||
|
||||
expose :greeting do |greeting:, context:|
|
||||
"#{greeting}, #{context.name}"
|
||||
|
@ -16,12 +16,12 @@ RSpec.describe 'View / exposures' do
|
|||
|
||||
context = Class.new(Dry::View::Context) do
|
||||
def name
|
||||
'Jane'
|
||||
"Jane"
|
||||
end
|
||||
end.new
|
||||
|
||||
local = view.(greeting: 'Hello', context: context).locals[:greeting]
|
||||
local = view.(greeting: "Hello", context: context).locals[:greeting]
|
||||
|
||||
expect(local.value).to eq 'Hello, Jane'
|
||||
expect(local.value).to eq "Hello, Jane"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view'
|
||||
require 'dry/view/part'
|
||||
require "dry/view"
|
||||
require "dry/view/part"
|
||||
|
||||
RSpec.describe 'View / locals' do
|
||||
specify 'locals are decorated with parts by default' do
|
||||
RSpec.describe "View / locals" do
|
||||
specify "locals are decorated with parts by default" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.template = 'greeting'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.template = "greeting"
|
||||
|
||||
expose :greeting
|
||||
end.new
|
||||
|
||||
local = view.(greeting: 'Hello').locals[:greeting]
|
||||
local = view.(greeting: "Hello").locals[:greeting]
|
||||
|
||||
expect(local).to be_a(Dry::View::Part)
|
||||
end
|
||||
|
||||
specify 'locals are not decorated if their exposure is marked as `decorate: false`' do
|
||||
specify "locals are not decorated if their exposure is marked as `decorate: false`" do
|
||||
view = Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.template = 'greeting'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.template = "greeting"
|
||||
|
||||
expose :greeting, decorate: false
|
||||
end.new
|
||||
|
||||
local = view.(greeting: 'Hello').locals[:greeting]
|
||||
local = view.(greeting: "Hello").locals[:greeting]
|
||||
|
||||
expect(local).to eq 'Hello'
|
||||
expect(local).to eq "Hello"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# coding: utf-8
|
||||
|
||||
RSpec.describe 'dry-view' do
|
||||
RSpec.describe "dry-view" do
|
||||
let(:view_class) do
|
||||
Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'users'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "users"
|
||||
config.default_format = :html
|
||||
|
||||
expose :users do
|
||||
[
|
||||
{ name: 'Jane', email: 'jane@doe.org' },
|
||||
{ name: 'Joe', email: 'joe@doe.org' }
|
||||
{name: "Jane", email: "jane@doe.org"},
|
||||
{name: "Joe", email: "joe@doe.org"}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
@ -22,7 +20,7 @@ RSpec.describe 'dry-view' do
|
|||
let(:context) {
|
||||
Class.new(Dry::View::Context) do
|
||||
def title
|
||||
'dry-view rocks!'
|
||||
"dry-view rocks!"
|
||||
end
|
||||
|
||||
def assets
|
||||
|
@ -31,7 +29,7 @@ RSpec.describe 'dry-view' do
|
|||
end.new
|
||||
}
|
||||
|
||||
it 'renders within a layout and makes the provided context available everywhere' do
|
||||
it "renders within a layout and makes the provided context available everywhere" do
|
||||
view = view_class.new
|
||||
|
||||
expect(view.(context: context).to_s).to eql(
|
||||
|
@ -39,7 +37,7 @@ RSpec.describe 'dry-view' do
|
|||
)
|
||||
end
|
||||
|
||||
it 'renders without a layout' do
|
||||
it "renders without a layout" do
|
||||
view = Class.new(view_class) do
|
||||
config.layout = false
|
||||
end.new
|
||||
|
@ -49,18 +47,18 @@ RSpec.describe 'dry-view' do
|
|||
)
|
||||
end
|
||||
|
||||
it 'renders a view with an alternative format and engine' do
|
||||
it "renders a view with an alternative format and engine" do
|
||||
view = view_class.new
|
||||
|
||||
# FIXME: there should be a "\n\n" before "* Jane", but this is missing due to https://github.com/apotonick/erbse/issues/10
|
||||
expect(view.(context: context, format: 'txt').to_s.strip).to eql(
|
||||
expect(view.(context: context, format: "txt").to_s.strip).to eql(
|
||||
"# dry-view rocks!* Jane (jane@doe.org)\n* Joe (joe@doe.org)"
|
||||
)
|
||||
end
|
||||
|
||||
it 'renders a view with a template on another view path' do
|
||||
it "renders a view with a template on another view path" do
|
||||
view = Class.new(view_class) do
|
||||
config.paths = [SPEC_ROOT.join('fixtures/templates_override')] + Array(config.paths)
|
||||
config.paths = [SPEC_ROOT.join("fixtures/templates_override")] + Array(config.paths)
|
||||
end.new
|
||||
|
||||
expect(view.(context: context).to_s).to eq(
|
||||
|
@ -68,9 +66,9 @@ RSpec.describe 'dry-view' do
|
|||
)
|
||||
end
|
||||
|
||||
it 'renders a view that passes arguments to partials' do
|
||||
it "renders a view that passes arguments to partials" do
|
||||
view = Class.new(view_class) do
|
||||
config.template = 'parts_with_args'
|
||||
config.template = "parts_with_args"
|
||||
end.new
|
||||
|
||||
expect(view.(context: context).to_s).to eq(
|
||||
|
@ -78,47 +76,47 @@ RSpec.describe 'dry-view' do
|
|||
)
|
||||
end
|
||||
|
||||
it 'renders using utf-8 by default' do
|
||||
it "renders using utf-8 by default" do
|
||||
view = Class.new(view_class) do
|
||||
config.template = 'utf8'
|
||||
config.template = "utf8"
|
||||
end.new
|
||||
|
||||
expect(view.(context: context).to_s).to eq(
|
||||
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body>ç</body></html>'
|
||||
"<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body>ç</body></html>"
|
||||
)
|
||||
end
|
||||
|
||||
describe 'inheritance' do
|
||||
describe "inheritance" do
|
||||
let(:parent_view) do
|
||||
klass = Class.new(Dry::View)
|
||||
|
||||
klass.setting :paths, SPEC_ROOT.join('fixtures/templates')
|
||||
klass.setting :layout, 'app'
|
||||
klass.setting :formats, { html: :slim }
|
||||
klass.setting :paths, SPEC_ROOT.join("fixtures/templates")
|
||||
klass.setting :layout, "app"
|
||||
klass.setting :formats, html: :slim
|
||||
|
||||
klass
|
||||
end
|
||||
|
||||
let(:child_view) do
|
||||
Class.new(parent_view) do
|
||||
config.template = 'tasks'
|
||||
config.template = "tasks"
|
||||
end
|
||||
end
|
||||
|
||||
it 'renders within a parent class layout using provided context' do
|
||||
it "renders within a parent class layout using provided context" do
|
||||
view = Class.new(view_class) do
|
||||
config.template = 'tasks'
|
||||
config.template = "tasks"
|
||||
|
||||
expose :tasks do
|
||||
[
|
||||
{ title: 'one' },
|
||||
{ title: 'two' },
|
||||
{title: "one"},
|
||||
{title: "two"}
|
||||
]
|
||||
end
|
||||
end.new
|
||||
|
||||
expect(view.(context: context).to_s).to eql(
|
||||
'<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><ol><li>one</li><li>two</li></ol></body></html>'
|
||||
"<!DOCTYPE html><html><head><title>dry-view rocks!</title></head><body><ol><li>one</li><li>two</li></ol></body></html>"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'support/coverage'
|
||||
require_relative "support/coverage"
|
||||
|
||||
begin
|
||||
require 'pry-byebug'
|
||||
require "pry-byebug"
|
||||
rescue LoadError; end
|
||||
SPEC_ROOT = Pathname(__FILE__).dirname
|
||||
FIXTURES_PATH = SPEC_ROOT.join('fixtures')
|
||||
FIXTURES_PATH = SPEC_ROOT.join("fixtures")
|
||||
|
||||
require 'slim'
|
||||
require 'dry/view'
|
||||
require "slim"
|
||||
require "dry/view"
|
||||
|
||||
module Test
|
||||
def self.remove_constants
|
||||
|
@ -34,7 +34,7 @@ RSpec.configure do |config|
|
|||
Dry::View::Path,
|
||||
Dry::View::Renderer,
|
||||
Dry::View::ScopeBuilder,
|
||||
Dry::View::Tilt,
|
||||
Dry::View::Tilt
|
||||
].each do |klass|
|
||||
klass.cache.clear
|
||||
end
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view/context'
|
||||
require 'dry/view/part'
|
||||
require 'dry/view/part_builder'
|
||||
require 'dry/view/scope_builder'
|
||||
require "dry/view/context"
|
||||
require "dry/view/part"
|
||||
require "dry/view/part_builder"
|
||||
require "dry/view/scope_builder"
|
||||
|
||||
RSpec.describe Dry::View::Context do
|
||||
let(:context_class) {
|
||||
|
@ -30,38 +30,38 @@ RSpec.describe Dry::View::Context do
|
|||
renderer: double(:renderer),
|
||||
context: Dry::View::Context.new,
|
||||
part_builder: Dry::View::PartBuilder.new,
|
||||
scope_builder: Dry::View::ScopeBuilder.new,
|
||||
scope_builder: Dry::View::ScopeBuilder.new
|
||||
)
|
||||
}
|
||||
|
||||
subject(:context) { context_class.new(assets: assets, routes: routes) }
|
||||
|
||||
describe 'attribute readers' do
|
||||
it 'provides access to its attributes' do
|
||||
describe "attribute readers" do
|
||||
it "provides access to its attributes" do
|
||||
expect(context.assets).to eql assets
|
||||
end
|
||||
end
|
||||
|
||||
context 'with render environment' do
|
||||
context "with render environment" do
|
||||
subject(:context) {
|
||||
context_class.new(assets: assets, routes: routes).for_render_env(render_env)
|
||||
}
|
||||
|
||||
describe 'attribute readers' do
|
||||
it 'provides attributes decorated in view parts' do
|
||||
describe "attribute readers" do
|
||||
it "provides attributes decorated in view parts" do
|
||||
expect(context.assets).to be_a Dry::View::Part
|
||||
expect(context.assets.value).to eql assets
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#with' do
|
||||
it 'returns a copy of the context with extra options' do
|
||||
describe "#with" do
|
||||
it "returns a copy of the context with extra options" do
|
||||
another_option = double(:another_option)
|
||||
new_context = context.with(another_option: another_option)
|
||||
|
||||
expect(new_context).to be_a(context.class)
|
||||
expect(new_context._options).to eq({ assets: context.assets, routes: routes, another_option: another_option })
|
||||
expect(new_context._options).to eq(assets: context.assets, routes: routes, another_option: another_option)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view/decorated_attributes'
|
||||
require "dry/view/decorated_attributes"
|
||||
|
||||
RSpec.describe Dry::View::DecoratedAttributes do
|
||||
subject(:decoratable) {
|
||||
|
@ -19,38 +19,38 @@ RSpec.describe Dry::View::DecoratedAttributes do
|
|||
let(:attr_2) { double(:attr_2) }
|
||||
let(:render_env) { spy(:render_env) }
|
||||
|
||||
context 'with render environment' do
|
||||
it 'returns decorated attributes as parts' do
|
||||
context "with render environment" do
|
||||
it "returns decorated attributes as parts" do
|
||||
decoratable.attr_1
|
||||
expect(render_env).to have_received(:part).with(:attr_1, attr_1, as: :my_value)
|
||||
|
||||
decoratable.attr_2
|
||||
if RUBY_VERSION >= '2.7'
|
||||
if RUBY_VERSION >= "2.7"
|
||||
expect(render_env).to have_received(:part).with(:attr_2, attr_2)
|
||||
else
|
||||
expect(render_env).to have_received(:part).with(:attr_2, attr_2, {})
|
||||
end
|
||||
end
|
||||
|
||||
it 'raises NoMethodError when an invalid attribute is accessed' do
|
||||
it "raises NoMethodError when an invalid attribute is accessed" do
|
||||
expect { decoratable.invalid_attr }.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'without render environment' do
|
||||
context "without render environment" do
|
||||
let(:render_env) { nil }
|
||||
|
||||
it 'returns attributes without decoration' do
|
||||
it "returns attributes without decoration" do
|
||||
expect(decoratable.attr_1).to be attr_1
|
||||
end
|
||||
|
||||
it 'raises NoMethodError when an invalid attribute is accessed' do
|
||||
it "raises NoMethodError when an invalid attribute is accessed" do
|
||||
expect { decoratable.invalid_attr }.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
it 'prepends a single module to provide the decorated attribute readers' do
|
||||
it "prepends a single module to provide the decorated attribute readers" do
|
||||
expect(decoratable.class.ancestors.map(&:name).grep(/Test::Decoratable::DecoratedAttributes/).length).to eq 1
|
||||
expect(decoratable.class.ancestors[0].inspect).to eq '#<Dry::View::DecoratedAttributes::Attributes[:attr_1, :attr_2, :invalid_attr]>'
|
||||
expect(decoratable.class.ancestors[0].inspect).to eq "#<Dry::View::DecoratedAttributes::Attributes[:attr_1, :attr_2, :invalid_attr]>"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,94 +3,94 @@
|
|||
RSpec.describe Dry::View::Exposure do
|
||||
subject(:exposure) { described_class.new(:hello, proc, object, **options) }
|
||||
|
||||
let(:proc) { -> input { 'hi' } }
|
||||
let(:proc) { -> _input { "hi" } }
|
||||
let(:object) { nil }
|
||||
let(:options) { {} }
|
||||
|
||||
describe 'initialization and attributes' do
|
||||
describe '#name' do
|
||||
it 'accepts a name' do
|
||||
describe "initialization and attributes" do
|
||||
describe "#name" do
|
||||
it "accepts a name" do
|
||||
expect(exposure.name).to eql :hello
|
||||
end
|
||||
end
|
||||
|
||||
describe '#proc' do
|
||||
it 'accepts a proc' do
|
||||
describe "#proc" do
|
||||
it "accepts a proc" do
|
||||
expect(exposure.proc).to eql proc
|
||||
end
|
||||
|
||||
it 'allows a nil proc' do
|
||||
it "allows a nil proc" do
|
||||
expect(described_class.new(:hello).proc).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#object' do
|
||||
describe "#object" do
|
||||
let(:object) { Object.new }
|
||||
|
||||
it 'accepts an object' do
|
||||
it "accepts an object" do
|
||||
expect(exposure.object).to eq object
|
||||
end
|
||||
|
||||
it 'allows a nil object' do
|
||||
it "allows a nil object" do
|
||||
expect(described_class.new(:hello).object).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#decorate?' do
|
||||
it 'is true by default' do
|
||||
describe "#decorate?" do
|
||||
it "is true by default" do
|
||||
expect(exposure.decorate?).to eq true
|
||||
end
|
||||
|
||||
it 'can be set on initialization' do
|
||||
it "can be set on initialization" do
|
||||
expect(described_class.new(:hello, decorate: false).decorate?).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe '#private?' do
|
||||
it 'is false by default' do
|
||||
describe "#private?" do
|
||||
it "is false by default" do
|
||||
expect(exposure).not_to be_private
|
||||
end
|
||||
|
||||
it 'can be set on initialization' do
|
||||
it "can be set on initialization" do
|
||||
expect(described_class.new(:hello, private: true)).to be_private
|
||||
end
|
||||
end
|
||||
|
||||
describe '#default_value' do
|
||||
it 'is nil by default' do
|
||||
describe "#default_value" do
|
||||
it "is nil by default" do
|
||||
expect(exposure.default_value).to be_nil
|
||||
end
|
||||
|
||||
it 'can be set on initialization' do
|
||||
exposuse = described_class.new(:hello, default: 'Hi !')
|
||||
expect(exposuse.default_value).to eq('Hi !')
|
||||
it "can be set on initialization" do
|
||||
exposuse = described_class.new(:hello, default: "Hi !")
|
||||
expect(exposuse.default_value).to eq("Hi !")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#bind' do
|
||||
describe "#bind" do
|
||||
subject(:bound_exposure) { exposure.bind(bind_object) }
|
||||
|
||||
let(:bind_object) { Object.new }
|
||||
|
||||
it 'returns a new object' do
|
||||
it "returns a new object" do
|
||||
expect(bound_exposure).not_to eql exposure
|
||||
end
|
||||
|
||||
it 'retains the bind object' do
|
||||
it "retains the bind object" do
|
||||
expect(bound_exposure.object).to eq bind_object
|
||||
end
|
||||
|
||||
context 'proc is set' do
|
||||
it 'retains the existing proc' do
|
||||
context "proc is set" do
|
||||
it "retains the existing proc" do
|
||||
expect(bound_exposure.proc).to eql proc
|
||||
end
|
||||
end
|
||||
|
||||
context 'proc is nil' do
|
||||
context "proc is nil" do
|
||||
let(:proc) { nil }
|
||||
|
||||
context 'matching instance method' do
|
||||
context "matching instance method" do
|
||||
let(:bind_object) do
|
||||
Class.new do
|
||||
def hello(input)
|
||||
|
@ -104,31 +104,31 @@ RSpec.describe Dry::View::Exposure do
|
|||
end
|
||||
end
|
||||
|
||||
context 'no matching instance method' do
|
||||
context "no matching instance method" do
|
||||
let(:object) { Object.new }
|
||||
|
||||
it 'leaves proc as nil' do
|
||||
it "leaves proc as nil" do
|
||||
expect(bound_exposure.proc).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#dependency_names' do
|
||||
context 'proc provided' do
|
||||
let(:proc) { -> input, foo, bar { 'hi' } }
|
||||
describe "#dependency_names" do
|
||||
context "proc provided" do
|
||||
let(:proc) { -> input, foo, bar { "hi" } } # rubocop:disable Lint/UnusedBlockArgument
|
||||
|
||||
it "returns an array of exposure dependencies derived from the proc's argument names" do
|
||||
expect(exposure.dependency_names).to eql [:input, :foo, :bar]
|
||||
end
|
||||
end
|
||||
|
||||
context 'matching instance method' do
|
||||
context "matching instance method" do
|
||||
let(:proc) { nil }
|
||||
|
||||
let(:object) do
|
||||
Class.new do
|
||||
def hello(input, bar, baz)
|
||||
def hello(input, bar, baz) # rubocop:disable Lint/UnusedMethodArgument
|
||||
"hi there, #{input.fetch(:name)}"
|
||||
end
|
||||
end.new
|
||||
|
@ -139,73 +139,73 @@ RSpec.describe Dry::View::Exposure do
|
|||
end
|
||||
end
|
||||
|
||||
context 'proc is nil' do
|
||||
context "proc is nil" do
|
||||
let(:proc) { nil }
|
||||
|
||||
it 'returns no dependencies' do
|
||||
it "returns no dependencies" do
|
||||
expect(exposure.dependency_names).to eql []
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
let(:input) { { name: 'Jane' } }
|
||||
describe "#call" do
|
||||
let(:input) { {name: "Jane"} }
|
||||
|
||||
context 'proc expects input only' do
|
||||
context "proc expects input only" do
|
||||
let(:proc) { -> name: { name } }
|
||||
|
||||
it 'sends the input to the proc' do
|
||||
expect(exposure.(input)).to eql 'Jane'
|
||||
it "sends the input to the proc" do
|
||||
expect(exposure.(input)).to eql "Jane"
|
||||
end
|
||||
end
|
||||
|
||||
context 'proc expects input and dependencies' do
|
||||
context "proc expects input and dependencies" do
|
||||
let(:proc) { -> greeting, name: { "#{greeting}, #{name}" } }
|
||||
let(:locals) { { greeting: 'Hola' } }
|
||||
let(:locals) { {greeting: "Hola"} }
|
||||
|
||||
it 'sends the input and dependency values to the proc' do
|
||||
expect(exposure.(input, locals)).to eq 'Hola, Jane'
|
||||
it "sends the input and dependency values to the proc" do
|
||||
expect(exposure.(input, locals)).to eq "Hola, Jane"
|
||||
end
|
||||
end
|
||||
|
||||
context 'Default value' do
|
||||
let(:options) { { default: 'John' } }
|
||||
context "Default value" do
|
||||
let(:options) { {default: "John"} }
|
||||
|
||||
context 'use default value' do
|
||||
context "use default value" do
|
||||
let(:proc) { nil }
|
||||
|
||||
it 'use the default value' do
|
||||
expect(exposure.({})).to eq 'John'
|
||||
it "use the default value" do
|
||||
expect(exposure.({})).to eq "John"
|
||||
end
|
||||
end
|
||||
|
||||
context 'use input value instead of default' do
|
||||
context "use input value instead of default" do
|
||||
let(:proc) { nil }
|
||||
|
||||
it 'use the default value' do
|
||||
expect(exposure.({ hello: 'Jane' })).to eq 'Jane'
|
||||
it "use the default value" do
|
||||
expect(exposure.(hello: "Jane")).to eq "Jane"
|
||||
end
|
||||
end
|
||||
|
||||
context 'use input value over default even when input is nil' do
|
||||
context "use input value over default even when input is nil" do
|
||||
let(:proc) { nil }
|
||||
|
||||
it 'use the default value' do
|
||||
expect(exposure.({ hello: nil })).to eq nil
|
||||
it "use the default value" do
|
||||
expect(exposure.(hello: nil)).to eq nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'proc expects dependencies only' do
|
||||
context "proc expects dependencies only" do
|
||||
let(:proc) { -> greeting, farewell { "#{greeting}, #{farewell}" } }
|
||||
let(:locals) { { greeting: 'Hola', farewell: 'Adios' } }
|
||||
let(:locals) { {greeting: "Hola", farewell: "Adios"} }
|
||||
|
||||
it 'sends the dependency values to the proc' do
|
||||
expect(exposure.(input, locals)).to eq 'Hola, Adios'
|
||||
it "sends the dependency values to the proc" do
|
||||
expect(exposure.(input, locals)).to eq "Hola, Adios"
|
||||
end
|
||||
end
|
||||
|
||||
context 'proc accesses object instance' do
|
||||
context "proc accesses object instance" do
|
||||
let(:proc) { -> name: { "My name is #{name} but call me #{title} #{name}" } }
|
||||
|
||||
let(:object) do
|
||||
|
@ -215,23 +215,23 @@ RSpec.describe Dry::View::Exposure do
|
|||
def initialize(title)
|
||||
@title = title
|
||||
end
|
||||
end.new('Dr')
|
||||
end.new("Dr")
|
||||
end
|
||||
|
||||
it 'makes the instance available as self' do
|
||||
expect(exposure.(input)).to eq 'My name is Jane but call me Dr Jane'
|
||||
it "makes the instance available as self" do
|
||||
expect(exposure.(input)).to eq "My name is Jane but call me Dr Jane"
|
||||
end
|
||||
end
|
||||
|
||||
context 'no proc' do
|
||||
context "no proc" do
|
||||
let(:proc) { nil }
|
||||
let(:input) { { hello: 'hi there' } }
|
||||
let(:input) { {hello: "hi there"} }
|
||||
|
||||
it 'returns a matching key from the input' do
|
||||
expect(exposure.(input)).to eq 'hi there'
|
||||
it "returns a matching key from the input" do
|
||||
expect(exposure.(input)).to eq "hi there"
|
||||
end
|
||||
|
||||
it 'returns nil when no input key matches' do
|
||||
it "returns nil when no input key matches" do
|
||||
expect(exposure.(nothing_matches_here: true)).to be_nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
RSpec.describe Dry::View::Exposures do
|
||||
subject(:exposures) { described_class.new }
|
||||
|
||||
describe '#exposures' do
|
||||
it 'is empty by defalut' do
|
||||
describe "#exposures" do
|
||||
it "is empty by defalut" do
|
||||
expect(exposures.exposures).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
describe '#add' do
|
||||
it 'creates and adds an exposure' do
|
||||
proc = -> **input { 'hi' }
|
||||
describe "#add" do
|
||||
it "creates and adds an exposure" do
|
||||
proc = -> **_input { "hi" }
|
||||
exposures.add :hello, proc
|
||||
|
||||
expect(exposures[:hello].name).to eq :hello
|
||||
|
@ -19,13 +19,13 @@ RSpec.describe Dry::View::Exposures do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#bind' do
|
||||
describe "#bind" do
|
||||
subject(:bound_exposures) { exposures.bind(object) }
|
||||
|
||||
let(:object) do
|
||||
Class.new do
|
||||
def hello(input)
|
||||
'hi'
|
||||
def hello(_input)
|
||||
"hi"
|
||||
end
|
||||
end.new
|
||||
end
|
||||
|
@ -34,91 +34,91 @@ RSpec.describe Dry::View::Exposures do
|
|||
exposures.add(:hello)
|
||||
end
|
||||
|
||||
it 'binds each of the exposures' do
|
||||
it "binds each of the exposures" do
|
||||
expect(bound_exposures[:hello].proc).to eq object.method(:hello)
|
||||
end
|
||||
|
||||
it 'returns a new copy of the exposures' do
|
||||
it "returns a new copy of the exposures" do
|
||||
expect(exposures.exposures).not_to eql(bound_exposures.exposures)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
describe 'in general' do
|
||||
describe "#call" do
|
||||
describe "in general" do
|
||||
before do
|
||||
exposures.add(:greeting, -> greeting: { greeting.upcase })
|
||||
exposures.add(:farewell, -> greeting { "#{greeting} and goodbye" })
|
||||
end
|
||||
|
||||
subject(:locals) { exposures.(greeting: 'hello') }
|
||||
subject(:locals) { exposures.(greeting: "hello") }
|
||||
|
||||
it 'returns the values from calling the exposures' do
|
||||
expect(locals).to eq(greeting: 'HELLO', farewell: 'HELLO and goodbye')
|
||||
it "returns the values from calling the exposures" do
|
||||
expect(locals).to eq(greeting: "HELLO", farewell: "HELLO and goodbye")
|
||||
end
|
||||
|
||||
it 'does not include values from private exposures' do
|
||||
exposures.add(:hidden, -> **input { 'shh' }, private: true)
|
||||
it "does not include values from private exposures" do
|
||||
exposures.add(:hidden, -> **_input { "shh" }, private: true)
|
||||
|
||||
expect(locals).to include(:greeting, :farewell)
|
||||
expect(locals).not_to include(:hidden)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with block provided' do
|
||||
describe "with block provided" do
|
||||
before do
|
||||
exposures.add(:greeting, -> greeting: { greeting.upcase })
|
||||
exposures.add(:farewell, -> greeting { "#{greeting} and goodbye" })
|
||||
end
|
||||
|
||||
subject(:locals) {
|
||||
exposures.(greeting: 'hello') do |value, exposure|
|
||||
exposures.(greeting: "hello") do |value, exposure|
|
||||
"#{value} from #{exposure.name}"
|
||||
end
|
||||
}
|
||||
|
||||
it 'provides values determined from the block' do
|
||||
it "provides values determined from the block" do
|
||||
expect(locals).to eq(
|
||||
greeting: 'HELLO from greeting',
|
||||
farewell: 'HELLO from greeting and goodbye from farewell',
|
||||
greeting: "HELLO from greeting",
|
||||
farewell: "HELLO from greeting and goodbye from farewell"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with default exposure values' do
|
||||
describe "with default exposure values" do
|
||||
it "returns 'default_value' from exposure" do
|
||||
exposures.add(:name, default: 'John')
|
||||
exposures.add(:name, default: "John")
|
||||
locals = exposures.({})
|
||||
|
||||
expect(locals).to eq(name: 'John')
|
||||
expect(locals).to eq(name: "John")
|
||||
end
|
||||
|
||||
it 'returns values from arguments' do
|
||||
exposures.add(:name, default: 'John')
|
||||
locals = exposures.(name: 'William')
|
||||
it "returns values from arguments" do
|
||||
exposures.add(:name, default: "John")
|
||||
locals = exposures.(name: "William")
|
||||
|
||||
expect(locals).to eq(name: 'William')
|
||||
expect(locals).to eq(name: "William")
|
||||
end
|
||||
|
||||
it 'returns values from arguments even when value is nil' do
|
||||
exposures.add(:name, default: 'John')
|
||||
it "returns values from arguments even when value is nil" do
|
||||
exposures.add(:name, default: "John")
|
||||
locals = exposures.(name: nil)
|
||||
|
||||
expect(locals).to eq(name: nil)
|
||||
end
|
||||
|
||||
it 'returns value from proc' do
|
||||
exposures.add(:name, -> name: { name.upcase }, default: 'John')
|
||||
locals = exposures.(name: 'William')
|
||||
it "returns value from proc" do
|
||||
exposures.add(:name, -> name: { name.upcase }, default: "John")
|
||||
locals = exposures.(name: "William")
|
||||
|
||||
expect(locals).to eq(name: 'WILLIAM')
|
||||
expect(locals).to eq(name: "WILLIAM")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#import' do
|
||||
it 'imports an exposure to the set' do
|
||||
describe "#import" do
|
||||
it "imports an exposure to the set" do
|
||||
exposures_b = described_class.new
|
||||
exposures.add(:name, -> name: { name.upcase }, default: 'John')
|
||||
exposures.add(:name, -> name: { name.upcase }, default: "John")
|
||||
exposures_b.import(:name, exposures[:name])
|
||||
|
||||
expect(exposures_b[:name]).to eq(exposures[:name])
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view/scope_builder'
|
||||
require "dry/view/scope_builder"
|
||||
|
||||
RSpec.describe Dry::View::PartBuilder do
|
||||
subject(:part_builder) { render_env.part_builder }
|
||||
|
@ -17,7 +17,7 @@ RSpec.describe Dry::View::PartBuilder do
|
|||
|
||||
let(:namespace) { nil }
|
||||
|
||||
describe '#call' do
|
||||
describe "#call" do
|
||||
subject(:part) {
|
||||
part_builder.(name, value, **options)
|
||||
}
|
||||
|
@ -26,31 +26,31 @@ RSpec.describe Dry::View::PartBuilder do
|
|||
let(:value) { double(:user) }
|
||||
let(:options) { {} }
|
||||
|
||||
shared_examples 'a view part' do
|
||||
shared_examples "a view part" do
|
||||
let(:part_class) { Dry::View::Part }
|
||||
|
||||
it 'returns a part' do
|
||||
it "returns a part" do
|
||||
expect(part).to be_a part_class
|
||||
end
|
||||
|
||||
it 'wraps the value' do
|
||||
it "wraps the value" do
|
||||
expect(part._value).to eq value
|
||||
end
|
||||
|
||||
it 'retains the render environment' do
|
||||
it "retains the render environment" do
|
||||
expect(part._render_env).to eql render_env
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'a view part collection' do
|
||||
shared_examples "a view part collection" do
|
||||
let(:collection_part_class) { Dry::View::Part }
|
||||
let(:item_part_class) { Dry::View::Part }
|
||||
|
||||
it 'returns a part wrapping the collection' do
|
||||
it "returns a part wrapping the collection" do
|
||||
expect(part).to be_a collection_part_class
|
||||
end
|
||||
|
||||
it 'wraps the collection and its items' do
|
||||
it "wraps the collection and its items" do
|
||||
expect(part._value.map(&:_value)).to eq value
|
||||
end
|
||||
|
||||
|
@ -61,70 +61,70 @@ RSpec.describe Dry::View::PartBuilder do
|
|||
end
|
||||
end
|
||||
|
||||
context 'without namespace' do
|
||||
describe 'singular value' do
|
||||
let(:value) { double('user') }
|
||||
context "without namespace" do
|
||||
describe "singular value" do
|
||||
let(:value) { double("user") }
|
||||
|
||||
it_behaves_like 'a view part'
|
||||
it_behaves_like "a view part"
|
||||
|
||||
describe 'alternative name provided via :as option' do
|
||||
let(:options) { { as: :admin_user } }
|
||||
describe "alternative name provided via :as option" do
|
||||
let(:options) { {as: :admin_user} }
|
||||
|
||||
it_behaves_like 'a view part'
|
||||
it_behaves_like "a view part"
|
||||
end
|
||||
|
||||
describe 'explicit part class provided via as: option' do
|
||||
describe "explicit part class provided via as: option" do
|
||||
before do
|
||||
Test::UserPart = Class.new(Dry::View::Part)
|
||||
end
|
||||
|
||||
let(:options) { { as: Test::UserPart } }
|
||||
let(:options) { {as: Test::UserPart} }
|
||||
|
||||
it_behaves_like 'a view part' do
|
||||
it_behaves_like "a view part" do
|
||||
let(:part_class) { Test::UserPart }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'array-like value' do
|
||||
describe "array-like value" do
|
||||
let(:name) { :users }
|
||||
let(:value) { [double(:user), double(:user)] }
|
||||
|
||||
it_behaves_like 'a view part collection'
|
||||
it_behaves_like "a view part collection"
|
||||
|
||||
describe 'alternative name provided via :as option' do
|
||||
let(:options) { { as: :admin_user } }
|
||||
describe "alternative name provided via :as option" do
|
||||
let(:options) { {as: :admin_user} }
|
||||
|
||||
it_behaves_like 'a view part collection'
|
||||
it_behaves_like "a view part collection"
|
||||
end
|
||||
|
||||
describe 'explicit part class provided via as: option' do
|
||||
describe "explicit part class provided via as: option" do
|
||||
before do
|
||||
Test::UserPart = Class.new(Dry::View::Part)
|
||||
end
|
||||
|
||||
let(:options) { { as: Test::UserPart } }
|
||||
let(:options) { {as: Test::UserPart} }
|
||||
|
||||
it_behaves_like 'a view part collection' do
|
||||
it_behaves_like "a view part collection" do
|
||||
let(:item_part_class) { Test::UserPart }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'explicit collection part class provided via as: option' do
|
||||
describe "explicit collection part class provided via as: option" do
|
||||
before do
|
||||
Test::UserCollectionPart = Class.new(Dry::View::Part)
|
||||
end
|
||||
|
||||
let(:options) { { as: [Test::UserCollectionPart] } }
|
||||
let(:options) { {as: [Test::UserCollectionPart]} }
|
||||
|
||||
it_behaves_like 'a view part collection' do
|
||||
it_behaves_like "a view part collection" do
|
||||
let(:collection_part_class) { Test::UserCollectionPart }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with namespace' do
|
||||
context "with namespace" do
|
||||
before do
|
||||
module Test
|
||||
module Parts
|
||||
|
@ -152,100 +152,100 @@ RSpec.describe Dry::View::PartBuilder do
|
|||
|
||||
let(:namespace) { Test::Parts }
|
||||
|
||||
describe 'singular value' do
|
||||
let(:value) { double('user', profile: 'profile') }
|
||||
describe "singular value" do
|
||||
let(:value) { double("user", profile: "profile") }
|
||||
|
||||
it_behaves_like 'a view part' do
|
||||
it_behaves_like "a view part" do
|
||||
let(:part_class) { Test::Parts::User }
|
||||
end
|
||||
|
||||
it 'returns decorated attributes in part classes found from the namespace' do
|
||||
it "returns decorated attributes in part classes found from the namespace" do
|
||||
expect(part.profile).to be_a Test::Parts::Profile
|
||||
end
|
||||
|
||||
describe 'alternative name provided via :as option' do
|
||||
let(:options) { { as: :admin_user } }
|
||||
describe "alternative name provided via :as option" do
|
||||
let(:options) { {as: :admin_user} }
|
||||
|
||||
it_behaves_like 'a view part' do
|
||||
it_behaves_like "a view part" do
|
||||
let(:part_class) { Test::Parts::AdminUser }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'alternative name provided via :as option, when matched constant is not a class inheriting from Dry::View::Part' do
|
||||
let(:options) { { as: :user_module } }
|
||||
describe "alternative name provided via :as option, when matched constant is not a class inheriting from Dry::View::Part" do
|
||||
let(:options) { {as: :user_module} }
|
||||
|
||||
it_behaves_like 'a view part' do
|
||||
it_behaves_like "a view part" do
|
||||
let(:part_class) { Dry::View::Part }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'explicit part class provided via as: option' do
|
||||
let(:options) { { as: Test::Parts::AdminUser } }
|
||||
describe "explicit part class provided via as: option" do
|
||||
let(:options) { {as: Test::Parts::AdminUser} }
|
||||
|
||||
it_behaves_like 'a view part' do
|
||||
it_behaves_like "a view part" do
|
||||
let(:part_class) { Test::Parts::AdminUser }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'array-like value' do
|
||||
describe "array-like value" do
|
||||
let(:name) { :users }
|
||||
let(:value) { [double(:user), double(:user)] }
|
||||
|
||||
it_behaves_like 'a view part collection' do
|
||||
it_behaves_like "a view part collection" do
|
||||
let(:collection_part_class) { Test::Parts::Users }
|
||||
let(:item_part_class) { Test::Parts::User }
|
||||
end
|
||||
|
||||
describe 'alternative element name provided via :as option' do
|
||||
let(:options) { { as: :admin_user } }
|
||||
describe "alternative element name provided via :as option" do
|
||||
let(:options) { {as: :admin_user} }
|
||||
|
||||
it_behaves_like 'a view part collection' do
|
||||
it_behaves_like "a view part collection" do
|
||||
let(:collection_part_class) { Test::Parts::Users }
|
||||
let(:item_part_class) { Test::Parts::AdminUser }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'alternative collection name provided via :as option' do
|
||||
let(:options) { { as: [:user_collection] } }
|
||||
describe "alternative collection name provided via :as option" do
|
||||
let(:options) { {as: [:user_collection]} }
|
||||
|
||||
it_behaves_like 'a view part collection' do
|
||||
it_behaves_like "a view part collection" do
|
||||
let(:collection_part_class) { Test::Parts::UserCollection }
|
||||
let(:item_part_class) { Test::Parts::User }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'alternative collection and element names provided via :as option' do
|
||||
let(:options) { { as: [:user_collection, :admin_user] } }
|
||||
describe "alternative collection and element names provided via :as option" do
|
||||
let(:options) { {as: [:user_collection, :admin_user]} }
|
||||
|
||||
it_behaves_like 'a view part collection' do
|
||||
it_behaves_like "a view part collection" do
|
||||
let(:collection_part_class) { Test::Parts::UserCollection }
|
||||
let(:item_part_class) { Test::Parts::AdminUser }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'explicit part class provided via as: option' do
|
||||
let(:options) { { as: Test::Parts::AdminUser } }
|
||||
describe "explicit part class provided via as: option" do
|
||||
let(:options) { {as: Test::Parts::AdminUser} }
|
||||
|
||||
it_behaves_like 'a view part collection' do
|
||||
it_behaves_like "a view part collection" do
|
||||
let(:collection_part_class) { Test::Parts::Users }
|
||||
let(:item_part_class) { Test::Parts::AdminUser }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'explicit collection part class provided via as: option' do
|
||||
let(:options) { { as: [Test::Parts::UserCollection] } }
|
||||
describe "explicit collection part class provided via as: option" do
|
||||
let(:options) { {as: [Test::Parts::UserCollection]} }
|
||||
|
||||
it_behaves_like 'a view part collection' do
|
||||
it_behaves_like "a view part collection" do
|
||||
let(:collection_part_class) { Test::Parts::UserCollection }
|
||||
let(:item_part_class) { Test::Parts::User }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'explicit collection and element part classes provided via :as option' do
|
||||
let(:options) { { as: [Test::Parts::UserCollection, Test::Parts::AdminUser] } }
|
||||
describe "explicit collection and element part classes provided via :as option" do
|
||||
let(:options) { {as: [Test::Parts::UserCollection, Test::Parts::AdminUser]} }
|
||||
|
||||
it_behaves_like 'a view part collection' do
|
||||
it_behaves_like "a view part collection" do
|
||||
let(:collection_part_class) { Test::Parts::UserCollection }
|
||||
let(:item_part_class) { Test::Parts::AdminUser }
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view/scope_builder'
|
||||
require 'dry/view/render_environment_missing'
|
||||
require "dry/view/scope_builder"
|
||||
require "dry/view/render_environment_missing"
|
||||
|
||||
RSpec::Matchers.define :scope do |locals|
|
||||
match do |actual|
|
||||
|
@ -18,89 +18,89 @@ RSpec.describe Dry::View::Part do
|
|||
inflector: Dry::Inflector.new,
|
||||
context: Dry::View::Context.new,
|
||||
scope_builder: Dry::View::ScopeBuilder.new,
|
||||
part_builder: Dry::View::ScopeBuilder.new,
|
||||
part_builder: Dry::View::ScopeBuilder.new
|
||||
)
|
||||
}
|
||||
let(:renderer) { spy(:renderer, format: :xml) }
|
||||
|
||||
context 'with a render environment' do
|
||||
context "with a render environment" do
|
||||
subject(:part) {
|
||||
described_class.new(
|
||||
name: name,
|
||||
value: value,
|
||||
render_env: render_env,
|
||||
render_env: render_env
|
||||
)
|
||||
}
|
||||
|
||||
describe '#render' do
|
||||
it 'renders a partial with the part available in its scope' do
|
||||
describe "#render" do
|
||||
it "renders a partial with the part available in its scope" do
|
||||
part.render(:info)
|
||||
expect(renderer).to have_received(:partial).with(:info, scope(user: part))
|
||||
end
|
||||
|
||||
it 'allows the part to be made available on a different name' do
|
||||
it "allows the part to be made available on a different name" do
|
||||
part.render(:info, as: :admin)
|
||||
expect(renderer).to have_received(:partial).with(:info, scope(admin: part))
|
||||
end
|
||||
|
||||
it 'includes extra locals in the scope' do
|
||||
part.render(:info, extra_local: 'hello')
|
||||
expect(renderer).to have_received(:partial).with(:info, scope(user: part, extra_local: 'hello'))
|
||||
it "includes extra locals in the scope" do
|
||||
part.render(:info, extra_local: "hello")
|
||||
expect(renderer).to have_received(:partial).with(:info, scope(user: part, extra_local: "hello"))
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_s' do
|
||||
describe "#to_s" do
|
||||
before do
|
||||
allow(value).to receive(:to_s).and_return 'to_s on the value'
|
||||
allow(value).to receive(:to_s).and_return "to_s on the value"
|
||||
end
|
||||
|
||||
it 'delegates to the wrapped value' do
|
||||
expect(part.to_s).to eq 'to_s on the value'
|
||||
it "delegates to the wrapped value" do
|
||||
expect(part.to_s).to eq "to_s on the value"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#new' do
|
||||
it 'preserves render environment' do
|
||||
new_part = part.new(value: 'new value')
|
||||
describe "#new" do
|
||||
it "preserves render environment" do
|
||||
new_part = part.new(value: "new value")
|
||||
expect(new_part._render_env).to be part._render_env
|
||||
end
|
||||
end
|
||||
|
||||
describe '#inspect' do
|
||||
it 'includes the clsas name, name, and value only' do
|
||||
expect(part.inspect).to eq '#<Dry::View::Part name=:user value=#<Double :value>>'
|
||||
describe "#inspect" do
|
||||
it "includes the clsas name, name, and value only" do
|
||||
expect(part.inspect).to eq "#<Dry::View::Part name=:user value=#<Double :value>>"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#_format' do
|
||||
describe "#_format" do
|
||||
it "returns the render environment's format" do
|
||||
expect(part._format).to eq :xml
|
||||
end
|
||||
end
|
||||
|
||||
describe '#method_missing' do
|
||||
let(:value) { double(greeting: 'hello from value') }
|
||||
describe "#method_missing" do
|
||||
let(:value) { double(greeting: "hello from value") }
|
||||
|
||||
it 'calls a matching method on the value' do
|
||||
expect(part.greeting).to eq 'hello from value'
|
||||
it "calls a matching method on the value" do
|
||||
expect(part.greeting).to eq "hello from value"
|
||||
end
|
||||
|
||||
it 'forwards all arguments to the method' do
|
||||
it "forwards all arguments to the method" do
|
||||
blk = -> {}
|
||||
part.greeting 'args', &blk
|
||||
part.greeting "args", &blk
|
||||
|
||||
expect(value).to have_received(:greeting).with('args', &blk)
|
||||
expect(value).to have_received(:greeting).with("args", &blk)
|
||||
end
|
||||
|
||||
it 'raises an error if no method matches' do
|
||||
it "raises an error if no method matches" do
|
||||
expect { part.farewell }.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#respond_to?' do
|
||||
let(:value) { double(greeting: 'hello from value') }
|
||||
describe "#respond_to?" do
|
||||
let(:value) { double(greeting: "hello from value") }
|
||||
|
||||
it 'handles convenience methods' do
|
||||
it "handles convenience methods" do
|
||||
expect(part).to respond_to(:format)
|
||||
expect(part).to respond_to(:context)
|
||||
expect(part).to respond_to(:render)
|
||||
|
@ -108,42 +108,42 @@ RSpec.describe Dry::View::Part do
|
|||
expect(part).to respond_to(:value)
|
||||
end
|
||||
|
||||
it 'handles value methods' do
|
||||
it "handles value methods" do
|
||||
expect(part).to respond_to(:greeting)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'without a render environment' do
|
||||
context "without a render environment" do
|
||||
subject(:part) {
|
||||
described_class.new(
|
||||
name: name,
|
||||
value: value,
|
||||
value: value
|
||||
)
|
||||
}
|
||||
|
||||
describe '#format' do
|
||||
it 'raises an error' do
|
||||
describe "#format" do
|
||||
it "raises an error" do
|
||||
expect { part.render(:info) }.to raise_error(Dry::View::RenderEnvironmentMissing::MissingEnvironmentError)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#render' do
|
||||
it 'raises an error' do
|
||||
describe "#render" do
|
||||
it "raises an error" do
|
||||
expect { part.render(:info) }.to raise_error(Dry::View::RenderEnvironmentMissing::MissingEnvironmentError)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#scope' do
|
||||
it 'raises an error' do
|
||||
describe "#scope" do
|
||||
it "raises an error" do
|
||||
expect { part.scope(:info) }.to raise_error(Dry::View::RenderEnvironmentMissing::MissingEnvironmentError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'without a name provided' do
|
||||
describe '#_name' do
|
||||
context 'when class has a name' do
|
||||
context "without a name provided" do
|
||||
describe "#_name" do
|
||||
context "when class has a name" do
|
||||
before do
|
||||
Test::MyPart = Class.new(Dry::View::Part)
|
||||
end
|
||||
|
@ -152,18 +152,18 @@ RSpec.describe Dry::View::Part do
|
|||
Test::MyPart.new(value: value)
|
||||
}
|
||||
|
||||
it 'is inferred from the class name' do
|
||||
expect(part._name).to eq 'my_part'
|
||||
it "is inferred from the class name" do
|
||||
expect(part._name).to eq "my_part"
|
||||
end
|
||||
end
|
||||
|
||||
context 'when class is anonymous' do
|
||||
context "when class is anonymous" do
|
||||
subject(:part) {
|
||||
Class.new(Dry::View::Part).new(value: value)
|
||||
}
|
||||
|
||||
it "defaults to 'part'" do
|
||||
expect(part._name).to eq 'part'
|
||||
expect(part._name).to eq "part"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view/render_environment'
|
||||
require "dry/view/render_environment"
|
||||
|
||||
require 'dry/inflector'
|
||||
require 'dry/view/context'
|
||||
require 'dry/view/part_builder'
|
||||
require 'dry/view/scope_builder'
|
||||
require "dry/inflector"
|
||||
require "dry/view/context"
|
||||
require "dry/view/part_builder"
|
||||
require "dry/view/scope_builder"
|
||||
|
||||
RSpec.describe Dry::View::RenderEnvironment do
|
||||
subject(:render_env) { described_class.new(**options) }
|
||||
|
@ -16,18 +16,18 @@ RSpec.describe Dry::View::RenderEnvironment do
|
|||
renderer: Dry::View::Renderer.new([Dry::View::Path.new(FIXTURES_PATH)], format: :html),
|
||||
context: Dry::View::Context.new,
|
||||
part_builder: Dry::View::PartBuilder.new,
|
||||
scope_builder: Dry::View::ScopeBuilder.new,
|
||||
scope_builder: Dry::View::ScopeBuilder.new
|
||||
}
|
||||
}
|
||||
|
||||
describe '#format' do
|
||||
describe "#format" do
|
||||
it "returns the renderer's format" do
|
||||
expect(render_env.format).to eq :html
|
||||
end
|
||||
end
|
||||
|
||||
describe '#==' do
|
||||
it 'is equal when its options are equal' do
|
||||
describe "#==" do
|
||||
it "is equal when its options are equal" do
|
||||
expect(render_env).to eq described_class.new(**options)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view/rendered'
|
||||
require "dry/view/rendered"
|
||||
|
||||
RSpec.describe Dry::View::Rendered do
|
||||
subject(:rendered) {
|
||||
described_class.new(
|
||||
output: 'rendered template output',
|
||||
output: "rendered template output",
|
||||
locals: {
|
||||
user: { name: 'Jane' },
|
||||
},
|
||||
user: {name: "Jane"}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
describe '#to_s' do
|
||||
it 'returns the rendered output' do
|
||||
expect(rendered.to_s).to eq 'rendered template output'
|
||||
describe "#to_s" do
|
||||
it "returns the rendered output" do
|
||||
expect(rendered.to_s).to eq "rendered template output"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_str' do
|
||||
it 'returns the rendered output' do
|
||||
expect(rendered.to_str).to eq 'rendered template output'
|
||||
describe "#to_str" do
|
||||
it "returns the rendered output" do
|
||||
expect(rendered.to_str).to eq "rendered template output"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#locals' do
|
||||
it 'returns the locals hash' do
|
||||
expect(rendered.locals).to eql({ user: { name: 'Jane' } })
|
||||
describe "#locals" do
|
||||
it "returns the locals hash" do
|
||||
expect(rendered.locals).to eql(user: {name: "Jane"})
|
||||
end
|
||||
end
|
||||
|
||||
describe '#[]' do
|
||||
it 'returns the named local' do
|
||||
expect(rendered[:user]).to eql(name: 'Jane')
|
||||
describe "#[]" do
|
||||
it "returns the named local" do
|
||||
expect(rendered[:user]).to eql(name: "Jane")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,68 +1,68 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view/path'
|
||||
require 'dry/view/renderer'
|
||||
require "dry/view/path"
|
||||
require "dry/view/renderer"
|
||||
|
||||
RSpec.describe Dry::View::Renderer do
|
||||
subject(:renderer) do
|
||||
Dry::View::Renderer.new(
|
||||
[Dry::View::Path.new(SPEC_ROOT.join('fixtures/templates'))],
|
||||
format: 'html',
|
||||
default_encoding: 'utf-8'
|
||||
[Dry::View::Path.new(SPEC_ROOT.join("fixtures/templates"))],
|
||||
format: "html",
|
||||
default_encoding: "utf-8"
|
||||
)
|
||||
end
|
||||
|
||||
let(:scope) { double(:scope) }
|
||||
|
||||
describe '#template' do
|
||||
it 'renders template in current directory' do
|
||||
expect(renderer.template(:hello, scope)).to eql('<h1>Hello</h1>')
|
||||
describe "#template" do
|
||||
it "renders template in current directory" do
|
||||
expect(renderer.template(:hello, scope)).to eql("<h1>Hello</h1>")
|
||||
end
|
||||
|
||||
it 'does not include `shared/` subdirectory under root when looking up templates' do
|
||||
it "does not include `shared/` subdirectory under root when looking up templates" do
|
||||
expect {
|
||||
renderer.template(:_shared_hello, scope)
|
||||
}.to raise_error(Dry::View::TemplateNotFoundError, /_shared_hello/)
|
||||
end
|
||||
|
||||
it 'raises error when template cannot be found' do
|
||||
it "raises error when template cannot be found" do
|
||||
expect {
|
||||
renderer.template(:missing_template, scope)
|
||||
}.to raise_error(Dry::View::TemplateNotFoundError, /missing_template/)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#partial' do
|
||||
it 'renders partial in current directory' do
|
||||
expect(renderer.partial(:hello, scope)).to eql('<h1>Partial hello</h1>')
|
||||
describe "#partial" do
|
||||
it "renders partial in current directory" do
|
||||
expect(renderer.partial(:hello, scope)).to eql("<h1>Partial hello</h1>")
|
||||
end
|
||||
|
||||
it 'renders partial in shared/ subdirectory under root' do
|
||||
expect(renderer.chdir('hello').partial(:shared_hello, scope)).to eql('<h1>Hello</h1>')
|
||||
it "renders partial in shared/ subdirectory under root" do
|
||||
expect(renderer.chdir("hello").partial(:shared_hello, scope)).to eql("<h1>Hello</h1>")
|
||||
end
|
||||
|
||||
it 'renders partial in shared/ subdirectory when descending from an upper directory' do
|
||||
expect(renderer.chdir('hello').partial(:shared_hello, scope)).to eql('<h1>Hello</h1>')
|
||||
it "renders partial in shared/ subdirectory when descending from an upper directory" do
|
||||
expect(renderer.chdir("hello").partial(:shared_hello, scope)).to eql("<h1>Hello</h1>")
|
||||
end
|
||||
|
||||
it 'renders partial in upper directory' do
|
||||
expect(renderer.chdir('nested').partial(:hello, scope)).to eql('<h1>Partial hello</h1>')
|
||||
it "renders partial in upper directory" do
|
||||
expect(renderer.chdir("nested").partial(:hello, scope)).to eql("<h1>Partial hello</h1>")
|
||||
end
|
||||
|
||||
it 'renders partial in upper shared/ subdirectory' do
|
||||
expect(renderer.chdir('nested').partial(:shared_hello, scope)).to eql('<h1>Hello</h1>')
|
||||
it "renders partial in upper shared/ subdirectory" do
|
||||
expect(renderer.chdir("nested").partial(:shared_hello, scope)).to eql("<h1>Hello</h1>")
|
||||
end
|
||||
|
||||
it 'raises error when partial cannot be found' do
|
||||
it "raises error when partial cannot be found" do
|
||||
expect {
|
||||
renderer.partial(:missing_partial, scope)
|
||||
}.to raise_error(Dry::View::TemplateNotFoundError, /_missing_partial/)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#chdir' do
|
||||
it 'copies options to new renderer instance' do
|
||||
expect(renderer.chdir('nested').options).to eq(default_encoding: 'utf-8')
|
||||
describe "#chdir" do
|
||||
it "copies options to new renderer instance" do
|
||||
expect(renderer.chdir("nested").options).to eq(default_encoding: "utf-8")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,113 +1,113 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'dry/view/scope_builder'
|
||||
require "dry/view/scope_builder"
|
||||
|
||||
RSpec.describe Dry::View::Scope do
|
||||
let(:locals) { {} }
|
||||
|
||||
context 'with a render environment' do
|
||||
context "with a render environment" do
|
||||
subject(:scope) {
|
||||
described_class.new(
|
||||
locals: locals,
|
||||
render_env: render_env,
|
||||
render_env: render_env
|
||||
)
|
||||
}
|
||||
|
||||
let(:render_env) { spy(:render_env, format: :xml, context: context) }
|
||||
let(:context) { double(:context) }
|
||||
|
||||
describe '#render' do
|
||||
it 'renders a partial with itself as the scope' do
|
||||
describe "#render" do
|
||||
it "renders a partial with itself as the scope" do
|
||||
scope.render(:info)
|
||||
expect(render_env).to have_received(:partial).with(:info, scope)
|
||||
end
|
||||
|
||||
it 'renders a partial with provided locals' do
|
||||
it "renders a partial with provided locals" do
|
||||
scope_with_locals = described_class.new(
|
||||
locals: { foo: 'bar' },
|
||||
render_env: render_env,
|
||||
locals: {foo: "bar"},
|
||||
render_env: render_env
|
||||
)
|
||||
|
||||
scope.render(:info, foo: 'bar')
|
||||
scope.render(:info, foo: "bar")
|
||||
|
||||
expect(render_env).to have_received(:partial).with(:info, scope_with_locals)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#_format' do
|
||||
describe "#_format" do
|
||||
it "returns the render environments's format" do
|
||||
expect(scope._format).to eq :xml
|
||||
end
|
||||
end
|
||||
|
||||
describe '#_context' do
|
||||
describe "#_context" do
|
||||
it "returns the render environment's context" do
|
||||
expect(scope._context).to be context
|
||||
end
|
||||
end
|
||||
|
||||
describe '#method_missing' do
|
||||
describe 'matching locals' do
|
||||
let(:locals) { { greeting: 'hello from locals' } }
|
||||
let(:context) { double(:context, greeting: 'hello from context') }
|
||||
describe "#method_missing" do
|
||||
describe "matching locals" do
|
||||
let(:locals) { {greeting: "hello from locals"} }
|
||||
let(:context) { double(:context, greeting: "hello from context") }
|
||||
|
||||
it 'returns a matching value from the locals, in favour of a matching method on the context' do
|
||||
expect(scope.greeting).to eq 'hello from locals'
|
||||
it "returns a matching value from the locals, in favour of a matching method on the context" do
|
||||
expect(scope.greeting).to eq "hello from locals"
|
||||
end
|
||||
end
|
||||
|
||||
describe 'matching context' do
|
||||
let(:context) { double(:context, greeting: 'hello from context') }
|
||||
describe "matching context" do
|
||||
let(:context) { double(:context, greeting: "hello from context") }
|
||||
|
||||
it 'calls the matching method on the context' do
|
||||
expect(scope.greeting).to eq 'hello from context'
|
||||
it "calls the matching method on the context" do
|
||||
expect(scope.greeting).to eq "hello from context"
|
||||
end
|
||||
|
||||
it 'forwards all arguments to the method' do
|
||||
it "forwards all arguments to the method" do
|
||||
blk = -> {}
|
||||
scope.greeting 'args', &blk
|
||||
scope.greeting "args", &blk
|
||||
|
||||
expect(context).to have_received(:greeting).with('args', &blk)
|
||||
expect(context).to have_received(:greeting).with("args", &blk)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'matching convenience methods' do
|
||||
it 'provides #context' do
|
||||
describe "matching convenience methods" do
|
||||
it "provides #context" do
|
||||
expect(scope.context).to be context
|
||||
end
|
||||
|
||||
it 'provides #locals' do
|
||||
it "provides #locals" do
|
||||
expect(scope.locals).to be locals
|
||||
end
|
||||
end
|
||||
|
||||
describe 'no matches' do
|
||||
it 'raises an error' do
|
||||
describe "no matches" do
|
||||
it "raises an error" do
|
||||
expect { scope.greeting }.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'without a render environment' do
|
||||
context "without a render environment" do
|
||||
subject(:scope) {
|
||||
described_class.new(locals: locals)
|
||||
}
|
||||
|
||||
describe '#render' do
|
||||
it 'raises an error' do
|
||||
describe "#render" do
|
||||
it "raises an error" do
|
||||
expect { scope.render(:info) }.to raise_error(Dry::View::RenderEnvironmentMissing::MissingEnvironmentError)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#scope' do
|
||||
it 'raises an error' do
|
||||
describe "#scope" do
|
||||
it "raises an error" do
|
||||
expect { scope.scope(:info) }.to raise_error(Dry::View::RenderEnvironmentMissing::MissingEnvironmentError)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#_context' do
|
||||
it 'raises an error' do
|
||||
describe "#_context" do
|
||||
it "raises an error" do
|
||||
expect { scope._context }.to raise_error(Dry::View::RenderEnvironmentMissing::MissingEnvironmentError)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'tilt/erubi'
|
||||
require "tilt/erubi"
|
||||
|
||||
RSpec.describe Dry::View do
|
||||
subject(:view) {
|
||||
Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.layout = 'app'
|
||||
config.template = 'user'
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.layout = "app"
|
||||
config.template = "user"
|
||||
|
||||
expose :user do
|
||||
{ name: 'Jane' }
|
||||
{name: "Jane"}
|
||||
end
|
||||
|
||||
expose :header do
|
||||
{ title: 'User' }
|
||||
{title: "User"}
|
||||
end
|
||||
end.new
|
||||
}
|
||||
|
@ -22,26 +22,26 @@ RSpec.describe Dry::View do
|
|||
let(:context) do
|
||||
Class.new(Dry::View::Context) do
|
||||
def title
|
||||
'Test'
|
||||
"Test"
|
||||
end
|
||||
end.new
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
it 'renders template within the layout' do
|
||||
describe "#call" do
|
||||
it "renders template within the layout" do
|
||||
expect(view.(context: context).to_s).to eql(
|
||||
'<!DOCTYPE html><html><head><title>Test</title></head><body><h1>User</h1><p>Jane</p></body></html>'
|
||||
"<!DOCTYPE html><html><head><title>Test</title></head><body><h1>User</h1><p>Jane</p></body></html>"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'renderer options' do
|
||||
describe "renderer options" do
|
||||
subject(:view) {
|
||||
Class.new(Dry::View) do
|
||||
config.paths = SPEC_ROOT.join('fixtures/templates')
|
||||
config.template = 'view_renderer_options'
|
||||
config.renderer_engine_mapping = { erb: Tilt::ErubiTemplate }
|
||||
config.renderer_options = { outvar: '@__buf__' }
|
||||
config.paths = SPEC_ROOT.join("fixtures/templates")
|
||||
config.template = "view_renderer_options"
|
||||
config.renderer_engine_mapping = {erb: Tilt::ErubiTemplate}
|
||||
config.renderer_options = {outvar: "@__buf__"}
|
||||
end.new
|
||||
}
|
||||
|
||||
|
@ -49,11 +49,11 @@ RSpec.describe Dry::View do
|
|||
module Test
|
||||
class Form
|
||||
def initialize(action, &block)
|
||||
@buf = eval('@__buf__', block.binding)
|
||||
@buf = eval("@__buf__", block.binding, __FILE__, __LINE__)
|
||||
|
||||
@buf << "<form action=\"#{action}\" method=\"post\">"
|
||||
block.(self)
|
||||
@buf << '</form>'
|
||||
@buf << "</form>"
|
||||
end
|
||||
|
||||
def text(name)
|
||||
|
@ -71,13 +71,13 @@ RSpec.describe Dry::View do
|
|||
end.new
|
||||
}
|
||||
|
||||
it 'merges configured options with default encoding' do
|
||||
expect(view.class.config.renderer_options[:outvar]).to eq '@__buf__'
|
||||
expect(view.class.config.renderer_options[:default_encoding]).to eq 'utf-8'
|
||||
it "merges configured options with default encoding" do
|
||||
expect(view.class.config.renderer_options[:outvar]).to eq "@__buf__"
|
||||
expect(view.class.config.renderer_options[:default_encoding]).to eq "utf-8"
|
||||
end
|
||||
|
||||
it 'are passed to renderer' do
|
||||
expect(view.(context: context).to_s.gsub(/\n\s*/m, '')).to eq(
|
||||
it "are passed to renderer" do
|
||||
expect(view.(context: context).to_s.gsub(/\n\s*/m, "")).to eq(
|
||||
'<form action="/people" method="post"><input type="text" name="name" /></form>'
|
||||
)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue