Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -28,12 +28,16 @@ jobs:
- "3.0"
- "2.7"
- "2.6"
dummy:
- "with-engine"
- "without-engine"
include:
- ruby: "3.0"
coverage: "true"
env:
COVERAGE: ${{matrix.coverage}}
COVERAGE_TOKEN: ${{secrets.CODACY_PROJECT_TOKEN}}
TEST_DUMMY: ${{matrix.dummy}}
steps:
- name: Checkout
uses: actions/checkout@v1
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ end

group :test do
gem "rspec-rails"
gem "super_engine", path: "spec/dummies/with-engine/dummy/engines/super_engine", require: false
end

group :tools do
3 changes: 3 additions & 0 deletions dry-rails.gemspec
Original file line number Diff line number Diff line change
@@ -36,4 +36,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "bundler"
spec.add_development_dependency "rake"
spec.add_development_dependency "rspec"

# our super engine used in specs
spec.add_development_dependency "super_engine"
end
27 changes: 16 additions & 11 deletions lib/dry/rails.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

require "dry/rails/railtie"
require "dry/rails/engine"
require "dry/rails/finalizer"
require "dry/rails/container"
require "dry/rails/components"

@@ -20,14 +22,24 @@ module Dry
#
# @api public
module Rails
extend Configurable
# Set to true to turn off dry-system for main application
# Meant to be used in setup where dry-system is only used within Rails::Engine(s)
#
# @api public
setting :main_app_disabled, default: false

# This is being injected by main app Railtie
# @api private
setting :main_app_name

# Set container block that will be evaluated in the context of the container
#
# @return [self]
#
# @api public
def self.container(&block)
_container_blocks << block
self
Engine.container(config.main_app_name, &block)
end

# Create a new container class
@@ -40,19 +52,12 @@ def self.container(&block)
#
# @api private
def self.create_container(options = {})
Class.new(Container) { config.update(options) }
Engine.create_container(options)
end

# @api private
def self.evaluate_initializer(container)
_container_blocks.each do |block|
container.class_eval(&block)
end
end

# @api private
def self._container_blocks
@_container_blocks ||= []
Engine.evaluate_initializer(config.main_app_name, container)
end
end
end
2 changes: 1 addition & 1 deletion lib/dry/rails/auto_registrars/app.rb
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ def relative_path(dir, file_path)
path = super
return path unless dir.start_with?("app")

path.split("/")[1..-1].join("/")
path.split("/")[1..].join("/")
end
end
end
7 changes: 5 additions & 2 deletions lib/dry/rails/boot/controller_helpers.rb
Original file line number Diff line number Diff line change
@@ -6,9 +6,12 @@
end

start do
ApplicationController.include(Dry::Rails::Features::ControllerHelpers)
unless ApplicationController.include?(Dry::Rails::Features::ControllerHelpers)
ApplicationController.include(Dry::Rails::Features::ControllerHelpers)
end

if defined?(ActionController::API)
if defined?(ActionController::API) &&
!ActionController::API.include?(Dry::Rails::Features::ControllerHelpers)
ActionController::API.include(Dry::Rails::Features::ControllerHelpers)
end
end
7 changes: 5 additions & 2 deletions lib/dry/rails/boot/safe_params.rb
Original file line number Diff line number Diff line change
@@ -6,9 +6,12 @@
end

start do
ApplicationController.include(Dry::Rails::Features::SafeParams)
unless ActionController::Base.include?(Dry::Rails::Features::SafeParams)
ActionController::Base.include(Dry::Rails::Features::SafeParams)
end

if defined?(ActionController::API)
if defined?(ActionController::API) &&
!ActionController::API.include?(Dry::Rails::Features::SafeParams)
ActionController::API.include(Dry::Rails::Features::SafeParams)
end
end
44 changes: 44 additions & 0 deletions lib/dry/rails/engine.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

module Dry
module Rails
module Engine
# Set container block that will be evaluated in the context of the container
#
# @param name [Symbol]
# @return [self]
#
# @api public
def self.container(name, &block)
_container_blocks[name] << block
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit puzzling tbh, when I do: Dry::Rails::Engine.container(...) { do something with container } it's not available until reload! call Finalizer and evaluates the config again 🤔 ("worked like that before")

would the same happen if container is used eg. in before_filter - changes done to container would "leak" into next request? this doesn't sound right... 😅

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zlw setting up container should only be available during app's booting phase. Once it's done, we should literally freeze its config (which I believe already happens?)

self
end

# Create a new container class
#
# This is used during booting and reloading
#
# @param name [Symbol]
# @param options [Hash] Container configuration settings
#
# @return [Class]
#
# @api private
def self.create_container(options = {})
Class.new(Container) { config.update(options) }
end

# @api private
def self.evaluate_initializer(name, container)
_container_blocks[name].each do |block|
container.class_eval(&block)
end
end

# @api private
def self._container_blocks
@_container_blocks ||= Hash.new { |h, k| h[k] = [] }
end
end
end
end
172 changes: 172 additions & 0 deletions lib/dry/rails/finalizer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# frozen_string_literal: true

module Dry
module Rails
class Finalizer
def self.app_namespace_to_name(app_namespace)
app_namespace.name.underscore.to_sym
end

