├── .editorconfig ├── .github └── workflows │ └── main.yml ├── .gitignore ├── .rspec ├── Appraisals ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── gemfiles ├── .gitignore ├── rails50.gemfile ├── rails51.gemfile ├── rails52.gemfile ├── rails60.gemfile ├── rails61.gemfile └── rails70.gemfile ├── lib ├── action_dispatch │ └── routing │ │ └── static_responder.rb ├── rails-static-router.rb └── rails_static_router │ ├── railtie.rb │ └── version.rb ├── rails-static-router.gemspec └── spec ├── dummy ├── .gitignore ├── app │ ├── assets │ │ └── config │ │ │ └── manifest.js │ └── controllers │ │ ├── application_controller.rb │ │ └── test_controller.rb ├── config.ru ├── config │ ├── application.rb │ ├── boot.rb │ ├── cable.yml │ ├── credentials.yml.enc │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ └── test.rb │ ├── locales │ │ └── en.yml │ ├── puma.rb │ ├── routes.rb │ ├── secrets.yml │ ├── spring.rb │ └── storage.yml ├── db │ └── seeds.rb ├── log │ └── .keep ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── favicon.ico │ ├── lucu.txt │ ├── mantap.txt │ └── robots.txt └── tmp │ └── .keep ├── integration └── routing_spec.rb ├── rails_helper.rb └── spec_helper.rb /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | indent_style = space 12 | indent_size = 2 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Main 2 | 3 | on: [push] 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | include: 13 | - gemfile: gemfiles/rails50.gemfile 14 | rubyver: 2.4.10 15 | - gemfile: gemfiles/rails51.gemfile 16 | rubyver: 2.4.10 17 | - gemfile: gemfiles/rails52.gemfile 18 | rubyver: 2.4.10 19 | - gemfile: gemfiles/rails60.gemfile 20 | rubyver: 2.6.10 21 | - gemfile: gemfiles/rails61.gemfile 22 | rubyver: 2.7.6 23 | - gemfile: gemfiles/rails70.gemfile 24 | rubyver: 3.1.2 25 | 26 | env: 27 | RAILS_ENV: test 28 | BUNDLE_GEMFILE: ${{ matrix.gemfile }} 29 | 30 | steps: 31 | - uses: actions/checkout@v2 32 | 33 | - name: Set up Ruby 34 | uses: ruby/setup-ruby@v1 35 | with: 36 | # Not needed with a .ruby-version file 37 | ruby-version: ${{ matrix.rubyver }} 38 | # runs 'bundle install' and caches installed gems automatically 39 | bundler-cache: true 40 | 41 | - name: Run tests 42 | env: 43 | BUNDLE_GEMFILE: ${{ matrix.gemfile }} 44 | run: | 45 | bundle exec rake test 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *~ 3 | .bundle 4 | .rvmrc 5 | .yardoc 6 | Gemfile.lock 7 | Gemfile.*.lock 8 | coverage/* 9 | doc/* 10 | log/* 11 | measurement/* 12 | pkg/* 13 | spec/examples.txt 14 | spec/reports/* 15 | test/coverage 16 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --order random 3 | --require spec_helper 4 | --format documentation --color 5 | --format html --out spec/reports/rspec_results.html 6 | -------------------------------------------------------------------------------- /Appraisals: -------------------------------------------------------------------------------- 1 | appraise 'rails50' do 2 | gem 'rails', '~> 5.0.0' 3 | gem 'sqlite3', '~> 1.3.6' 4 | 5 | gem 'rspec-rails' 6 | end 7 | 8 | appraise 'rails51' do 9 | gem 'rails', '~> 5.1.0' 10 | gem 'sqlite3', '~> 1.3.6' 11 | 12 | gem 'rspec-rails' 13 | end 14 | 15 | appraise 'rails52' do 16 | gem 'rails', '~> 5.2.0' 17 | gem 'sqlite3', '~> 1.3.6' 18 | 19 | gem 'rspec-rails' 20 | end 21 | 22 | appraise 'rails60' do 23 | gem 'rails', '~> 6.0.0' 24 | gem 'sqlite3' 25 | 26 | gem 'rspec-rails' 27 | end 28 | 29 | appraise 'rails61' do 30 | gem 'rails', '~> 6.1.0' 31 | gem 'sqlite3' 32 | 33 | gem 'rspec-rails' 34 | end 35 | 36 | appraise 'rails70' do 37 | gem 'rails', '~> 7.0.1' 38 | gem 'sqlite3' 39 | 40 | gem 'rspec-rails' 41 | end 42 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Eliot Sykes 4 | Copyright (c) 2018 Muhammad Mufid Afif 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rails Static Router [![Build Status](https://travis-ci.org/mufid/rails-static-router.svg?branch=master)](https://travis-ci.org/mufid/rails-static-router) [![Gem Version](https://badge.fury.io/rb/rails-static-router.svg)](https://badge.fury.io/rb/rails-static-router) 2 | 3 | Enjoy static routes in your Rails `config/routes.rb`. 4 | 5 | 6 | 7 | - [Installation](#installation) 8 | - [Example use](#example-use) 9 | - [Why?](#why) 10 | - [Contributors](#contributors) 11 | 12 | 13 | 14 | ## Installation 15 | 16 | 1. Put `gem 'rails-static-router'` in your `Gemfile` 17 | 2. Restart app 18 | 19 | ## Example use 20 | 21 | ```ruby 22 | Rails.application.routes.draw do 23 | ... 24 | # This route will serve public/index.html at the /login URL path, and have 25 | # URL helper named `login_path`: 26 | get "/login", to: static("index.html") 27 | 28 | # This route will serve public/index.html at the /register URL path, and 29 | # have URL helper named `new_user_registration_path`: 30 | get "/register", to: static("index.html"), as: :new_user_registration 31 | ... 32 | end 33 | ``` 34 | 35 | `bin/rake routes` output for the above routes: 36 | 37 | ``` 38 | Prefix Verb URI Pattern Controller#Action 39 | login GET /login(.:format) static('index.html') 40 | new_user_registration GET /register(.:format) static('index.html') 41 | ``` 42 | 43 | ## Compatibility 44 | 45 | This gem is compatible with Rails 5.0+. 46 | 47 | If you want to use with Rails 4.1 or Rails 4.2, use version 1.0.4: 48 | 49 | gem 'rails-static-router', '1.0.4' 50 | 51 | ## Rails API Mode 52 | 53 | We don't recommend use this gem if you are using Rails API Mode. Your apps 54 | supposed to only serving API, not assets. 55 | 56 | ## Why? 57 | 58 | This introduces a `static(path_to_file)` helper method to route to static files 59 | from within `routes.rb`. It is inspired by Rails' existing `redirect(...)` method. 60 | 61 | Some benefits of this technique over alternatives (such as rack-rewrite, 62 | nginx/httpd-configured rewrites): 63 | 64 | - Named URL helper method for static file available throughout app, for 65 | example in mail templates, view templates, and tests. 66 | 67 | - Route discoverable via `bin/rake routes` and Routing Error page in development. 68 | 69 | - Takes advantage of ActionDispatch's built-in gzip handling. Controller action 70 | based solutions for rendering static files tend to not use this. 71 | 72 | - Handy for Single Page Apps that serve the same static HTML file for multiple 73 | paths, as is often the case with Ember & Angular apps. 74 | 75 | - Heroku-like production environments work with this that do use the Rails app 76 | to serve static files. 77 | 78 | - Leaves door open for nginx, Apache, Varnish and friends to serve the static 79 | files directly for improved performance in production environments via symlinks 80 | and/or other artifacts generated at deploy time. 81 | 82 | ## Contributors 83 | 84 | - Eliot Sykes https://eliotsykes.com/ 85 | - Muhammad Mufid Afif https://mufid.github.io 86 | - Your name here! Contributions are welcome and easy. Fork the GitHub repo, make your changes, then submit your pull request. Don't hesitate to ask if you'd like some help. 87 | 88 | ## Contributing 89 | 90 | We are using Appraisals to test against multiple Rails version. To set it 91 | up for the first time, please run: 92 | 93 | bundle install 94 | bundle exec appraisal install 95 | 96 | After Appraisal installed, use this command to run all the test: 97 | 98 | bundle exec appraisal rake test 99 | 100 | To run against only specific Rails version, you can specify it 101 | with `BUNDLE_GEMFILE`. For example, if you want to run only 102 | against Rails 5.2, you can execute command below. 103 | 104 | export BUNDLE_GEMFILE=gemfiles/rails51.gemfile 105 | bundle install 106 | bundle exec rake test 107 | 108 | To test it agains multiple Ruby version, you may want to use rvm. 109 | For example: 110 | 111 | # Test it against all specified Rails version 112 | # with Ruby version 2.3.7 113 | rvm install 2.3.7 114 | rvm use 2.3.7 115 | bundle exec appraisal rake test 116 | 117 | # Test it against all specified Rails version 118 | # with Ruby version 2.4.4 119 | rvm install 2.4.4 120 | bundle exec appraisal rake test 121 | 122 | ## Releasing 123 | 124 | For contributors that have access to release server, do the 125 | following commands to release the gem. 126 | 127 | # Edit version.rb to match next version, then 128 | git add . 129 | git commit -m "ops: release" 130 | bundle exec rake release 131 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | Bundler::GemHelper.install_tasks 3 | 4 | # RSpec Rails available via Appraisal 5 | begin 6 | require 'rspec/core/rake_task' 7 | RSpec::Core::RakeTask.new(:spec) 8 | task test: :spec 9 | rescue LoadError 10 | end 11 | 12 | require 'rubocop/rake_task' 13 | RuboCop::RakeTask.new 14 | 15 | require 'reek/rake/task' 16 | Reek::Rake::Task.new 17 | 18 | task default: %i[spec] 19 | -------------------------------------------------------------------------------- /gemfiles/.gitignore: -------------------------------------------------------------------------------- 1 | .bundle 2 | *.gemfile.lock 3 | -------------------------------------------------------------------------------- /gemfiles/rails50.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "~> 5.0.0" 6 | gem "sqlite3", "~> 1.3.6" 7 | gem "rspec-rails" 8 | 9 | gemspec path: "../" 10 | -------------------------------------------------------------------------------- /gemfiles/rails51.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "~> 5.1.0" 6 | gem "sqlite3", "~> 1.3.6" 7 | gem "rspec-rails" 8 | 9 | gemspec path: "../" 10 | -------------------------------------------------------------------------------- /gemfiles/rails52.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "~> 5.2.0" 6 | gem "sqlite3", "~> 1.3.6" 7 | gem "rspec-rails" 8 | 9 | gemspec path: "../" 10 | -------------------------------------------------------------------------------- /gemfiles/rails60.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "~> 6.0.0" 6 | gem "sqlite3" 7 | gem "rspec-rails" 8 | 9 | gemspec path: "../" 10 | -------------------------------------------------------------------------------- /gemfiles/rails61.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "~> 6.1.0" 6 | gem "sqlite3" 7 | gem "rspec-rails" 8 | 9 | gemspec path: "../" 10 | -------------------------------------------------------------------------------- /gemfiles/rails70.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "~> 7.0.1" 6 | gem "sqlite3" 7 | gem "rspec-rails" 8 | 9 | gemspec path: "../" 10 | -------------------------------------------------------------------------------- /lib/action_dispatch/routing/static_responder.rb: -------------------------------------------------------------------------------- 1 | # Example use: 2 | # 3 | # Rails.application.routes.draw do 4 | # ... 5 | # # This route will serve public/index.html at the /login URL path, and have 6 | # # URL helper named `login_path`: 7 | # get "/login", to: static("index.html") 8 | # 9 | # # This route will serve public/index.html at the /register URL path, and 10 | # # have URL helper named `new_user_registration_path`: 11 | # get "/register", to: static("index.html"), as: :new_user_registration 12 | # ... 13 | # end 14 | # 15 | # `bin/rake routes` output for the above routes: 16 | # 17 | # Prefix Verb URI Pattern Controller#Action 18 | # login GET /login(.:format) static('index.html') 19 | # new_user_registration GET /register(.:format) static('index.html') 20 | # 21 | # 22 | # Why? 23 | # 24 | # static(path_to_file) helper method used to route to static files 25 | # from within routes.rb. Inspired by Rails' existing redirect(...) method. 26 | # 27 | # Some benefits of this technique over alternatives (such as rack-rewrite, 28 | # nginx/httpd-configured rewrites): 29 | # 30 | # - Named URL helper method for static file available throughout app, for 31 | # example in mail templates, view templates, and tests. 32 | # 33 | # - Route discoverable via `bin/rake routes` and Routing Error page in development. 34 | # 35 | # - Takes advantage of ActionDispatch's built-in gzip handling. Controller action 36 | # based solutions for rendering static files tend to not use this. 37 | # 38 | # - Handy for Single Page Apps that serve the same static HTML file for multiple 39 | # paths, as is often the case with Ember & Angular apps. 40 | # 41 | # - Heroku-like production environments work with this that do use the Rails app 42 | # to serve static files. 43 | # 44 | # - Leaves door open for nginx, Apache, Varnish and friends to serve the static 45 | # files directly for improved performance in production environments via symlinks 46 | # and/or other artifacts generated at deploy time. 47 | # 48 | 49 | # Required if serve_static_assets set to false 50 | require 'action_dispatch/middleware/static' 51 | 52 | module ActionDispatch 53 | module Routing 54 | 55 | if Gem::Version.new(Rails.version) >= Gem::Version.new('4.2') 56 | class StaticResponder < Endpoint; end 57 | else 58 | class StaticResponder; end 59 | end 60 | 61 | if Gem::Version.new(Rails.version) < Gem::Version.new('5.0') 62 | class StaticResponder 63 | def file_handler 64 | @file_handler ||= ::ActionDispatch::FileHandler.new( 65 | Rails.configuration.paths["public"].first, 66 | Rails.configuration.static_cache_control 67 | ) 68 | end 69 | end 70 | else 71 | class StaticResponder 72 | def file_handler 73 | @file_handler ||= ::ActionDispatch::FileHandler.new( 74 | Rails.configuration.paths["public"].first, 75 | headers: Rails.configuration.public_file_server.headers 76 | ) 77 | end 78 | end 79 | end 80 | 81 | class StaticResponder 82 | 83 | attr_accessor :path 84 | 85 | def initialize(path) 86 | self.path = path 87 | self.trigger_file_handler_initialization 88 | end 89 | 90 | def trigger_file_handler_initialization 91 | file_handler 92 | end 93 | 94 | def call(env) 95 | env["PATH_INFO"] = path 96 | @file_handler.call(env) 97 | end 98 | 99 | def inspect 100 | "static('#{path}')" 101 | end 102 | 103 | end 104 | 105 | class Mapper 106 | def static(path) 107 | StaticResponder.new(path) 108 | end 109 | end 110 | end 111 | end 112 | -------------------------------------------------------------------------------- /lib/rails-static-router.rb: -------------------------------------------------------------------------------- 1 | require 'rails_static_router/railtie' 2 | require 'rails_static_router/version' 3 | -------------------------------------------------------------------------------- /lib/rails_static_router/railtie.rb: -------------------------------------------------------------------------------- 1 | module RailsStaticRouter 2 | class Railtie < Rails::Railtie 3 | initializer 'rails_static_router.railtie' do 4 | require 'action_dispatch/routing/static_responder' 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/rails_static_router/version.rb: -------------------------------------------------------------------------------- 1 | module RailsStaticRouter 2 | VERSION = '1.0.6' 3 | end 4 | -------------------------------------------------------------------------------- /rails-static-router.gemspec: -------------------------------------------------------------------------------- 1 | lib = File.expand_path('./lib', __dir__) 2 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 3 | require 'rails_static_router/version' 4 | 5 | Gem::Specification.new do |spec| 6 | spec.authors = ['Eliot Sykes', 'Muhammad Mufid Afif'] 7 | spec.description = 'Enjoy static routes in your Rails `config/routes.rb`' 8 | spec.email = ['mufidafif@icloud.com'] 9 | spec.files = `git ls-files -z`.split("\x0").reject { |f| f.start_with?('spec/') } 10 | spec.homepage = 'https://github.com/mufid/rails-static-router' 11 | spec.licenses = %w[MIT] 12 | spec.name = 'rails-static-router' 13 | spec.require_paths = %w[lib] 14 | 15 | spec.summary = spec.description 16 | spec.version = RailsStaticRouter::VERSION 17 | 18 | spec.add_dependency 'railties', '>= 5.0', '< 7.1' 19 | 20 | # Test and build tools 21 | # The test shouldn't broken by the incompatible RSpec version. 22 | # Thus, we need to lock the version. 23 | spec.add_development_dependency "appraisal" 24 | spec.add_development_dependency 'bundler' 25 | spec.add_development_dependency 'rake', '~> 12.0' 26 | spec.add_development_dependency 'simplecov' 27 | spec.add_development_dependency 'simplecov-html' 28 | 29 | # Docs, debugger, linter. 30 | # We don't need to specify the lock version for these documentation 31 | # Please do adjust our program so that it will always compatible 32 | # with the latest version of these dependencies 33 | spec.add_development_dependency 'maruku' 34 | spec.add_development_dependency 'pry' 35 | spec.add_development_dependency 'reek' 36 | spec.add_development_dependency 'rubocop' 37 | spec.add_development_dependency 'yard' 38 | end 39 | -------------------------------------------------------------------------------- /spec/dummy/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/* 16 | /tmp/* 17 | !/log/.keep 18 | !/tmp/.keep 19 | 20 | # Ignore uploaded files in development 21 | /storage/* 22 | 23 | /node_modules 24 | /yarn-error.log 25 | 26 | /public/assets 27 | .byebug_history 28 | 29 | # Ignore master key for decrypting credentials and more. 30 | /config/master.key 31 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/config/manifest.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mufid/rails-static-router/975b3435b4b04edc37de99f63885b2b3fab912b1/spec/dummy/app/assets/config/manifest.js -------------------------------------------------------------------------------- /spec/dummy/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | end 3 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/test_controller.rb: -------------------------------------------------------------------------------- 1 | class TestController < ApplicationController 2 | def aroute 3 | render plain: 'hi2!' 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /spec/dummy/config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative 'boot' 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module Dummy 10 | class Application < Rails::Application 11 | if Rails.version.match('7.0') 12 | config.load_defaults 7.0 13 | elsif Rails.version.match('6.1') 14 | config.load_defaults 6.1 15 | elsif Rails.version.match('6.0') 16 | config.load_defaults 6.0 17 | elsif Rails.version.match('5.2') 18 | config.load_defaults 5.2 19 | elsif Rails.version.match('5.1') 20 | config.load_defaults 5.1 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/dummy/config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' # Set up gems listed in the Gemfile. 2 | -------------------------------------------------------------------------------- /spec/dummy/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: async 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: dummy_production 11 | -------------------------------------------------------------------------------- /spec/dummy/config/credentials.yml.enc: -------------------------------------------------------------------------------- 1 | AB3uKKehyWJ6ALdJpRfuyFsO0CRz88Cbnh7CVGX0wnthmfS+uC/gvLzeKWvQtQXTHiaUA2VvWl44VMTaKljbjtfi5OmUVMOWajU61hLTaT6pkqBmZ2ccRGIF7aGYszE3pvyWdoQcD7keRTv17dTwXQVDOej0N348sK4/+ERXVpopOXmHcFG19YHIUzErrhhqqt90NZFRko330jimZ0zJVzUC6Bano6Duoi6TjVw/AeaTSQdnTldu6I4z27kHIbymrfmca07inUQzmdXOPMiBDjWtw16ZhIdqaIgBWro4HoZBuAUSAQ0gVEWza0pWcPz1wTGTsoYmryx3JKvR2dwb9GdfMzLyR45B6CrbQT0OUM7pOgXp4rP/A6WdCr6wGty3QLItU1DQwwlQQM7C4zizsACm2gn8jVg12NTQ--shOunLXOMXbicXoQ--W56M+RkWetpgC/yfn1NYvA== -------------------------------------------------------------------------------- /spec/dummy/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | # 7 | default: &default 8 | adapter: sqlite3 9 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 10 | timeout: 5000 11 | 12 | development: 13 | <<: *default 14 | database: db/development.sqlite3 15 | 16 | # Warning: The database defined as "test" will be erased and 17 | # re-generated from your development database when you run "rake". 18 | # Do not set this db to the same as development or production. 19 | test: 20 | <<: *default 21 | database: db/test.sqlite3 22 | 23 | production: 24 | <<: *default 25 | database: db/production.sqlite3 26 | -------------------------------------------------------------------------------- /spec/dummy/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /spec/dummy/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | 3 | if Rails.version.match(/^(5|6|7)/) 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # The test environment is used exclusively to run your application's 7 | # test suite. You never need to work with it otherwise. Remember that 8 | # your test database is "scratch space" for the test suite and is wiped 9 | # and recreated between test runs. Don't rely on the data there! 10 | config.cache_classes = true 11 | 12 | # Do not eager load code on boot. This avoids loading your whole application 13 | # just for the purpose of running a single test. If you are using a tool that 14 | # preloads Rails for running tests, you may have to set it to true. 15 | config.eager_load = false 16 | 17 | # Show full error reports and disable caching. 18 | config.consider_all_requests_local = true 19 | config.action_controller.perform_caching = false 20 | 21 | # Raise exceptions instead of rendering exception templates. 22 | config.action_dispatch.show_exceptions = false 23 | 24 | # Disable request forgery protection in test environment. 25 | config.action_controller.allow_forgery_protection = false 26 | 27 | if Gem::Version.new(Rails.version) >= Gem::Version.new('5.2') 28 | # Store uploaded files on the local file system in a temporary directory 29 | config.active_storage.service = :test 30 | end 31 | 32 | config.action_mailer.perform_caching = false 33 | 34 | # Tell Action Mailer not to deliver emails to the real world. 35 | # The :test delivery method accumulates sent emails in the 36 | # ActionMailer::Base.deliveries array. 37 | config.action_mailer.delivery_method = :test 38 | 39 | # Print deprecation notices to the stderr. 40 | config.active_support.deprecation = :stderr 41 | 42 | # Raises error for missing translations 43 | # config.action_view.raise_on_missing_translations = true 44 | 45 | config.public_file_server.enabled = false 46 | config.public_file_server.headers = { 47 | 'Cache-Control' => "my-cache-control" 48 | } 49 | 50 | else 51 | # Settings specified here will take precedence over those in config/application.rb. 52 | 53 | # The test environment is used exclusively to run your application's 54 | # test suite. You never need to work with it otherwise. Remember that 55 | # your test database is "scratch space" for the test suite and is wiped 56 | # and recreated between test runs. Don't rely on the data there! 57 | config.cache_classes = true 58 | 59 | # Do not eager load code on boot. This avoids loading your whole application 60 | # just for the purpose of running a single test. If you are using a tool that 61 | # preloads Rails for running tests, you may have to set it to true. 62 | config.eager_load = false 63 | 64 | # Configure static asset server for tests with Cache-Control for performance. 65 | config.serve_static_assets = false 66 | config.static_cache_control = 'my-cache-control' 67 | 68 | # Show full error reports and disable caching. 69 | config.consider_all_requests_local = true 70 | config.action_controller.perform_caching = false 71 | 72 | # Raise exceptions instead of rendering exception templates. 73 | config.action_dispatch.show_exceptions = false 74 | 75 | # Disable request forgery protection in test environment. 76 | config.action_controller.allow_forgery_protection = false 77 | 78 | # Tell Action Mailer not to deliver emails to the real world. 79 | # The :test delivery method accumulates sent emails in the 80 | # ActionMailer::Base.deliveries array. 81 | config.action_mailer.delivery_method = :test 82 | 83 | # Print deprecation notices to the stderr. 84 | config.active_support.deprecation = :stderr 85 | 86 | # Raises error for missing translations 87 | # config.action_view.raise_on_missing_translations = true 88 | end 89 | end 90 | -------------------------------------------------------------------------------- /spec/dummy/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # The following keys must be escaped otherwise they will not be retrieved by 20 | # the default I18n backend: 21 | # 22 | # true, false, on, off, yes, no 23 | # 24 | # Instead, surround them with single quotes. 25 | # 26 | # en: 27 | # 'true': 'foo' 28 | # 29 | # To learn more, please read the Rails Internationalization guide 30 | # available at http://guides.rubyonrails.org/i18n.html. 31 | 32 | en: 33 | hello: "Hello world" 34 | -------------------------------------------------------------------------------- /spec/dummy/config/puma.rb: -------------------------------------------------------------------------------- 1 | # Puma can serve each request in a thread from an internal thread pool. 2 | # The `threads` method setting takes two numbers: a minimum and maximum. 3 | # Any libraries that use thread pools should be configured to match 4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum 5 | # and maximum; this matches the default thread size of Active Record. 6 | # 7 | threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 8 | threads threads_count, threads_count 9 | 10 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000. 11 | # 12 | port ENV.fetch("PORT") { 3000 } 13 | 14 | # Specifies the `environment` that Puma will run in. 15 | # 16 | environment ENV.fetch("RAILS_ENV") { "development" } 17 | 18 | # Specifies the number of `workers` to boot in clustered mode. 19 | # Workers are forked webserver processes. If using threads and workers together 20 | # the concurrency of the application would be max `threads` * `workers`. 21 | # Workers do not work on JRuby or Windows (both of which do not support 22 | # processes). 23 | # 24 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 } 25 | 26 | # Use the `preload_app!` method when specifying a `workers` number. 27 | # This directive tells Puma to first boot the application and load code 28 | # before forking the application. This takes advantage of Copy On Write 29 | # process behavior so workers use less memory. 30 | # 31 | # preload_app! 32 | 33 | # Allow puma to be restarted by `rails restart` command. 34 | plugin :tmp_restart 35 | -------------------------------------------------------------------------------- /spec/dummy/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | get '/lucu.txt', to: static('lucu.txt') 3 | get '/another', to: static('lucu.txt') 4 | controller :test do 5 | get :aroute 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/dummy/config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: c1cdd4b629f11ef1c4da861487587f36d7529a632245735d13e0e032b8e2c3fb7dd6c8a916a79579fea3c8a36ccf194f93bb68f5bdc311072036706726e2f787 15 | 16 | test: 17 | secret_key_base: 421c46030474030e5b724b7dd7e61dbfa5939ebd4205c19e24668f9660dbbf72a240854a9226f2c27c11a83813426fef9e4722bf74ef152733416823ffba297a 18 | 19 | # Do not keep production secrets in the repository, 20 | # instead read values from the environment. 21 | production: 22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 23 | -------------------------------------------------------------------------------- /spec/dummy/config/spring.rb: -------------------------------------------------------------------------------- 1 | %w[ 2 | .ruby-version 3 | .rbenv-vars 4 | tmp/restart.txt 5 | tmp/caching-dev.txt 6 | ].each { |path| Spring.watch(path) } 7 | -------------------------------------------------------------------------------- /spec/dummy/config/storage.yml: -------------------------------------------------------------------------------- 1 | test: 2 | service: Disk 3 | root: <%= Rails.root.join("tmp/storage") %> 4 | 5 | local: 6 | service: Disk 7 | root: <%= Rails.root.join("storage") %> 8 | 9 | # Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) 10 | # amazon: 11 | # service: S3 12 | # access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> 13 | # secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> 14 | # region: us-east-1 15 | # bucket: your_own_bucket 16 | 17 | # Remember not to checkin your GCS keyfile to a repository 18 | # google: 19 | # service: GCS 20 | # project: your_project 21 | # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> 22 | # bucket: your_own_bucket 23 | 24 | # Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) 25 | # microsoft: 26 | # service: AzureStorage 27 | # storage_account_name: your_account_name 28 | # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> 29 | # container: your_container_name 30 | 31 | # mirror: 32 | # service: Mirror 33 | # primary: local 34 | # mirrors: [ amazon, google, microsoft ] 35 | -------------------------------------------------------------------------------- /spec/dummy/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) 7 | # Character.create(name: 'Luke', movie: movies.first) 8 | -------------------------------------------------------------------------------- /spec/dummy/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mufid/rails-static-router/975b3435b4b04edc37de99f63885b2b3fab912b1/spec/dummy/log/.keep -------------------------------------------------------------------------------- /spec/dummy/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /spec/dummy/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /spec/dummy/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /spec/dummy/public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mufid/rails-static-router/975b3435b4b04edc37de99f63885b2b3fab912b1/spec/dummy/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /spec/dummy/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mufid/rails-static-router/975b3435b4b04edc37de99f63885b2b3fab912b1/spec/dummy/public/apple-touch-icon.png -------------------------------------------------------------------------------- /spec/dummy/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mufid/rails-static-router/975b3435b4b04edc37de99f63885b2b3fab912b1/spec/dummy/public/favicon.ico -------------------------------------------------------------------------------- /spec/dummy/public/lucu.txt: -------------------------------------------------------------------------------- 1 | hi! 2 | -------------------------------------------------------------------------------- /spec/dummy/public/mantap.txt: -------------------------------------------------------------------------------- 1 | mantap 2 | -------------------------------------------------------------------------------- /spec/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /spec/dummy/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mufid/rails-static-router/975b3435b4b04edc37de99f63885b2b3fab912b1/spec/dummy/tmp/.keep -------------------------------------------------------------------------------- /spec/integration/routing_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | RSpec.describe 'Integration Test', type: :request do 4 | it 'can respond to static routes' do 5 | get '/lucu.txt' 6 | expect(response).to have_http_status(:ok) 7 | expect(response.body.strip).to eq('hi!') 8 | expect(response.headers['Cache-Control']).to eq('my-cache-control') 9 | end 10 | 11 | it 'can respond to another static routes' do 12 | get '/another' 13 | expect(response).to have_http_status(:ok) 14 | expect(response.body.strip).to eq('hi!') 15 | expect(response.headers['Cache-Control']).to eq('my-cache-control') 16 | end 17 | 18 | it 'cant response via non-defined static routes' do 19 | expect { get '/mantap.txt' }.to raise_exception 20 | end 21 | 22 | it 'works with normal controller' do 23 | get '/aroute' 24 | expect(response).to have_http_status(:ok) 25 | expect(response.body.strip).to eq('hi2!') 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/rails_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is copied to spec/ when you run 'rails generate rspec:install' 2 | ENV['RAILS_ENV'] ||= 'test' 3 | require File.expand_path('../dummy/config/environment', __FILE__) 4 | # Prevent database truncation if the environment is production 5 | abort("The Rails environment is running in production mode!") if Rails.env.production? 6 | require 'spec_helper' 7 | require 'rspec/rails' 8 | # Add additional requires below this line. Rails is not loaded until this point! 9 | require 'rails-static-router' 10 | 11 | # Requires supporting ruby files with custom matchers and macros, etc, in 12 | # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are 13 | # run as spec files by default. This means that files in spec/support that end 14 | # in _spec.rb will both be required and run as specs, causing the specs to be 15 | # run twice. It is recommended that you do not name files matching this glob to 16 | # end with _spec.rb. You can configure this pattern with the --pattern 17 | # option on the command line or in ~/.rspec, .rspec or `.rspec-local`. 18 | # 19 | # The following line is provided for convenience purposes. It has the downside 20 | # of increasing the boot-up time by auto-requiring all files in the support 21 | # directory. Alternatively, in the individual `*_spec.rb` files, manually 22 | # require only the support files necessary. 23 | # 24 | # Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } 25 | 26 | RSpec.configure do |config| 27 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 28 | # config.fixture_path = "#{::Rails.root}/spec/fixtures" 29 | 30 | # RSpec Rails can automatically mix in different behaviours to your tests 31 | # based on their file location, for example enabling you to call `get` and 32 | # `post` in specs under `spec/controllers`. 33 | # 34 | # You can disable this behaviour by removing the line below, and instead 35 | # explicitly tag your specs with their type, e.g.: 36 | # 37 | # RSpec.describe UsersController, :type => :controller do 38 | # # ... 39 | # end 40 | # 41 | # The different available types are documented in the features, such as in 42 | # https://relishapp.com/rspec/rspec-rails/docs 43 | config.infer_spec_type_from_file_location! 44 | 45 | end 46 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # This file was generated by the `rspec --init` command. Conventionally, all 2 | # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. 3 | # The generated `.rspec` file contains `--require spec_helper` which will cause 4 | # this file to always be loaded, without a need to explicitly require it in any 5 | # files. 6 | # 7 | # Given that it is always loaded, you are encouraged to keep this file as 8 | # light-weight as possible. Requiring heavyweight dependencies from this file 9 | # will add to the boot time of your test suite on EVERY test run, even for an 10 | # individual file that may not need all of that loaded. Instead, consider making 11 | # a separate helper file that requires the additional dependencies and performs 12 | # the additional setup, and require it from the spec files that actually need 13 | # it. 14 | # 15 | # The `.rspec` file also contains a few flags that are not defaults but that 16 | # users commonly want. 17 | # 18 | # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration 19 | 20 | require 'pry' 21 | 22 | require 'rack/test' 23 | 24 | require 'simplecov' 25 | require 'simplecov-html' 26 | SimpleCov.start do 27 | # Don't include test files into code coverage 28 | add_filter 'spec/' 29 | end 30 | 31 | RSpec.configure do |config| 32 | # rspec-expectations config goes here. You can use an alternate 33 | # assertion/expectation library such as wrong or the stdlib/minitest 34 | # assertions if you prefer. 35 | config.expect_with :rspec do |expectations| 36 | # This option will default to `true` in RSpec 4. It makes the `description` 37 | # and `failure_message` of custom matchers include text for helper methods 38 | # defined using `chain`, e.g.: 39 | # be_bigger_than(2).and_smaller_than(4).description 40 | # # => "be bigger than 2 and smaller than 4" 41 | # ...rather than: 42 | # # => "be bigger than 2" 43 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true 44 | end 45 | 46 | # rspec-mocks config goes here. You can use an alternate test double 47 | # library (such as bogus or mocha) by changing the `mock_with` option here. 48 | config.mock_with :rspec do |mocks| 49 | # Prevents you from mocking or stubbing a method that does not exist on 50 | # a real object. This is generally recommended, and will default to 51 | # `true` in RSpec 4. 52 | mocks.verify_partial_doubles = true 53 | end 54 | 55 | # This option will default to `:apply_to_host_groups` in RSpec 4 (and will 56 | # have no way to turn it off -- the option exists only for backwards 57 | # compatibility in RSpec 3). It causes shared context metadata to be 58 | # inherited by the metadata hash of host groups and examples, rather than 59 | # triggering implicit auto-inclusion in groups with matching metadata. 60 | config.shared_context_metadata_behavior = :apply_to_host_groups 61 | 62 | # This allows you to limit a spec run to individual examples or groups 63 | # you care about by tagging them with `:focus` metadata. When nothing 64 | # is tagged with `:focus`, all examples get run. RSpec also provides 65 | # aliases for `it`, `describe`, and `context` that include `:focus` 66 | # metadata: `fit`, `fdescribe` and `fcontext`, respectively. 67 | config.filter_run_when_matching :focus 68 | 69 | # Allows RSpec to persist some state between runs in order to support 70 | # the `--only-failures` and `--next-failure` CLI options. We recommend 71 | # you configure your source control system to ignore this file. 72 | config.example_status_persistence_file_path = "spec/examples.txt" 73 | 74 | # Limits the available syntax to the non-monkey patched syntax that is 75 | # recommended. For more details, see: 76 | # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ 77 | # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ 78 | # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode 79 | config.disable_monkey_patching! 80 | 81 | # This setting enables warnings. It's recommended, but in some cases may 82 | # be too noisy due to issues in dependencies. 83 | config.warnings = true 84 | 85 | # Many RSpec users commonly either run the entire suite or an individual 86 | # file, and it's useful to allow more verbose output when running an 87 | # individual spec file. 88 | if config.files_to_run.one? 89 | # Use the documentation formatter for detailed output, 90 | # unless a formatter has already been configured 91 | # (e.g. via a command-line flag). 92 | config.default_formatter = 'doc' 93 | end 94 | 95 | # Print the 10 slowest examples and example groups at the 96 | # end of the spec run, to help surface which specs are running 97 | # particularly slow. 98 | config.profile_examples = 10 99 | 100 | # Run specs in random order to surface order dependencies. If you find an 101 | # order dependency and want to debug it, you can fix the order by providing 102 | # the seed, which is printed after each run. 103 | # --seed 1234 104 | config.order = :random 105 | 106 | # Seed global randomization in this process using the `--seed` CLI option. 107 | # Setting this allows you to use `--seed` to deterministically reproduce 108 | # test failures related to randomization by passing the same `--seed` value 109 | # as the one that triggered the failure. 110 | Kernel.srand config.seed 111 | end 112 | --------------------------------------------------------------------------------