# rubocop:disable Metrics/ParameterLists
def initialize(
railtie:,
app_namespace:,
root_path:,
name: Dry::Rails.config.main_app_name,
container_const_name: Dry::Rails::Container.container_constant,
default_inflector: ActiveSupport::Inflector
)
@railtie = railtie
@app_namespace = app_namespace
@root_path = root_path
@name = name
@container_const_name = container_const_name
@default_inflector = default_inflector
end
# rubocop:enable Metrics/ParameterLists

attr_reader :railtie,
:root_path,
:container_const_name

# Infer the default application namespace
#
# TODO: we had to rename namespace=>app_namespace because
# Rake::DSL's Kernel#namespace *sometimes* breaks things.
# Currently we are missing specs verifying that rake tasks work
# correctly and those must be added!
#
# @return [Module]
#
# @api public
attr_reader :app_namespace

# Code-reloading-aware finalization process
#
# This sets up `Container` and `Deps` constants, reloads them if this is in reloading mode,
# and registers default components like the railtie itself or the inflector
#
# @api public
#
# rubocop:disable Metrics/AbcSize
def finalize!
stop_features if reloading?

container = Dry::Rails::Engine.create_container(
root: root_path,
inflector: default_inflector,
system_dir: root_path.join("config/system"),
bootable_dirs: [root_path.join("config/system/boot")]
)

# Enable :env plugin by default because it is a very common requirement
container.use :env, inferrer: -> { ::Rails.env }

container.register(:railtie, railtie)
container.register(:inflector, default_inflector)

# Remove previously defined constants, if any, so we don't end up with
# unsused constants in app's namespace when a name change happens.
remove_constant(container.auto_inject_constant)
remove_constant(container.container_constant)

Dry::Rails::Engine.evaluate_initializer(name, container)

@container_const_name = container.container_constant

set_or_reload(container.container_constant, container)
set_or_reload(container.auto_inject_constant, container.injector)

container.features.each do |feature|
container.boot(feature, from: :rails)
end

container.refresh_boot_files if reloading?

container.finalize!(freeze: !::Rails.env.test?)
end
# rubocop:enable Metrics/AbcSize

# Stops all configured features (bootable components)
#
# This is *crucial* when reloading code in development mode. Every bootable component
# should be able to clear the runtime from any constants that it created in its `stop`
# lifecycle step
#
# @api public
def stop_features
container.features.each do |feature|
container.stop(feature) if container.booted?(feature)
end
end

# Exposes the container constant
#
# @return [Dry::Rails::Container]
#
# @api public
def container
app_namespace.const_get(container_const_name, false)
end

# Return true if we're in code-reloading mode
#
# @api private
def reloading?
app_namespace.const_defined?(container_const_name, false)
end

# Return the default system name
#
# In the dry-system world containers are explicitly named using symbols, so that you can
# refer to them easily when ie importing one container into another
#
# @return [Symbol]
#
# @api private
attr_reader :name

# Sets or reloads a constant within the application namespace
#
# @api private
attr_reader :default_inflector

# @api private
def set_or_reload(const_name, const)
remove_constant(const_name)
app_namespace.const_set(const_name, const)
end

# @api private
def remove_constant(const_name)
if app_namespace.const_defined?(const_name, false)
app_namespace.__send__(:remove_const, const_name)
end
end
end

module Engine
class Finalizer
# rubocop:disable Metrics/ParameterLists
def self.new(
railtie:,
app_namespace:,
root_path:,
name: nil,
container_const_name: Dry::Rails::Container.container_constant,
default_inflector: ActiveSupport::Inflector
)
Dry::Rails::Finalizer.new(
railtie: railtie,
app_namespace: app_namespace,
root_path: root_path,
name: name || ::Dry::Rails::Finalizer.app_namespace_to_name(app_namespace),
container_const_name: container_const_name,
default_inflector: default_inflector
)
end
# rubocop:enable Metrics/ParameterLists
end
end
end
end
137 changes: 34 additions & 103 deletions lib/dry/rails/railtie.rb
Original file line number Diff line number Diff line change
@@ -8,12 +8,31 @@ module Rails
#
# @api public
class Railtie < ::Rails::Railtie
attr_reader :container_const_name

# This is needed because `finalize!` can reload code and this hook is called every-time
# in development env upon a request (in production it's called just once during booting)
config.to_prepare do
Railtie.finalize!
Railtie.finalize! unless Dry::Rails.config.main_app_disabled
end

initializer "dry-rails.main-app-container" do
Dry::Rails.config.main_app_name = Dry::Rails::Finalizer.app_namespace_to_name(app_namespace)
end

# Infer the default application namespace
#
# TODO: we had to rename namespace=>app_namespace because
# Rake::DSL's Kernel#namespace *sometimes* breaks things.
# Currently we are missing specs verifying that rake tasks work
# correctly and those must be added!
#
# @return [Module]
#
# @api public
def app_namespace
@app_namespace ||= begin
top_level_namespace = ::Rails.application.class.to_s.split("::").first
Object.const_get(top_level_namespace)
end
end

# Code-reloading-aware finalization process
@@ -22,49 +41,7 @@ class Railtie < ::Rails::Railtie
# and registers default components like the railtie itself or the inflector
#
# @api public
#
# rubocop:disable Metrics/AbcSize
def finalize!
@container_const_name ||= Dry::Rails::Container.container_constant

stop_features if reloading?

root_path = ::Rails.root

container = Dry::Rails.create_container(
root: root_path,
inflector: default_inflector,
system_dir: root_path.join("config/system"),
bootable_dirs: [root_path.join("config/system/boot")]
)

# Enable :env plugin by default because it is a very common requirement
container.use :env, inferrer: -> { ::Rails.env }

container.register(:railtie, self)
container.register(:inflector, default_inflector)

# Remove previously defined constants, if any, so we don't end up with
# unsused constants in app's namespace when a name change happens.
remove_constant(container.auto_inject_constant)
remove_constant(container.container_constant)

Dry::Rails.evaluate_initializer(container)

@container_const_name = container.container_constant

set_or_reload(container.container_constant, container)
set_or_reload(container.auto_inject_constant, container.injector)

container.features.each do |feature|
container.boot(feature, from: :rails)
end

container.refresh_boot_files if reloading?

container.finalize!(freeze: !::Rails.env.test?)
end
# rubocop:enable Metrics/AbcSize
delegate :finalize!, to: :finalizer
alias_method :reload, :finalize!

# Stops all configured features (bootable components)
@@ -74,75 +51,29 @@ def finalize!
# lifecycle step
#
# @api public
def stop_features
container.features.each do |feature|
container.stop(feature) if container.booted?(feature)
end
end
delegate :stop_features, to: :finalizer

# Exposes the container constant
#
# @return [Dry::Rails::Container]
#
# @api public
def container
app_namespace.const_get(container_const_name, false)
end
delegate :container, to: :finalizer

# Return true if we're in code-reloading mode
#
# @api private
def reloading?
app_namespace.const_defined?(container_const_name, false)
end
delegate :set_or_reload, to: :finalizer

# Return the default system name
#
# In the dry-system world containers are explicitly named using symbols, so that you can
# refer to them easily when ie importing one container into another
#
# @return [Symbol]
#
# @api private
def name
app_namespace.name.underscore.to_sym
end
delegate :remove_constant, to: :finalizer

# Infer the default application namespace
#
# TODO: we had to rename namespace=>app_namespace because
# Rake::DSL's Kernel#namespace *sometimes* breaks things.
# Currently we are missing specs verifying that rake tasks work
# correctly and those must be added!
#
# @return [Module]
#
# @api public
def app_namespace
@app_namespace ||= begin
top_level_namespace = ::Rails.application.class.to_s.split("::").first
Object.const_get(top_level_namespace)
end
end
private

# Sets or reloads a constant within the application namespace
#
# @api private
def default_inflector
ActiveSupport::Inflector
end

# @api private
def set_or_reload(const_name, const)
remove_constant(const_name)
app_namespace.const_set(const_name, const)
end

# @api private
def remove_constant(const_name)
if app_namespace.const_defined?(const_name, false)
app_namespace.__send__(:remove_const, const_name)
end
def finalizer
@finalizer ||= Finalizer.new(
railtie: self,
app_namespace: app_namespace,
root_path: ::Rails.root
)
end
end
end
File renamed without changes.
9 changes: 9 additions & 0 deletions spec/dummies/with-engine/dummy-5.x/dummy/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

source "https://rubygems.org"

gem "actionpack"
gem "dry-rails", path: "../../../.."
gem "listen"
gem "railties"
gem "super_engine", path: "engines/super_engine"
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

# Load the Rails application.
require_relative "application"
require "super_engine"

# Initialize the Rails application.
Rails.application.initialize!
Original file line number Diff line number Diff line change
@@ -59,7 +59,7 @@
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')

if ENV["RAILS_LOG_TO_STDOUT"].present?
logger = ActiveSupport::Logger.new(STDOUT)
logger = ActiveSupport::Logger.new($stdout)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions spec/dummies/with-engine/dummy-5.x/dummy/engines
File renamed without changes.
File renamed without changes.
33 changes: 33 additions & 0 deletions spec/dummies/with-engine/dummy-6.x/dummy/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby "2.6.5"

gem "dry-rails", path: "../../../../.."
gem "super_engine", path: "engines/super_engine"

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem "rails", "~> 6.0.2", ">= 6.0.2.1"
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem "jbuilder", "~> 2.7"
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem "byebug", platforms: %i[mri mingw x64_mingw]
end

group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem "listen", ">= 3.0.5", "< 3.2"
gem "web-console", ">= 3.3.0"
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem "spring"
gem "spring-watcher-listen", "~> 2.0.0"
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw jruby]
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

# Load the Rails application.
require_relative "application"
require "super_engine"

# Initialize the Rails application.
Rails.application.initialize!
Original file line number Diff line number Diff line change
@@ -63,7 +63,7 @@
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')

if ENV["RAILS_LOG_TO_STDOUT"].present?
logger = ActiveSupport::Logger.new(STDOUT)
logger = ActiveSupport::Logger.new($stdout)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions spec/dummies/with-engine/dummy-6.x/dummy/engines
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -13,6 +13,5 @@ class ApiSafeParamsCallbacksController < ActionController::API
required(:id).value(:integer)
end

def show
end
def show; end
end
Original file line number Diff line number Diff line change
@@ -13,6 +13,5 @@ class SafeParamsCallbacksController < ApplicationController
required(:id).value(:integer)
end

def show
end
def show; end
end
File renamed without changes.
3 changes: 3 additions & 0 deletions spec/dummies/with-engine/dummy/app/models/container.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

class Container; end
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
15 changes: 15 additions & 0 deletions spec/dummies/with-engine/dummy/config/routes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

Rails.application.routes.draw do
mount SuperEngine::Engine, at: "super_engine"

get "users/show/:id" => "users#show"
get "users/new/:id" => "users#new"

get "safe_params_callbacks/show/:id" => "safe_params_callbacks#show"

get "/api/users/show/:id" => "api_users#show"
get "/api/users/new/:id" => "api_users#new"

get "/api/safe_params_callbacks/show/:id" => "api_safe_params_callbacks#show"
end
18 changes: 18 additions & 0 deletions spec/dummies/with-engine/dummy/engines/super_engine/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

source "https://rubygems.org"

# Declare your gem's dependencies in example_engine.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gemspec

gem "dry-rails", path: "../../../../../.."

# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.

# To use a debugger
# gem 'byebug', group: [:development, :test]
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

module SuperEngine
class ApiBooksController < ActionController::API
schema(:show) do
required(:id).value(:integer)
end

schema(:new) do
required(:id).value(:integer)
end

def show
if safe_params.success?
render json: {id: safe_params[:id], name: "Harry Potter"}
else
render json: {errors: safe_params.errors.to_h}
end
end

def new
if safe_params.success?
render json: {id: safe_params[:id], name: "Harry Potter"}
else
render json: {errors: safe_params.errors.to_h}
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module SuperEngine
class ApiSafeParamsCallbacksController < ActionController::API
before_action do
if safe_params&.failure?
head 422
else
head 200
end
end

schema(:show) do
required(:id).value(:integer)
end

def show; end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module SuperEngine
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

module SuperEngine
class BooksController < ApplicationController
schema(:show) do
required(:id).value(:integer)
end

schema(:new) do
required(:id).value(:integer)
end

def show
if safe_params.success?
render json: {id: safe_params[:id], name: "Harry Potter"}
else
render json: {errors: safe_params.errors.to_h}
end
end

def new
if safe_params.success?
render json: {id: safe_params[:id], name: "Harry Potter"}
else
render json: {errors: safe_params.errors.to_h}
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module SuperEngine
class SafeParamsCallbacksController < ApplicationController
before_action do
if safe_params&.failure?
head 422
else
head 200
end
end

schema(:show) do
required(:id).value(:integer)
end

def show; end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

module SuperEngine
class CreateBookForm
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

module SuperEngine
module Books
class Create
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

SuperEngine::Engine.routes.draw do
get "books/show/:id" => "books#show"
get "books/new/:id" => "books#new"

get "safe_params_callbacks/show/:id" => "safe_params_callbacks#show"

get "/api/books/show/:id" => "api_books#show"
get "/api/books/new/:id" => "api_books#new"

get "/api/safe_params_callbacks/show/:id" => "api_safe_params_callbacks#show"
end
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

require "super_engine/engine"

module SuperEngine
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

require "dry-rails"

module SuperEngine
class Engine < ::Rails::Engine
isolate_namespace SuperEngine

initializer "super_engine.dry-container" do |_app|
Dry::Rails::Engine.container(:super_engine) do
config.component_dirs.add "app/operations"
end
end

# This is needed because `finalize!` can reload code and this hook is called every-time
# in development env upon a request (in production it's called just once during booting)
config.to_prepare do
Engine.finalize!
end

# Code-reloading-aware finalization process
#
# This sets up `Container` and `Deps` constants, reloads them if this is in reloading mode,
# and registers default components like the railtie itself or the inflector
#
# @api public
#
delegate :finalize!, to: :finalizer
alias_method :reload, :finalize!

# Stops all configured features (bootable components)
#
# This is *crucial* when reloading code in development mode. Every bootable component
# should be able to clear the runtime from any constants that it created in its `stop`
# lifecycle step
#
# @api public
delegate :stop_features, to: :finalizer

# Exposes the container constant
#
# @return [Dry::Rails::Container]
#
# @api public
delegate :container, to: :finalizer

# @api private
delegate :set_or_reload, to: :finalizer

# @api private
delegate :remove_constant, to: :finalizer

private

def finalizer
@finalizer ||= Dry::Rails::Engine::Finalizer.new(
railtie: self,
app_namespace: SuperEngine,
root_path: ::Rails.root.join("engines/super_engine")
)
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

module SuperEngine
VERSION = "0.0.1"
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

$LOAD_PATH.push File.expand_path("lib", __dir__)
unless defined? RAILS_VERSION
RAILS_VERSION = ENV["RAILS_VERSION"] || "6.x"
end

# Maintain your gem's version:
require "super_engine/version"

# Describe your gem and declare its dependencies:
Gem::Specification.new do |spec|
spec.name = "super_engine"
spec.version = SuperEngine::VERSION
spec.authors = ["Krzysztof Zalewski"]
spec.email = ["zlw.zalewski@gmail.com"]
spec.homepage = ""
spec.summary = ""
spec.description = ""
spec.required_ruby_version = ">= 2.6.0"
spec.metadata["rubygems_mfa_required"] = "true"

spec.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]

spec.add_dependency "actionpack", "~> 6.0.2", ">= 6.0.2.1"
spec.add_dependency "dry-rails"
end
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions spec/dummies/without-engine/dummy-5.x/dummy/.rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--color
File renamed without changes.
1 change: 1 addition & 0 deletions spec/dummies/without-engine/dummy-5.x/dummy/app
14 changes: 14 additions & 0 deletions spec/dummies/without-engine/dummy-5.x/dummy/config/application.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

require_relative "boot"

require "rails"
require "action_controller/railtie"

Bundler.setup(*Rails.groups)

module Dummy
class Application < Rails::Application
config.root = Pathname(__dir__).join("..").realpath
end
end
5 changes: 5 additions & 0 deletions spec/dummies/without-engine/dummy-5.x/dummy/config/boot.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)

require "bundler/setup" # Set up gems listed in the Gemfile.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false

# Do not eager load code on boot.
config.eager_load = false

# Show full error reports.
config.consider_all_requests_local = true

# Enable/disable caching. By default caching is disabled.
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=172800"
}
else
config.action_controller.perform_caching = false

config.cache_store = :null_store
end

# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log

# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true

# Use an evented file watcher to asynchronously detect changes in source code,
# routes, locales, etc. This feature depends on the listen gem.
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# frozen_string_literal: true

Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

# Code is not reloaded between requests.
config.cache_classes = true

# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true

# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true

# 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?

# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com'

# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX

# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true

# Use the lowest log level to ensure availability of diagnostic information
# when problems arise.
config.log_level = :debug

# Prepend all log lines with the following tags.
config.log_tags = [:request_id]

# Use a different cache store in production.
# config.cache_store = :mem_cache_store

# Use a real queuing backend for Active Job (and separate queues per environment)
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "dummy_#{Rails.env}"

# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true

# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify

# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new

# Use a different logger for distributed setups.
# require 'syslog/logger'
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')

if ENV["RAILS_LOG_TO_STDOUT"].present?
logger = ActiveSupport::Logger.new($stdout)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true

# Do not eager load code on boot. This avoids loading your whole application
# just for the purpose of running a single test. If you are using a tool that
# preloads Rails for running tests, you may have to set it to true.
config.eager_load = false

# 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=3600"
}

# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false

# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false

# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false

# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr

# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# ApplicationController.renderer.defaults.merge!(
# http_host: 'example.org',
# https: false
# )
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# You can add backtrace silencers for libraries that you're
# using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }

# You can also remove all the silencers if you're trying to
# debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# Specify a serializer for the signed and encrypted cookie jars.
# Valid options are :json, :marshal, and :hybrid.
Rails.application.config.action_dispatch.cookies_serializer = :json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# Configure sensitive parameters which will be filtered from the log file.
Rails.application.config.filter_parameters += [:password]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# Add new inflection rules using the following format. Inflections
# are locale specific, and you may define rules for as many different
# locales as you wish. All of these examples are active by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep )
# end

# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.acronym 'RESTful'
# end
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.
#
# This file contains migration options to ease your Rails 5.0 upgrade.
#
# Read the Rails 5.0 release notes for more info on each option.

# Enable per-form CSRF tokens. Previous versions had false.
Rails.application.config.action_controller.per_form_csrf_tokens = true

# Enable origin-checking CSRF mitigation. Previous versions had false.
Rails.application.config.action_controller.forgery_protection_origin_check = true

# Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`.
# Previous versions had false.
ActiveSupport.to_time_preserves_timezone = true

# Configure SSL options to enable HSTS with subdomains. Previous versions had false.
Rails.application.config.ssl_options = {hsts: {subdomains: true}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

Rails.application.config.session_store :cookie_store, key: "_dummy_session"
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# This file contains settings for ActionController::ParamsWrapper which
# is enabled by default.

# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json]
end
1 change: 1 addition & 0 deletions spec/dummies/without-engine/dummy-5.x/dummy/config/locales
22 changes: 22 additions & 0 deletions spec/dummies/without-engine/dummy-5.x/dummy/config/secrets.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Be sure to restart your server when you modify this file.

# Your secret key is used for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!

# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# You can use `rails secret` to generate a secure secret key.

# Make sure the secrets in this file are kept private
# if you're sharing your code publicly.

development:
secret_key_base: 93cc56a5c8991ad66f5a0ad2fa901a680d33b4d2b2556737115113246700705a46122df56d060d3da333778569e9bd5a0a0e8c21693cd10c48ad496db33edffd

test:
secret_key_base: 3040bb7ecbe834a675144408fc988bdaa791f78e9a9df2493665d514e25b8e409644e65194e070f903d18a03cd01e9463d0d562bb50bfbb7ba9dc8d0aef2076b

# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
8 changes: 8 additions & 0 deletions spec/dummies/without-engine/dummy-5.x/dummy/config/spring.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

%w[
.ruby-version
.rbenv-vars
tmp/restart.txt
tmp/caching-dev.txt
].each { |path| Spring.watch(path) }
1 change: 1 addition & 0 deletions spec/dummies/without-engine/dummy-5.x/dummy/config/system
1 change: 1 addition & 0 deletions spec/dummies/without-engine/dummy-5.x/dummy/lib
Empty file.
File renamed without changes.
1 change: 1 addition & 0 deletions spec/dummies/without-engine/dummy-6.x/dummy/app
28 changes: 28 additions & 0 deletions spec/dummies/without-engine/dummy-6.x/dummy/config/application.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

require_relative "boot"

require "rails"
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.
Bundler.require(*Rails.groups)

module Dummy
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 6.0

config.root = Pathname(__dir__).join("..").realpath

# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.

# Don't generate system test files.
config.generators.system_tests = nil
end
end
5 changes: 5 additions & 0 deletions spec/dummies/without-engine/dummy-6.x/dummy/config/boot.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)

require "bundler/setup" # Set up gems listed in the Gemfile.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gQ0RauBY7+ysf9CEmGsMv3Qcd4FcdU/iCsHSy8GQOA3b5LvtWit8mLybKKNPT5Nua2kL1WWoUB2nvKYEMWcYVFwaMCgmygmslkY8GYgqQJYFd+L7NDC3xeJ8twc/7rih+CcnIQzWseVDSqJX16PwedAiH54UsP9OkLTONL0mOWGYNPnoXeAjnXLgYYekkBE+iwhapGFc7hfQ8QG4PvKKG5EkLDzAFkpGrGrxQ3Fzt2hLCRJ1MPF+qs0hqEYXcJ8lsuKFrH5GzumPWeQEI5saCm0RxfKfVCSP3FHUUnI4Rr9zyrWUcOzbaxs8NWg5QaG9qy75Q4I1gMRoAlIjUuMpQeir4i0njkpWeGVh5tjzRv6t42wlrx3SN1BwAVgbWIldNilNfJqb6KPvmT2Sshigb5Z0tGt042Jj9hDL--UtdTCgDlI7AAkKTI--7sR0UgSU0TcMcoYdCsKUdw==
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false

# Do not eager load code on boot.
config.eager_load = false

# Show full error reports.
config.consider_all_requests_local = true

# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
if Rails.root.join("tmp", "caching-dev.txt").exist?
config.action_controller.perform_caching = true
config.action_controller.enable_fragment_cache_logging = true

config.cache_store = :memory_store
config.public_file_server.headers = {
"Cache-Control" => "public, max-age=#{2.days.to_i}"
}
else
config.action_controller.perform_caching = false

config.cache_store = :null_store
end

# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log

# Raises error for missing translations.
# config.action_view.raise_on_missing_translations = true

# Use an evented file watcher to asynchronously detect changes in source code,
# routes, locales, etc. This feature depends on the listen gem.
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# frozen_string_literal: true

Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

# Code is not reloaded between requests.
config.cache_classes = true

# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true

# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true

# Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
# or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
# config.require_master_key = true

# 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?

# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com'

# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX

# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true

# Use the lowest log level to ensure availability of diagnostic information
# when problems arise.
config.log_level = :debug

# Prepend all log lines with the following tags.
config.log_tags = [:request_id]

# Use a different cache store in production.
# config.cache_store = :mem_cache_store

# Use a real queuing backend for Active Job (and separate queues per environment).
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "dummy_production"

# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true

# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify

# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new

# Use a different logger for distributed setups.
# require 'syslog/logger'
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')

if ENV["RAILS_LOG_TO_STDOUT"].present?
logger = ActiveSupport::Logger.new($stdout)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end

# Inserts middleware to perform automatic connection switching.
# The `database_selector` hash is used to pass options to the DatabaseSelector
# middleware. The `delay` is used to determine how long to wait after a write
# to send a subsequent read to the primary.
#
# The `database_resolver` class is used by the middleware to determine which
# database is appropriate to use based on the time delay.
#
# The `database_resolver_context` class is used by the middleware to set
# timestamps for the last write to the primary. The resolver uses the context
# class timestamps to determine how long to wait before reading from the
# replica.
#
# By default Rails will store a last write timestamp in the session. The
# DatabaseSelector middleware is designed as such you can define your own
# strategy for connection switching and pass that into the middleware through
# these configuration options.
# config.active_record.database_selector = { delay: 2.seconds }
# config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
# config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!

Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

config.cache_classes = false

# Do not eager load code on boot. This avoids loading your whole application
# just for the purpose of running a single test. If you are using a tool that
# preloads Rails for running tests, you may have to set it to true.
config.eager_load = false

# 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=3600"
}

# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.cache_store = :null_store

# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false

# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false

# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr

# Raises error for missing translations.
# config.action_view.raise_on_missing_translations = true
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# ActiveSupport::Reloader.to_prepare do
# ApplicationController.renderer.defaults.merge!(
# http_host: 'example.org',
# https: false
# )
# end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }

# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# Define an application-wide content security policy
# For further information see the following documentation
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy

# Rails.application.config.content_security_policy do |policy|
# policy.default_src :self, :https
# policy.font_src :self, :https, :data
# policy.img_src :self, :https, :data
# policy.object_src :none
# policy.script_src :self, :https
# policy.style_src :self, :https

# # Specify URI for violation reports
# # policy.report_uri "/csp-violation-report-endpoint"
# end

# If you are using UJS then enable automatic nonce generation
# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }

# Set the nonce only to specific directives
# Rails.application.config.content_security_policy_nonce_directives = %w(script-src)

# Report CSP violations to a specified URI
# For further information see the following documentation:
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
# Rails.application.config.content_security_policy_report_only = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# Specify a serializer for the signed and encrypted cookie jars.
# Valid options are :json, :marshal, and :hybrid.
Rails.application.config.action_dispatch.cookies_serializer = :json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# Configure sensitive parameters which will be filtered from the log file.
Rails.application.config.filter_parameters += [:password]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# Add new inflection rules using the following format. Inflections
# are locale specific, and you may define rules for as many different
# locales as you wish. All of these examples are active by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep )
# end

# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.acronym 'RESTful'
# end
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# This file contains settings for ActionController::ParamsWrapper which
# is enabled by default.

# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json]
end
1 change: 1 addition & 0 deletions spec/dummies/without-engine/dummy-6.x/dummy/config/locales
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4fea9f11ee0a627b125c0fd8df6ebab5
8 changes: 8 additions & 0 deletions spec/dummies/without-engine/dummy-6.x/dummy/config/spring.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

Spring.watch(
".ruby-version",
".rbenv-vars",
"tmp/restart.txt",
"tmp/caching-dev.txt"
)
1 change: 1 addition & 0 deletions spec/dummies/without-engine/dummy-6.x/dummy/config/system
1 change: 1 addition & 0 deletions spec/dummies/without-engine/dummy-6.x/dummy/lib
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

class ApiSafeParamsCallbacksController < ActionController::API
before_action do
if safe_params&.failure?
head 422
else
head 200
end
end

schema(:show) do
required(:id).value(:integer)
end

def show; end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

class ApiUsersController < ActionController::API
schema(:show) do
required(:id).value(:integer)
end

schema(:new) do
required(:id).value(:integer)
end

def show
if safe_params.success?
render json: {id: safe_params[:id], name: "Jane"}
else
render json: {errors: safe_params.errors.to_h}
end
end

def new
if safe_params.success?
render json: {id: safe_params[:id], name: "Jane"}
else
render json: {errors: safe_params.errors.to_h}
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

class SafeParamsCallbacksController < ApplicationController
before_action do
if safe_params&.failure?
head 422
else
head 200
end
end

schema(:show) do
required(:id).value(:integer)
end

def show; end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

class UsersController < ApplicationController
schema(:show) do
required(:id).value(:integer)
end

schema(:new) do
required(:id).value(:integer)
end

def show
if safe_params.success?
render json: {id: safe_params[:id], name: "Jane"}
else
render json: {errors: safe_params.errors.to_h}
end
end

def new
if safe_params.success?
render json: {id: safe_params[:id], name: "Jane"}
else
render json: {errors: safe_params.errors.to_h}
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

class CreateUserForm
end
3 changes: 3 additions & 0 deletions spec/dummies/without-engine/dummy/app/models/container.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

class Container; end
5 changes: 5 additions & 0 deletions spec/dummies/without-engine/dummy/app/models/user_repo.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

class UserRepo
include Dummy::Deps["persistence.db"]
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

class CreateUser
end
4 changes: 4 additions & 0 deletions spec/dummies/without-engine/dummy/app/services/github.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

class Github
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

class MailerWorker
include Dummy::Deps["mailer"]
end
15 changes: 15 additions & 0 deletions spec/dummies/without-engine/dummy/config/initializers/system.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

require "dry/rails"

Dry::Rails.container do
config.component_dirs.add "lib" do |dir|
dir.namespaces.add "dummy", key: nil
end

config.component_dirs.add "app/operations"
config.component_dirs.add "app/services"
config.component_dirs.add("app/workers") do |dir|
dir.memoize = true
end
end
4 changes: 4 additions & 0 deletions spec/dummies/without-engine/dummy/config/locales/en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
en:
contracts:
errors:
filled?: 'cannot be blank'
4 changes: 4 additions & 0 deletions spec/dummies/without-engine/dummy/config/locales/pl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pl:
contracts:
errors:
filled?: 'nie może być puste'
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

Dummy::Container.boot(:persistence) do |container|
start do
container.register("persistence.db", :i_am_db)
end
end
7 changes: 7 additions & 0 deletions spec/dummies/without-engine/dummy/lib/dummy/notifier.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module Dummy
class Notifier
include Deps[:mailer]
end
end
9 changes: 9 additions & 0 deletions spec/dummies/without-engine/dummy/lib/dummy/user_contract.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

module Dummy
class UserContract < ApplicationContract
params do
required(:name).filled(:string)
end
end
end
4 changes: 4 additions & 0 deletions spec/dummies/without-engine/dummy/lib/mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

class Mailer
end
1 change: 0 additions & 1 deletion spec/dummy/app/models/container.rb

This file was deleted.

40 changes: 40 additions & 0 deletions spec/integration/dry/rails/railtie/finalize_engine_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

RSpec.describe Dry::Rails::Railtie, ".finalize!", :engine do
subject(:railtie) { Dry::Rails::Railtie.instance }

it "reloads container and import module", no_reload: true do
Rails.application.reloader.reload!

Dry::Rails.container do
config.component_dirs.add "app/forms"
end

Dry::Rails::Engine.container(:super_engine) do
config.component_dirs.add "app/forms" do |dir|
dir.namespaces.add "super_engine", key: nil
end
end

Dummy::Container.register("foo", Object.new)
SuperEngine::Container.register("bar", Object.new)

expect(Dummy::Container.keys).to include("foo")
expect(SuperEngine::Container.keys).to include("bar")

Rails.application.reloader.reload!

expect(Dummy::Container.keys).to_not include("foo")
expect(SuperEngine::Container.keys).to_not include("bar")

klass = Class.new do
include Dummy::Deps["create_user_form"]
include SuperEngine::Deps["create_book_form"]
end

obj = klass.new

expect(obj.create_user_form).to be_instance_of(CreateUserForm)
expect(obj.create_book_form).to be_instance_of(SuperEngine::CreateBookForm)
end
end
2 changes: 1 addition & 1 deletion spec/integration/dry/rails/railtie/finalize_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

RSpec.describe Dry::Rails::Railtie, ".finalize!" do
RSpec.describe Dry::Rails::Railtie, ".finalize!", :main_app do
subject(:railtie) { Dry::Rails::Railtie.instance }

it "reloads container and import module", no_reload: true do
24 changes: 24 additions & 0 deletions spec/requests/engine/api_books_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

RSpec.describe "SuperEngine::ApiBooksController", :engine, type: :request do
%w[show new].each do |action|
describe "GET /api/users/#{action}" do
it "returns a successful response" do
get "/super_engine/api/books/#{action}/312"

json = JSON.parse(response.body, symbolize_names: true)

expect(json[:id]).to be(312)
expect(json[:name]).to eql("Harry Potter")
end

it "returns errors" do
get "/super_engine/api/books/#{action}/oops"

json = JSON.parse(response.body, symbolize_names: true)

expect(json[:errors]).to eql(id: ["must be an integer"])
end
end
end
end
17 changes: 17 additions & 0 deletions spec/requests/engine/api_safe_params_callbacks_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

RSpec.describe "SuperEngine::ApiSafeParamsCallbacksController", :engine, type: :request do
describe "GET /api/safe_params_callbacks/show" do
it "returns a successful response code" do
get "/super_engine/api/safe_params_callbacks/show/312"

expect(response).to have_http_status(200)
end

it "returns errors" do
get "/super_engine/api/safe_params_callbacks/show/oops"

expect(response).to have_http_status(422)
end
end
end
24 changes: 24 additions & 0 deletions spec/requests/engine/books_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

RSpec.describe "SuperEngine::BooksController", :engine, type: :request do
%w[show new].each do |action|
describe "GET /users/#{action}" do
it "returns a successful response" do
get "/super_engine/books/#{action}/312"

json = JSON.parse(response.body, symbolize_names: true)

expect(json[:id]).to be(312)
expect(json[:name]).to eql("Harry Potter")
end

it "returns errors" do
get "/super_engine/books/#{action}/oops"

json = JSON.parse(response.body, symbolize_names: true)

expect(json[:errors]).to eql(id: ["must be an integer"])
end
end
end
end
17 changes: 17 additions & 0 deletions spec/requests/engine/safe_params_callbacks_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

RSpec.describe "SuperEngine::SafeParamsCallbacksController", :engine, type: :request do
describe "GET /safe_params_callbacks/show" do
it "returns a successful response code" do
get "/super_engine/safe_params_callbacks/show/312"

expect(response).to have_http_status(200)
end

it "returns errors" do
get "/super_engine/safe_params_callbacks/show/oops"

expect(response).to have_http_status(422)
end
end
end
27 changes: 16 additions & 11 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -9,31 +9,36 @@

SPEC_ROOT = Pathname(__dir__)

Dir[SPEC_ROOT.join("shared/**/*.rb")].each(&method(:require))
Dir[SPEC_ROOT.join("support/**/*.rb")].each(&method(:require))
Dir[SPEC_ROOT.join("shared/**/*.rb")].sort.each(&method(:require))
Dir[SPEC_ROOT.join("support/**/*.rb")].sort.each(&method(:require))

ENV["RAILS_ENV"] ||= "test"

RAILS_VERSION = ENV["RAILS_VERSION"] || "6.x"

require SPEC_ROOT.join("dummy-#{RAILS_VERSION}/dummy/config/environment").to_s
DUMMY_DIR = ENV["TEST_DUMMY"] || "with-engine"
WITH_ENGINE = DUMMY_DIR == "with-engine"
require SPEC_ROOT.join("dummies/#{DUMMY_DIR}/dummy-#{RAILS_VERSION}/dummy/config/environment").to_s

require "rspec/rails"

RSpec.configure do |config|
if WITH_ENGINE
config.filter_run_excluding main_app: true
else
config.filter_run_excluding engine: true
end

config.disable_monkey_patching!

config.before do |example|
Rails.application.reloader.reload! unless example.metadata[:no_reload]
end

config.around(production: true) do |example|
begin
prev_env = Rails.env
Rails.env = "production"
example.run
ensure
Rails.env = prev_env
end
prev_env = Rails.env
Rails.env = "production"
example.run
ensure
Rails.env = prev_env
end
end