diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/.document b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/.document new file mode 100644 index 00000000..136eea59 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/.document @@ -0,0 +1,5 @@ +lib/**/*.rb +bin/* +- +README.rdoc +LICENSE.txt diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/.gitignore b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/.gitignore new file mode 100644 index 00000000..2a3a6401 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/.gitignore @@ -0,0 +1,22 @@ +## MAC OS +.DS_Store + +## TEXTMATE +*.tmproj +tmtags + +## EMACS +*~ +\#* +.\#* + +## VIM +*.swp + +## PROJECT::GENERAL +coverage +rdoc +pkg + +## PROJECT::SPECIFIC +test/tmp/* diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/.yardopts b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/.yardopts new file mode 100644 index 00000000..30447b7f --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/.yardopts @@ -0,0 +1 @@ +--title 'Padrino Core Documentation' --protected diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/LICENSE.txt b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/LICENSE.txt new file mode 100644 index 00000000..8f1ef777 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2011 Padrino + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/README.rdoc b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/README.rdoc new file mode 100644 index 00000000..12eaf53a --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/README.rdoc @@ -0,0 +1,294 @@ += Padrino (padrino-core) + +Padrino is the godfather of Sinatra. + +== Preface + +Padrino is a ruby framework built upon the excellent {Sinatra Microframework}[http://www.sinatrarb.com]. +Sinatra is a DSL for creating simple web applications in Ruby with speed and minimal effort. +This framework tries hard to make it as fun and easy as possible to code much more advanced web applications by +building upon the Sinatra philosophies and foundation. + +== Introduction + +Many people love Sinatra's simplicity and lightweight but often quickly come to miss a great deal +of functionality provided by other web frameworks such as Rails when building non-trivial applications. + +Our goal with this framework is to match the essence of Sinatra and at the same time create a standard library +of tools, helpers and components that will make Sinatra suitable for more complex applications. + +Here is a brief overview of functionality provided by the Padrino framework: + +Agnostic:: Full support for many popular testing, templating, mocking, and data storage choices. +Generators:: Create Padrino applications, models, controllers i.e: padrino-gen project. +Mountable:: Unlike other ruby frameworks, principally designed for mounting multiple apps. +Routing:: Full url named routes, named params, before/after filter support. +Tag Helpers:: View helpers such as: tag, content_tag, input_tag. +Asset Helpers:: View helpers such as: link_to, image_tag, javascript_include_tag. +Form Helpers:: Builder support such as: form_tag, form_for, field_set_tag, text_field. +Text Helpers:: Useful formatting like: time_ago_in_words, js_escape_html, sanitize_html. +Mailer:: Fast and simple delivery support for sending emails (akin to ActionMailer). +Admin:: Builtin Admin interface (like Django) +Logging:: Provide a unified logger that can interact with your ORM or any library. +Reloading:: Automatically reloads server code during development. +Localization:: Full support of I18n language localization and can auto-set user's locale. + +Keep in mind, the user will be able to pull in these components +{seperately into existing Sinatra applications}[http://www.padrinorb.com/guides/standalone-usage-in-sinatra] +or use them altogether for a comprehensive upgrade to Sinatra (a full-stack Padrino application). + +== Installation + +To install the padrino framework, simply grab the latest version from gemcutter: + + $ sudo gem install padrino + +This will install the necessary padrino gems to get you started. +Now you are ready to use this gem to enhance your sinatra projects or to create new Padrino applications. + +For a more detailed look at Padrino installation, +check out the {Installation Guide}[http://www.padrinorb.com/guides/installation]. + +== Usage + +Padrino is a framework which builds on the existing functionality and Sinatra and provides a variety of +additional tools and helpers to build upon that foundation. This README and Padrino documentation in general will focus +on the enhancements to the core Sinatra functionality. To use Padrino, one should be familiar with the basic +usage of Sinatra itself. + +Please check out the +{Understanding Sinatra}[http://www.padrinorb.com/guides/underlying-sinatra-overview] guide +to learn more about these fundamentals. + +For information on how to use a specific gem in isolation within an existing Sinatra project, checkout the guide for +{Using Padrino in Sinatra}[http://www.padrinorb.com/guides/standalone-usage-in-sinatra]. + +== Getting Started + +Once a developer understands Sinatra, Padrino is quite easy to get comfortable with since Padrino is simply a superset +of existing Sinatra Functionality! Best way to get started with building Padrino applications is to read following resources: + +* {Blog Tutorial}[http://www.padrinorb.com/guides/blog-tutorial] - Step-by-step guide to building a blog application with Padrino. +* {Quick Overview}[http://www.padrinorb.com/guides/basic-projects] - Outlines basic generation commands. +* {Padrino Examples}[http://www.padrinorb.com/guides/examples] - List of known Padrino applications which can serve as examples. + +== Enhanced Base Application (padrino-core) + +Sinatra has support for classes which can be extended to create an application: Sinatra::Base and Sinatra::Application +These classes can be extended in order to create a Sinatra web application. These classes provide support for all the basic +functionality afforded by Sinatra. + +Padrino has support for an enhanced base application class Padrino::Application. Padrino::Application +expands the capabilities of Sinatra::Application and automatically provides the resulting application access to all of +the padrino framework's functionalities. + +=== Simple Application Definition + +Let us first take a look at the simplest possible Padrino application: + + # app.rb + PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT + require 'padrino' + Padrino.load! + + class SimpleApp < Padrino::Application + get '/' do + 'Hello world' + end + + # and for read better we can divide with controllers + controller '/admin' do + get '/foo' do + 'Url is /admin/foo' + end + end + end + +=== Enhanced Route Definitions and Controllers + +For a complete overview of the Padrino routing and controller system, +check out the {Routing and Controller guide}[http://www.padrinorb.com/guides/controllers]. + +Suppose we wanted to add additional routes to our Padrino application, and we want to organize the routes +within a more structured layout. Simply add a controllers or app/controllers folder and create a file as such: + + # Simple Example + SimpleApp.controllers do + get "/test" do + "Text to return" + end + end + +You can also do more complex route alias definitions: + + # app/controllers/example.rb + SimpleApp.controllers :posts do + get :index do + ... + end + + get :show, :with => :id do + # url generated is '/posts/show/:id' + # access params[:id] + end + end + +as well as mapping the route aliases to an explicit url: + + # app/controllers/example.rb + SimpleApp.controllers do + get :index, :map => '/index' do + ... + end + + get :account, :map => '/the/accounts/:name/and/:id' do + # access params[:name] and params[:index] + end + end + +and even configure the +provides+ for each route: + + # app/controllers/example.rb + SimpleApp.controllers :admin do + get :show, :with => :id, :provides => :js do + "Url is /admin/show/#{params[:id]}.#{params[:format]}" + end + + get :other, :with => [:id, :name], :provides => [:html, :json] do + case content_type + when :js then ... end + when :json then ... end + end + end + end + +or auto lookup for current locale or content_type + + # app/controllers/example.rb + SimpleApp.controllers :admin do + get :show, :with => :id, :provides => [:html, :js] do + render "admin/show" + end + end + +When you visit :+show+ and your I18n.locale == :ru Padrino try to look for "admin/show.ru.js.*" if nothing match that path +they try "admin/show.ru.*" then "admin/show.js.*" if none match return "admin/show.erb" (or other engine i.e. haml) + +For a complete overview of the routing and controller system, check out the +{Routing and Controller guide}[http://www.padrinorb.com/guides/controllers]. + +=== Rendering + +Unlike Sinatra, Padrino supports automatic template lookups such as: + + # searches for 'account/index.{erb,haml,...} + render 'account/index' + +This render does not require any template engine to be specified and will choose the first one that is discovered. +The existing render function works as well if an engine type should be specified: + +# example.haml +render :haml, 'account/index' + +For a complete overview of the Padrino rendering system, check out the +{Routing and Controller guide}[http://www.padrinorb.com/guides/controllers]. + +=== Layout + +With Padrino you can (like rails do) use for your custom layout, disable it + + class SimpleApp < Padrino::Application + + # Disable layouts + disable layout + + # Use the layout located in views/layouts/custom.haml + layout :custom + +For a complete overview of the layout functionality, +check out the {Routing and Controller guide}[http://www.padrinorb.com/guides/controllers]. + +=== Mounting Applications + +Padrino applications are all automatically mountable into other Padrino projects. This means that a given Padrino +project directory can easily mount multiple applications. This allows for better organization of complex applications, +re-usable applications that can be applied (i.e admin, auth, blog) and even more flexibility. + +You can think of mountable applications as a 'full-featured' merb slice or rails engine. Instead of a separate construct, +any application can simply be packaged and mounted into another project. + +Padrino stores application mounting information by default within config/apps.rb. This file is intended +to keep all information regarding what applications are mounted to which uri's. + +For a complete look at mounting applications within a Padrino project, +check out the guide on {Mounting Applications}[http://www.padrinorb.com/guides/mounting-applications]. + +=== Auto Load Paths + +Padrino also intelligently supports requiring useful files within your application automatically and provides +functionality for easily splitting up your application into separate files. Padrino automatically requires config/database.rb +as a convention for establishing database connection. Also, any files within the lib folder will be required +automatically by Padrino. + +For a complete overview of auto-loaded paths within Padrino, +check out the {Padrino Development Guide}[http://www.padrinorb.com/guides/development-and-terminal-commands]. + +=== Application Logging + +Padrino also supports robust logging capabilities. By default, logging information will +go to the STDOUT in development (for use in a console) and in an environment-specific log file log/development.log +in test and production environments. + +To use the logger within a Padrino application, simply refer to the logger method accessible +within your app and any controller or views: + + # controllers/example.rb + SimpleApp.controllers do + get("/test") { logger.info "This is a test" } + end + +For a complete overview of Padrino logger functionality, check out the +{Padrino Development Guide}[http://www.padrinorb.com/guides/development-and-terminal-commands]. + +=== Development Reloader + +Padrino applications also have the enabled ability to automatically reload all changing application files without +the need to restart the server. Through the use of a customized Rack middleware, all files on the 'load path' +are monitored and reloaded whenever changes are applied. + +This makes rapid development much easier and provides a better alternative to 'shotgun' or 'rerun' +which requires the application server to be restarted which makes requests take much longer to complete. + +For a complete overview of code reloading in development, +check out the {Padrino Development Guide}[http://www.padrinorb.com/guides/development-and-terminal-commands]. + +=== Terminal Commands + +Padrino also comes equipped with multiple useful terminal commands which can be activated to perform +common tasks such as starting / stopping the application, executing the unit tests or activating an irb session. + +The following commands are available: + + # starts the app server (non-daemonized) + $ padrino start + # starts the app server (daemonized) with given port, environment and adapter + $ padrino start -d -p 3000 -e development -a thin + + # Stops a daemonized app server + $ padrino stop + + # Bootup the Padrino console (irb) + $ padrino console + + # Run/List tasks + $ padrino rake + +You can also create custom rake tasks as well. Using these commands can simplify common tasks +making development that much smoother. + +For a complete overview of Padrino terminal commands, check out the +{Padrino Commands Guide}[http://www.padrinorb.com/guides/development-and-terminal-commands]. + +== Copyright + +Copyright (c) 2011-2013 Padrino. See LICENSE for details. diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/Rakefile b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/Rakefile new file mode 100644 index 00000000..f33347d2 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/Rakefile @@ -0,0 +1,5 @@ +# coding:utf-8 +RAKE_ROOT = __FILE__ + +require 'rubygems' +require File.expand_path(File.dirname(__FILE__) + '/../gem_rake_helper') \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/bin/padrino b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/bin/padrino new file mode 100755 index 00000000..ccc4c62e --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/bin/padrino @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +require 'rubygems' unless defined?(Gem) +require 'bundler/setup' if %w(Gemfile .components).all? { |f| File.exist?(f) } + +padrino_core_path = File.expand_path('../../lib', __FILE__) +$:.unshift(padrino_core_path) if File.directory?(padrino_core_path) && !$:.include?(padrino_core_path) + +require 'padrino-core/cli/base' +Padrino::Cli::Base.start(ARGV) \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core.rb new file mode 100644 index 00000000..e2ebdd24 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core.rb @@ -0,0 +1,200 @@ +require 'sinatra/base' +require 'padrino-core/version' +require 'padrino-core/support_lite' +require 'padrino-core/application' + +require 'padrino-core/caller' +require 'padrino-core/command' +require 'padrino-core/loader' +require 'padrino-core/logger' +require 'padrino-core/mounter' +require 'padrino-core/reloader' +require 'padrino-core/router' +require 'padrino-core/server' +require 'padrino-core/tasks' +require 'padrino-core/module' + + +PADRINO_ENV = ENV["PADRINO_ENV"] ||= ENV["RACK_ENV"] ||= "development" unless defined?(PADRINO_ENV) +PADRINO_ROOT = ENV["PADRINO_ROOT"] ||= File.dirname(Padrino.first_caller) unless defined?(PADRINO_ROOT) + +module Padrino + class ApplicationLoadError < RuntimeError # @private + end + + class << self + ## + # Helper method for file references. + # + # @param [Array] args + # The directories to join to {PADRINO_ROOT}. + # + # @return [String] + # The absolute path. + # + # @example + # # Referencing a file in config called settings.yml + # Padrino.root("config", "settings.yml") + # # returns PADRINO_ROOT + "/config/setting.yml" + # + def root(*args) + File.expand_path(File.join(PADRINO_ROOT, *args)) + end + + ## + # Helper method that return {PADRINO_ENV}. + # + # @return [Symbol] + # The Padrino Environment. + # + def env + @_env ||= PADRINO_ENV.to_s.downcase.to_sym + end + + ## + # The resulting rack builder mapping each 'mounted' application. + # + # @return [Padrino::Router] + # The router for the application. + # + # @raise [ApplicationLoadError] + # No applications were mounted. + # + def application + raise ApplicationLoadError, "At least one app must be mounted!" unless Padrino.mounted_apps && Padrino.mounted_apps.any? + router = Padrino::Router.new + Padrino.mounted_apps.each { |app| app.map_onto(router) } + + if middleware.present? + builder = Rack::Builder.new + middleware.each { |c,a,b| builder.use(c, *a, &b) } + builder.run(router) + builder.to_app + else + router + end + end + + ## + # Configure Global Project Settings for mounted apps. These can be overloaded + # in each individual app's own personal configuration. This can be used like: + # + # @yield [] + # The given block will be called to configure each application. + # + # @example + # Padrino.configure_apps do + # enable :sessions + # disable :raise_errors + # end + # + def configure_apps(&block) + return unless block_given? + @@_global_configurations ||= [] + @@_global_configurations << block + @_global_configuration = lambda do |app| + @@_global_configurations.each do |configuration| + app.class_eval(&configuration) + end + end + end + + ## + # Returns project-wide configuration settings defined in + # {configure_apps} block. + # + def apps_configuration + @_global_configuration + end + + ## + # Set +Encoding.default_internal+ and +Encoding.default_external+ + # to +Encoding::UFT_8+. + # + # Please note that in +1.9.2+ with some template engines like +haml+ + # you should turn off Encoding.default_internal to prevent problems. + # + # @see https://github.com/rtomayko/tilt/issues/75 + # + # @return [NilClass] + # + def set_encoding + if RUBY_VERSION < '1.9' + $KCODE='u' + else + Encoding.default_external = Encoding::UTF_8 + Encoding.default_internal = Encoding::UTF_8 + end + nil + end + + ## + # A Rack::Builder object that allows to add middlewares in front of all + # Padrino applications. + # + # @return [Array>] + # The middleware classes. + # + def middleware + @middleware ||= [] + end + + ## + # Clears all previously configured middlewares. + # + # @return [Array] + # An empty array + # + def clear_middleware! + @middleware = [] + end + + ## + # Convenience method for adding a Middleware to the whole padrino app. + # + # @param [Class] m + # The middleware class. + # + # @param [Array] args + # The arguments for the middleware. + # + # @yield [] + # The given block will be passed to the initialized middleware. + # + def use(m, *args, &block) + middleware << [m, args, block] + end + + ## + # Registers a gem with padrino. This relieves the caller from setting up + # loadpaths by itself and enables Padrino to look up apps in gem folder. + # + # The name given has to be the proper gem name as given in the gemspec. + # + # @param [String] name + # The name of the gem being registered. + # + # @param [Module] main_module + # The main module of the gem. + # + # @returns The root path of the loaded gem + def gem(name, main_module) + _, spec = Gem.loaded_specs.find{|spec_pair| spec_pair[0] == name } + gems << spec + modules << main_module + spec.full_gem_path + end + + ## + # @returns [Gem::Specification] + def gems + @gems ||= [] + end + + ## + # @returns [] + def modules + @modules ||= [] + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application.rb new file mode 100644 index 00000000..67c5c4ab --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application.rb @@ -0,0 +1,297 @@ +require 'padrino-core/application/flash' +require 'padrino-core/application/rendering' +require 'padrino-core/application/routing' +require 'padrino-core/application/showexceptions' + +module Padrino + class ApplicationSetupError < RuntimeError + end + + ## + # Subclasses of this become independent Padrino applications + # (stemming from Sinatra::Application). + # These subclassed applications can be easily mounted into other + # Padrino applications as well. + # + class Application < Sinatra::Base + # Support for advanced routing, controllers, url_for + register Padrino::Routing + + ## + # Returns the logger for this application. + # + # @return [Padrino::Logger] Logger associated with this app. + # + def logger + Padrino.logger + end + + class << self + def inherited(base) + begun_at = Time.now + CALLERS_TO_IGNORE.concat(PADRINO_IGNORE_CALLERS) + base.default_configuration! + base.prerequisites.concat([ + File.join(base.root, '/models.rb'), + File.join(base.root, '/models/**/*.rb'), + File.join(base.root, '/lib.rb'), + File.join(base.root, '/lib/**/*.rb') + ]).uniq! + Padrino.require_dependencies(base.prerequisites) + logger.devel :setup, begun_at, base + super(base) # Loading the subclass inherited method + end + + ## + # Reloads the application files from all defined load paths. + # + # This method is used from our Padrino Reloader during development mode + # in order to reload the source files. + # + # @return [TrueClass] + # + # @example + # MyApp.reload! + # + def reload! + logger.devel "Reloading #{settings}" + reset! + reset_router! + Padrino.require_dependencies(settings.app_file, :force => true) # Reload the app file + require_dependencies + default_filters! + default_routes! + default_errors! + I18n.reload! if defined?(I18n) + true + end + + ## + # Resets application routes to only routes not defined by the user. + # + # @return [TrueClass] + # + # @example + # MyApp.reset_routes! + # + def reset_routes! + reset_router! + default_routes! + true + end + + ## + # Returns the routes of our app. + # + # @example + # MyApp.routes + # + def routes + router.routes + end + + ## + # Setup the application by registering initializers, load paths and logger. + # Invoked automatically when an application is first instantiated. + # + # @return [TrueClass] + # + def setup_application! + return if @_configured + settings.require_dependencies + settings.default_filters! + settings.default_routes! + settings.default_errors! + if defined?(I18n) + I18n.load_path << settings.locale_path + I18n.reload! + end + @_configured = true + @_configured + end + + ## + # Run the Padrino app as a self-hosted server using + # Thin, Mongrel or WEBrick (in that order). + # + # @see Padrino::Server#start + # + def run!(options={}) + return unless Padrino.load! + Padrino.mount(settings.to_s).to('/') + Padrino.run!(options) + end + + ## + # @return [Array] + # directory that need to be added to +$LOAD_PATHS+ from this application + # + def load_paths + @_load_paths ||= %w[models lib mailers controllers helpers].map { |path| File.join(settings.root, path) } + end + + ## + # Returns default list of path globs to load as dependencies. + # Appends custom dependency patterns to the be loaded for your Application. + # + # @return [Array] + # list of path globs to load as dependencies + # + # @example + # MyApp.dependencies << "#{Padrino.root}/uploaders/**/*.rb" + # MyApp.dependencies << Padrino.root('other_app', 'controllers.rb') + # + def dependencies + [ + 'urls.rb', 'config/urls.rb', 'mailers/*.rb', 'mailers.rb', + 'controllers/**/*.rb', 'controllers.rb', 'helpers/**/*.rb', 'helpers.rb' + ].map { |file| Dir[File.join(settings.root, file)] }.flatten + end + + ## + # An array of file to load before your app.rb, basically are files + # which our app depends on. + # + # By default we look for files: + # + # # List of default files that we are looking for: + # yourapp/models.rb + # yourapp/models/**/*.rb + # yourapp/lib.rb + # yourapp/lib/**/*.rb + # + # @example Adding a custom prerequisite + # MyApp.prerequisites << Padrino.root('my_app', 'custom_model.rb') + # + def prerequisites + @_prerequisites ||= [] + end + + protected + ## + # Defines default settings for Padrino application. + # + def default_configuration! + # Overwriting Sinatra defaults + set :app_file, File.expand_path(caller_files.first || $0) # Assume app file is first caller + set :environment, Padrino.env + set :reload, Proc.new { development? } + set :logging, Proc.new { development? } + set :method_override, true + set :sessions, false + set :public_folder, Proc.new { Padrino.root('public', uri_root) } + set :views, Proc.new { File.join(root, 'views') } + set :images_path, Proc.new { File.join(public_folder, 'images') } + set :protection, true + + set :haml, { :ugly => (Padrino.env == :production) } if defined?(Haml) + + # Padrino specific + set :uri_root, '/' + set :app_name, settings.to_s.underscore.to_sym + set :default_builder, 'StandardFormBuilder' + set :authentication, false + + set :locale_path, Proc.new { Dir[File.join(settings.root, '/locale/**/*.{rb,yml}')] } + + # Authenticity token + set :protect_from_csrf, false + set :allow_disabled_csrf, false + # Load the Global Configurations + class_eval(&Padrino.apps_configuration) if Padrino.apps_configuration + end + + ## + # We need to add almost __sinatra__ images. + # + def default_routes! + configure :development do + get '*__sinatra__/:image.png' do + content_type :png + filename = File.dirname(__FILE__) + "/images/#{params[:image]}.png" + send_file filename + end + end + end + + ## + # This filter it's used for know the format of the request, and + # automatically set the content type. + # + def default_filters! + before do + unless @_content_type + response['Content-Type'] = 'text/html;charset=utf-8' + end + end + end + + ## + # This log errors for production environments. + # + def default_errors! + configure :production do + error ::Exception do + boom = env['sinatra.error'] + logger.error ["#{boom.class} - #{boom.message}:", *boom.backtrace].join("\n ") + response.status = 500 + content_type 'text/html' + '

Internal Server Error

' + end unless errors.has_key?(::Exception) + end + end + + ## + # Requires all files within the application load paths. + # + def require_dependencies + Padrino.set_load_paths(*load_paths) + Padrino.require_dependencies(dependencies, :force => true) + end + + private + # Overrides the default middleware for Sinatra based on Padrino conventions. + # Also initializes the application after setting up the middleware. + def setup_default_middleware(builder) + setup_sessions builder + builder.use Padrino::ShowExceptions if show_exceptions? + builder.use Padrino::Logger::Rack, uri_root if Padrino.logger && logging? + builder.use Padrino::Reloader::Rack if reload? + builder.use Rack::MethodOverride if method_override? + builder.use Rack::Head + register Padrino::Flash + setup_protection builder + setup_csrf_protection builder + setup_application! + end + + # sets up csrf protection for the app: + def setup_csrf_protection(builder) + if protect_from_csrf? && !sessions? + raise(<<-ERROR) +`protect_from_csrf` is activated, but `sessions` are not. To enable csrf +protection, use: + + enable :sessions + +or deactivate protect_from_csrf: + + disable :protect_from_csrf +ERROR + end + + if protect_from_csrf? + if allow_disabled_csrf? + builder.use Rack::Protection::AuthenticityToken, + :reaction => :report, + :report_key => 'protection.csrf.failed', + :logger => logger + else + builder.use Rack::Protection::AuthenticityToken, + :logger => logger + end + end + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/flash.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/flash.rb new file mode 100644 index 00000000..8edfe79c --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/flash.rb @@ -0,0 +1,229 @@ +module Padrino + module Flash + + class << self + def registered(app) + app.helpers Helpers + app.after do + session[:_flash] = @_flash.next if @_flash + end + end + end + + class Storage + include Enumerable + + # @private + def initialize(session=nil) + @_now = session || {} + @_next = {} + end + + def now + @_now + end + + def next + @_next + end + + # @since 0.10.8 + # @api public + def [](type) + @_now[type] + end + + # @since 0.10.8 + # @api public + def []=(type, message) + @_next[type] = message + end + + # @since 0.10.8 + # @api public + def delete(type) + @_now.delete(type) + self + end + + # @since 0.10.8 + # @api public + def keys + @_now.keys + end + + # @since 0.10.8 + # @api public + def key?(type) + @_now.key?(type) + end + + # @since 0.10.8 + # @api public + def each(&block) + @_now.each(&block) + end + + # @since 0.10.8 + # @api public + def replace(hash) + @_now.replace(hash) + self + end + + # @since 0.10.8 + # @api public + def update(hash) + @_now.update(hash) + self + end + alias_method :merge!, :update + + # @since 0.10.8 + # @api public + def sweep + @_now.replace(@_next) + @_next = {} + self + end + + # @since 0.10.8 + # @api public + def keep(key = nil) + if key + @_next[key] = @_now[key] + else + @_next.merge!(@_now) + end + self + end + + # @since 0.10.8 + # @api public + def discard(key = nil) + if key + @_next.delete(key) + else + @_next = {} + end + self + end + + # @since 0.10.8 + # @api public + def clear + @_now.clear + end + + # @since 0.10.8 + # @api public + def empty? + @_now.empty? + end + + # @since 0.10.8 + # @api public + def to_hash + @_now.dup + end + + def length + @_now.length + end + alias_method :size, :length + + # @since 0.10.8 + # @api public + def to_s + @_now.to_s + end + + # @since 0.10.8 + # @api public + def error=(message) + self[:error] = message + end + + # @since 0.10.8 + # @api public + def error + self[:error] + end + + # @since 0.10.8 + # @api public + def notice=(message) + self[:notice] = message + end + + # @since 0.10.8 + # @api public + def notice + self[:notice] + end + + # @since 0.10.8 + # @api public + def success=(message) + self[:success] = message + end + + # @since 0.10.8 + # @api public + def success + self[:success] + end + end # Storage + + module Helpers + ### + # Overloads the existing redirect helper in-order to provide support for + # flash messages. + # + # @overload redirect(url) + # @param [String] url + # + # @overload redirect(url, status_code) + # @param [String] url + # @param [Fixnum] status_code + # + # @overload redirect(url, status_code, flash_messages) + # @param [String] url + # @param [Fixnum] status_code + # @param [Hash] flash_messages + # + # @overload redirect(url, flash_messages) + # @param [String] url + # @param [Hash] flash_messages + # + # @example + # redirect(dashboard, success: :user_created) + # redirect(new_location, 301, notice: 'This page has moved. Please update your bookmarks!!') + # + # @since 0.10.8 + # @api public + def redirect(url, *args) + flashes = args.extract_options! + + flashes.each do |type, message| + message = I18n.translate(message) if message.is_a?(Symbol) && defined?(I18n) + flash[type] = message + end + + super(url, args) + end + alias_method :redirect_to, :redirect + + ### + # Returns the flash storage object. + # + # @return [Storage] + # + # @since 0.10.8 + # @api public + def flash + @_flash ||= Storage.new(env['rack.session'] ? session[:_flash] : {}) + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/rendering.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/rendering.rb new file mode 100644 index 00000000..4b71d840 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/rendering.rb @@ -0,0 +1,317 @@ +require 'padrino-core/support_lite' unless defined?(SupportLite) + +module Padrino + ## + # Padrino enhances the Sinatra 'render' method to have support for + # automatic template engine detection, enhanced layout functionality, + # locale enabled rendering, among other features. + # + module Rendering + ## + # A SafeTemplate assumes that its output is safe. + # + module SafeTemplate + def render(*) + super.html_safe + end + end + + ## + # Exception responsible for when an expected template did not exist. + # + class TemplateNotFound < RuntimeError + end + + ## + # This is an array of file patterns to ignore. If your editor add a + # suffix during editing to your files please add it like: + # + # @example + # Padrino::Rendering::IGNORE_FILE_PATTERN << /~$/ + # + IGNORE_FILE_PATTERN = [ + /~$/ # This is for Gedit + ] unless defined?(IGNORE_FILE_PATTERN) + + ## + # Default options used in the resolve_template-method. + # + DEFAULT_RENDERING_OPTIONS = { :strict_format => false, :raise_exceptions => true } unless defined?(DEFAULT_RENDERING_OPTIONS) + + class << self + ## + # Default engine configurations for Padrino::Rendering. + # + # @return {Hash} + # The configurations, keyed by engine. + def engine_configurations + @engine_configurations ||= {} + end + + def registered(app) + included(app) + engine_configurations.each do |engine, configs| + app.set engine, configs + end + end + + def included(base) + base.send(:include, InstanceMethods) + base.extend(ClassMethods) + end + end + + ## + # Class methods responsible for rendering templates as part of a request. + # + module ClassMethods + ## + # Use layout like rails does or if a block given then like sinatra. + # If used without a block, sets the current layout for the route. + # + # By default, searches in your: + # + # +app+/+views+/+layouts+/+application+.(+haml+|+erb+|+xxx+) + # +app+/+views+/+layout_name+.(+haml+|+erb+|+xxx+) + # + # If you define +layout+ :+custom+ then searches for your layouts in + # +app+/+views+/+layouts+/+custom+.(+haml+|+erb+|+xxx+) + # +app+/+views+/+custom+.(+haml+|+erb+|+xxx+) + # + # @param [Symbol] name (:layout) + # The layout to use. + # + # @yield [] + # + def layout(name=:layout, &block) + return super(name, &block) if block_given? + @layout = name + end + + ## + # Returns the cached template file to render for a given url, + # content_type and locale. + # + # @param [Array] render_options + # + def fetch_template_file(render_options) + (@_cached_templates ||= {})[render_options] + end + + ## + # Caches the template file for the given rendering options. + # + # @param [String] template_file + # The path of the template file. + # + # @param [Array] render_options + # + def cache_template_file!(template_file, render_options) + (@_cached_templates ||= {})[render_options] = template_file || [] + end + + ## + # Returns the cached layout path. + # + # @param [Symbol, nil] given_layout + # The requested layout. + # + def fetch_layout_path(given_layout=nil) + layout_name = given_layout || @layout || :application + @_cached_layout ||= {} + cached_layout_path = @_cached_layout[layout_name] + return cached_layout_path if cached_layout_path + has_layout_at_root = Dir["#{views}/#{layout_name}.*"].any? + layout_path = has_layout_at_root ? layout_name.to_sym : File.join('layouts', layout_name.to_s).to_sym + @_cached_layout[layout_name] = layout_path unless reload_templates? + layout_path + end + end + + # Instance methods that allow enhanced rendering to function properly in Padrino. + module InstanceMethods + attr_reader :current_engine + + ## + # Get/Set the content_type + # + # @param [String, nil] type + # The Content-Type to use. + # + # @param [Symbol, nil] type. + # Look and parse the given symbol to the matched Content-Type. + # + # @param [Hash] params + # Additional params to append to the Content-Type. + # + # @example + # case content_type + # when :js then do_some + # when :css then do_another + # end + # + # content_type :js + # # => set the response with 'application/javascript' Content-Type + # content_type 'text/html' + # + # # => set directly the Content-Type to 'text/html' + # + def content_type(type=nil, params={}) + unless type.nil? + super(type, params) + @_content_type = type + end + @_content_type + end + + private + ## + # Enhancing Sinatra render functionality for: + # + # * Using layout similar to rails + # * Use render 'path/to/my/template' (without symbols) + # * Use render 'path/to/my/template' (with engine lookup) + # * Use render 'path/to/template.haml' (with explicit engine lookup) + # * Use render 'path/to/template', :layout => false + # * Use render 'path/to/template', :layout => false, :engine => 'haml' + # + def render(engine, data=nil, options={}, locals={}, &block) + + # If engine is nil, ignore engine parameter and shift up all arguments + # render nil, "index", { :layout => true }, { :localvar => "foo" } + engine, data, options = data, options, locals if engine.nil? && data + + # Data is a hash of options when no engine isn't explicit + # render "index", { :layout => true }, { :localvar => "foo" } + # Data is options, and options is locals in this case + data, options, locals = nil, data, options if data.is_a?(Hash) + + # If data is unassigned then this is a likely a template to be resolved + # This means that no engine was explicitly defined + data, engine = *resolve_template(engine, options.dup) if data.nil? + + # Use @layout if it exists + layout_was = options[:layout] + options[:layout] = @layout if options[:layout].nil? || options[:layout] == true + # Resolve layouts similar to in Rails + if options[:layout].nil? && !settings.templates.has_key?(:layout) + layout_path, layout_engine = *resolved_layout + + # We need to force layout false so sinatra don't try to render it + options[:layout] = layout_path || false + options[:layout] = false unless layout_engine == engine # TODO allow different layout engine + options[:layout_engine] = layout_engine || engine if options[:layout] + elsif options[:layout].present? + options[:layout] = settings.fetch_layout_path(options[:layout] || @layout) + end + # Default to original layout value if none found. + options[:layout] ||= layout_was + + # Cleanup the template. + @current_engine, engine_was = engine, @current_engine + @_out_buf, _buf_was = ActiveSupport::SafeBuffer.new, @_out_buf + + # Pass arguments to Sinatra render method. + super(engine, data, options.dup, locals, &block) + ensure + @current_engine = engine_was + @_out_buf = _buf_was + end + + ## + # Returns the located layout tuple to be used for the rendered template + # (if available). + # + # @example + # resolve_layout + # # => ["/layouts/custom", :erb] + # # => [nil, nil] + # + def resolved_layout + located_layout = resolve_template(settings.fetch_layout_path, :raise_exceptions => false, :strict_format => true) + located_layout ? located_layout : [nil, nil] + end + + ## + # Returns the template path and engine that match content_type (if present), + # I18n.locale. + # + # @param [String] template_path + # The path of the template. + # + # @param [Hash] options + # Additional options. + # + # @option options [Boolean] :strict_format (false) + # The resolved template must match the content_type of the request. + # + # @option options [Boolean] :raise_exceptions (false) + # Raises a {TemplateNotFound} exception if the template cannot be located. + # + # @return [Array] + # The path and format of the template. + # + # @raise [TemplateNotFound] + # The template could not be found. + # + # @example + # get "/foo", :provides => [:html, :js] do; render 'path/to/foo'; end + # # If you request "/foo.js" with I18n.locale == :ru => [:"/path/to/foo.ru.js", :erb] + # # If you request "/foo" with I18n.locale == :de => [:"/path/to/foo.de.haml", :haml] + # + def resolve_template(template_path, options={}) + began_at = Time.now + _content_type = content_type || :html + # Fetch cached template for rendering options + template_path = template_path.to_s[0] == ?/ ? template_path.to_s : "/#{template_path}" + rendering_options = [template_path, _content_type, locale] + cached_template = settings.fetch_template_file(rendering_options) + if cached_template + logger.debug :cached, began_at, cached_template[0] if settings.logging? && defined?(logger) + return cached_template + end + + # Resolve view path and options. + options.reverse_merge!(DEFAULT_RENDERING_OPTIONS) + view_path = options.delete(:views) || settings.views || "./views" + target_extension = File.extname(template_path)[1..-1] || "none" # explicit template extension + template_path = template_path.chomp(".#{target_extension}") + + # Generate potential template candidates + templates = Dir[File.join(view_path, template_path) + ".*"].map do |file| + template_engine = File.extname(file)[1..-1].to_sym # Retrieves engine extension + template_file = file.sub(view_path, '').chomp(".#{template_engine}").to_sym # retrieves template filename + [template_file, template_engine] unless IGNORE_FILE_PATTERN.any? { |pattern| template_engine.to_s =~ pattern } + end + + # Check if we have a simple content type + simple_content_type = [:html, :plain].include?(_content_type) + + # Resolve final template to render + located_template = + templates.find { |file, e| file.to_s == "#{template_path}.#{locale}.#{_content_type}" } || + templates.find { |file, e| file.to_s == "#{template_path}.#{locale}" && simple_content_type } || + templates.find { |file, e| File.extname(file.to_s) == ".#{target_extension}" or e.to_s == target_extension.to_s } || + templates.find { |file, e| file.to_s == "#{template_path}.#{_content_type}" } || + templates.find { |file, e| file.to_s == "#{template_path}" && simple_content_type } || + (!options[:strict_format] && templates.first) # If not strict, fall back to the first located template. + + raise TemplateNotFound, "Template '#{template_path}' not found in '#{view_path}'!" if !located_template && options[:raise_exceptions] + settings.cache_template_file!(located_template, rendering_options) unless settings.reload_templates? + logger.debug :template, began_at, located_template[0] if located_template && settings.logging? && defined?(logger) + located_template + end + + ## + # Return the I18n.locale if I18n is defined. + # + def locale + I18n.locale if defined?(I18n) + end + end + end +end + +require 'padrino-core/application/rendering/extensions/haml' +require 'padrino-core/application/rendering/extensions/erubis' +require 'padrino-core/application/rendering/extensions/slim' diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/rendering/extensions/erubis.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/rendering/extensions/erubis.rb new file mode 100644 index 00000000..b53433c0 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/rendering/extensions/erubis.rb @@ -0,0 +1,64 @@ +begin + require 'erubis' + + module Padrino + module Erubis + ## + # SafeBufferEnhancer is an Erubis Enhancer that compiles templates that + # are fit for using ActiveSupport::SafeBuffer as a Buffer. + # + # @api private + module SafeBufferEnhancer + def add_expr_literal(src, code) + src << " #{@bufvar}.concat((" << code << ').to_s);' + end + + def add_expr_escaped(src, code) + src << " #{@bufvar}.safe_concat " << code << ';' + end + + def add_text(src, text) + src << " #{@bufvar}.safe_concat '" << escape_text(text) << "';" unless text.empty? + end + end + + ## + # SafeBufferTemplate is the classic Erubis template, augmented with + # SafeBufferEnhancer. + # + # @api private + class SafeBufferTemplate < ::Erubis::Eruby + include SafeBufferEnhancer + end + + ## + # Modded ErubisTemplate that doesn't insist in an String as output + # buffer. + # + # @api private + class Template < Tilt::ErubisTemplate + def render(*args) + app = args.first + app_class = app.class + @padrino_app = app.kind_of?(Padrino::Application) || + (app_class.respond_to?(:erb) && app_class.erb[:engine_class] == Padrino::Erubis::SafeBufferTemplate) + super + end + + def precompiled_preamble(locals) + buf = @padrino_app ? "ActiveSupport::SafeBuffer.new" : "''" + old_postamble = super.split("\n")[0..-2] + [old_postamble, "#{@outvar} = _buf = (#{@outvar} || #{buf})"].join("\n") + end + end + end + end + + Tilt.prefer(Padrino::Erubis::Template, :erb) + + if defined? Padrino::Rendering + Padrino::Rendering.engine_configurations[:erb] = + {:engine_class => Padrino::Erubis::SafeBufferTemplate} + end +rescue LoadError +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/rendering/extensions/haml.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/rendering/extensions/haml.rb new file mode 100644 index 00000000..064ea41a --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/rendering/extensions/haml.rb @@ -0,0 +1,28 @@ +begin + require 'haml' + require 'haml/helpers/xss_mods' + require 'haml/helpers/action_view_extensions' + + module Haml + module Helpers + include XssMods + include ActionViewExtensions + end + + module Util + def self.rails_xss_safe? + true + end + end + end + + if defined? Padrino::Rendering + Padrino::Rendering.engine_configurations[:haml] = + {:escape_html => true} + + class Tilt::HamlTemplate + include Padrino::Rendering::SafeTemplate + end + end +rescue LoadError +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/rendering/extensions/slim.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/rendering/extensions/slim.rb new file mode 100644 index 00000000..e89043a8 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/rendering/extensions/slim.rb @@ -0,0 +1,14 @@ +begin + require 'slim' + + if defined? Padrino::Rendering + Padrino::Rendering.engine_configurations[:slim] = + {:generator => Temple::Generators::RailsOutputBuffer, + :buffer => "@_out_buf", :use_html_safe => true} + + class Slim::Template + include Padrino::Rendering::SafeTemplate + end + end +rescue LoadError +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/routing.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/routing.rb new file mode 100644 index 00000000..526bbdba --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/routing.rb @@ -0,0 +1,1077 @@ +require 'http_router' unless defined?(HttpRouter) +require 'padrino-core/support_lite' unless defined?(SupportLite) + +## +# Adds to Sinatra +controller+ informations +# +class Sinatra::Request + attr_accessor :route_obj + + def controller + route_obj && route_obj.controller + end + def action + route_obj && route_obj.action + end +end + + +class HttpRouter + def rewrite_partial_path_info(env, request); end + def rewrite_path_info(env, request); end + + def process_destination_path(path, env) + Thread.current['padrino.instance'].instance_eval do + request.route_obj = path.route + @_response_buffer = nil + @route = path.route + @params ||= {} + @params.update(env['router.params']) + @block_params = if match_data = env['router.request'].extra_env['router.regex_match'] + params_list = match_data.to_a + params_list.shift + @params[:captures] = params_list + params_list + else + env['router.request'].params + end + # Provide access to the current controller to the request + # Now we can eval route, but because we have "throw halt" we need to be + # (en)sure to reset old layout and run controller after filters. + original_params = @params + parent_layout = @layout + successful = false + begin + filter! :before + (@route.before_filters - settings.filters[:before]).each { |block| instance_eval(&block) } + @layout = path.route.use_layout if path.route.use_layout + @route.custom_conditions.each { |block| pass if block.bind(self).call == false } + halt_response = catch(:halt) { route_eval { @route.dest[self, @block_params] } } + @_response_buffer = halt_response.is_a?(Array) ? halt_response.last : halt_response + successful = true + halt halt_response + ensure + (@route.after_filters - settings.filters[:after]).each { |block| instance_eval(&block) } if successful + @layout = parent_layout + @params = original_params + end + end + end + + class Route + VALID_HTTP_VERBS.replace %w[GET POST PUT PATCH DELETE HEAD OPTIONS LINK UNLINK] + + attr_accessor :use_layout, :controller, :action, :cache, :cache_key, :cache_expires_in, :parent + + def before_filters(&block) + @_before_filters ||= [] + @_before_filters << block if block_given? + + @_before_filters + end + + def after_filters(&block) + @_after_filters ||= [] + @_after_filters << block if block_given? + + @_after_filters + end + + def custom_conditions(&block) + @_custom_conditions ||= [] + @_custom_conditions << block if block_given? + + @_custom_conditions + end + + def significant_variable_names + @significant_variable_names ||= if @original_path.is_a?(String) + @original_path.scan(/(^|[^\\])[:\*]([a-zA-Z0-9_]+)/).map{|p| p.last.to_sym} + elsif @original_path.is_a?(Regexp) and @original_path.respond_to?(:named_captures) + @original_path.named_captures.keys.map(&:to_sym) + else + [] + end + end + + def to(dest = nil, &dest_block) + @dest = dest || dest_block || raise("you didn't specify a destination") + + @router.current_order ||= 0 + @order = @router.current_order + @router.current_order += 1 + + if @dest.respond_to?(:url_mount=) + urlmount = UrlMount.new(@path_for_generation, @default_values || {}) # TODO url mount should accept nil here. + urlmount.url_mount = @router.url_mount if @router.url_mount + @dest.url_mount = urlmount + end + self + end + + attr_accessor :order + + end + + attr_accessor :current_order + + def sort! + @routes.sort!{ |a, b| a.order <=> b.order } + end + + class Node::SpanningRegex + def to_code + params_count = @ordered_indicies.size + whole_path_var = "whole_path#{root.next_counter}" + "#{whole_path_var} = request.joined_path + if match = #{@matcher.inspect}.match(#{whole_path_var}) and match.begin(0).zero? + _#{whole_path_var} = request.path.dup + " << param_capturing_code << " + remaining_path = #{whole_path_var}[match[0].size + (#{whole_path_var}[match[0].size] == ?/ ? 1 : 0), #{whole_path_var}.size] + request.path = remaining_path.split('/') + #{node_to_code} + request.path = _#{whole_path_var} + request.params.slice!(#{-params_count}, #{params_count}) + end + " + end + end + + # Monkey patching the Request class. Using Rack::Utils.unescape rather than + # URI.unescape which can't handle utf-8 chars + class Request + def initialize(path, rack_request) + @rack_request = rack_request + @path = path.split(/\//).map{|part| Rack::Utils.unescape(part) } + @path.shift if @path.first == '' + @path.push('') if path[-1] == ?/ + @extra_env = {} + @params = [] + @acceptable_methods = Set.new + end + end + + class Node::Path + def to_code + path_ivar = inject_root_ivar(self) + "#{"if !callback && request.path.size == 1 && request.path.first == '' && (request.rack_request.head? || request.rack_request.get?) && request.rack_request.path_info[-1] == ?/ + catch(:pass) do + response = ::Rack::Response.new + response.redirect(request.rack_request.path_info[0, request.rack_request.path_info.size - 1], 302) + return response.finish + end + end" if router.redirect_trailing_slash?} + + #{"if request.#{router.ignore_trailing_slash? ? 'path_finished?' : 'path.empty?'}" unless route.match_partially} + catch(:pass) do + if callback + request.called = true + callback.call(Response.new(request, #{path_ivar})) + else + env = request.rack_request.dup.env + env['router.request'] = request + env['router.params'] ||= {} + #{"env['router.params'].merge!(Hash[#{param_names.inspect}.zip(request.params)])" if dynamic?} + @router.rewrite#{"_partial" if route.match_partially}_path_info(env, request) + response = @router.process_destination_path(#{path_ivar}, env) + return response unless router.pass_on_response(response) + end + end + #{"end" unless route.match_partially}" + end + end +end + +module Padrino + class Filter + attr_reader :block + + def initialize(mode, scoped_controller, options, args, &block) + @mode, @scoped_controller, @options, @args, @block = mode, scoped_controller, options, args, block + end + + def apply?(request) + detect = @args.any? do |arg| + case arg + when Symbol then request.route_obj && (request.route_obj.name == arg or request.route_obj.name == [@scoped_controller, arg].flatten.join("_").to_sym) + else arg === request.path_info + end + end || @options.any? do |name, val| + case name + when :agent then val === request.user_agent + else val === request.send(name) + end + end + detect ^ !@mode + end + + def to_proc + if @args.empty? && @options.empty? + block + else + filter = self + proc { instance_eval(&filter.block) if filter.apply?(request) } + end + end + end + + ## + # Padrino provides advanced routing definition support to make routes and + # url generation much easier. This routing system supports named route + # aliases and easy access to url paths. The benefits of this is that instead + # of having to hard-code route urls into every area of your application, now + # we can just define the urls in a single spot and then attach an alias + # which can be used to refer to the url throughout the application. + # + module Routing + # Defines common content-type alias mappings. + CONTENT_TYPE_ALIASES = { :htm => :html } unless defined?(CONTENT_TYPE_ALIASES) + # Defines the available route priorities supporting route deferrals. + ROUTE_PRIORITY = {:high => 0, :normal => 1, :low => 2} unless defined?(ROUTE_PRIORITY) + + # Raised when a route was invalid or cannot be processed. + class UnrecognizedException < RuntimeError; end + + class Parent < String + attr_reader :map + attr_reader :optional + attr_reader :options + + alias_method :optional?, :optional + + def initialize(value, options={}) + super(value.to_s) + @map = options.delete(:map) + @optional = options.delete(:optional) + @options = options + end + end + + class << self + ## + # Main class that register this extension. + # + def registered(app) + app.send(:include, InstanceMethods) + app.extend(ClassMethods) + end + alias :included :registered + end + + # Class methods responsible for enhanced routing for controllers. + module ClassMethods + ## + # Method to organize our routes in a better way. + # + # @param [Array] args + # Controller arguments. + # + # @yield [] + # The given block will be used to define the routes within the + # Controller. + # + # @example + # controller :admin do + # get :index do; ...; end + # get :show, :with => :id do; ...; end + # end + # + # url(:admin_index) # => "/admin" + # url(:admin_show, :id => 1) # "/admin/show/1" + # + # @example Using named routes follow the sinatra way: + # controller "/admin" do + # get "/index" do; ...; end + # get "/show/:id" do; ...; end + # end + # + # @example Supply +:provides+ to all controller routes: + # controller :provides => [:html, :xml, :json] do + # get :index do; "respond to html, xml and json"; end + # post :index do; "respond to html, xml and json"; end + # get :foo do; "respond to html, xml and json"; end + # end + # + # @example Specify parent resources in padrino with the +:parent+ option on the controller: + # controllers :product, :parent => :user do + # get :index do + # # url is generated as "/user/#{params[:user_id]}/product" + # # url_for(:product, :index, :user_id => 5) => "/user/5/product" + # end + # get :show, :with => :id do + # # url is generated as "/user/#{params[:user_id]}/product/show/#{params[:id]}" + # # url_for(:product, :show, :user_id => 5, :id => 10) => "/user/5/product/show/10" + # end + # end + # + # @example Specify conditions to run for all routes: + # controller :conditions => {:protect => true} do + # def self.protect(protected) + # condition do + # halt 403, "No secrets for you!" unless params[:key] == "s3cr3t" + # end if protected + # end + # + # # This route will only return "secret stuff" if the user goes to + # # `/private?key=s3cr3t`. + # get("/private") { "secret stuff" } + # + # # And this one, too! + # get("/also-private") { "secret stuff" } + # + # # But you can override the conditions for each route as needed. + # # This route will be publicly accessible without providing the + # # secret key. + # get :index, :protect => false do + # "Welcome!" + # end + # end + # + # @example Supply default values: + # controller :lang => :de do + # get :index, :map => "/:lang" do; "params[:lang] == :de"; end + # end + # + # In a controller, before and after filters are scoped and don't + # affect other controllers or the main app. + # In a controller, layouts are scoped and don't affect other + # controllers or the main app. + # + # @example + # controller :posts do + # layout :post + # before { foo } + # after { bar } + # end + # + def controller(*args, &block) + if block_given? + options = args.extract_options! + + # Controller defaults. + @_controller, original_controller = args, @_controller + @_parents, original_parent = options.delete(:parent), @_parents + @_provides, original_provides = options.delete(:provides), @_provides + @_use_format, original_use_format = options.delete(:use_format), @_use_format + @_cache, original_cache = options.delete(:cache), @_cache + @_map, original_map = options.delete(:map), @_map + @_conditions, original_conditions = options.delete(:conditions), @_conditions + @_defaults, original_defaults = options, @_defaults + + # Application defaults. + @filters, original_filters = { :before => @filters[:before].dup, :after => @filters[:after].dup }, @filters + @layout, original_layout = nil, @layout + + instance_eval(&block) + + # Application defaults. + @filters = original_filters + @layout = original_layout + + # Controller defaults. + @_controller, @_parents, @_cache = original_controller, original_parent, original_cache + @_defaults, @_provides, @_map = original_defaults, original_provides, original_map + @_conditions, @_use_format = original_conditions, original_use_format + else + include(*args) if extensions.any? + end + end + alias :controllers :controller + + ## + # Add a before filter hook. + # + # @see #construct_filter + # + def before(*args, &block) + add_filter :before, &(args.empty? ? block : construct_filter(*args, &block)) + end + + ## + # Add an after filter hook. + # + # @see #construct_filter + # + def after(*args, &block) + add_filter :after, &(args.empty? ? block : construct_filter(*args, &block)) + end + + ## + # Adds a filter hook to a request. + # + def add_filter(type, &block) + filters[type] << block + end + + ## + # Creates a filter to process before/after the matching route. + # + # @param [Array] args + # + # @example We are be able to filter with String path + # before('/') { 'only to :index' } + # get(:index} { 'foo' } # => filter match only before this. + # get(:main) { 'bar' } + # + # @example is the same of + # before(:index) { 'only to :index' } + # get(:index} { 'foo' } # => filter match only before this. + # get(:main) { 'bar' } + # + # @example it works only for the given controller + # controller :foo do + # before(:index) { 'only to for :foo_index' } + # get(:index} { 'foo' } # => filter match only before this. + # get(:main) { 'bar' } + # end + # + # controller :bar do + # before(:index) { 'only to for :bar_index' } + # get(:index} { 'foo' } # => filter match only before this. + # get(:main) { 'bar' } + # end + # + # @example if filters based on a symbol or regexp + # before :index, /main/ do; ... end + # # => match only path that are +/+ or contains +main+ + # + # @example filtering everything except an occurrence + # before :except => :index do; ...; end + # + # @example you can also filter using a request param + # before :agent => /IE/ do; ...; end + # # => match +HTTP_USER_AGENT+ containing +IE+ + # + # @see http://www.padrinorb.com/guides/controllers#route-filters + # + def construct_filter(*args, &block) + options = args.last.is_a?(Hash) ? args.pop : {} + except = options.key?(:except) && Array(options.delete(:except)) + raise("You cannot use except with other options specified") if except && (!args.empty? || !options.empty?) + options = except.last.is_a?(Hash) ? except.pop : {} if except + Filter.new(!except, @_controller, options, Array(except || args), &block) + end + + ## + # Provides many parents with shallowing. + # + # @param [Symbol] name + # The parent name. + # + # @param [Hash] options + # Additional options. + # + # @example + # controllers :product do + # parent :shop, :optional => true, :map => "/my/stand" + # parent :category, :optional => true + # get :show, :with => :id do + # # generated urls: + # # "/product/show/#{params[:id]}" + # # "/my/stand/#{params[:shop_id]}/product/show/#{params[:id]}" + # # "/my/stand/#{params[:shop_id]}/category/#{params[:category_id]}/product/show/#{params[:id]}" + # # url_for(:product, :show, :id => 10) => "/product/show/10" + # # url_for(:product, :show, :shop_id => 5, :id => 10) => "/my/stand/5/product/show/10" + # # url_for(:product, :show, :shop_id => 5, :category_id => 1, :id => 10) => "/my/stand/5/category/1/product/show/10" + # end + # end + # + def parent(name, options={}) + defaults = { :optional => false, :map => name.to_s } + options = defaults.merge(options) + @_parents = Array(@_parents) unless @_parents.is_a?(Array) + @_parents << Parent.new(name, options) + end + + ## + # Using HttpRouter, for features and configurations. + # + # @example + # router.add('/greedy/:greed') + # router.recognize('/simple') + # + # @see http://github.com/joshbuddy/http_router + # + def router + @router ||= HttpRouter.new + block_given? ? yield(@router) : @router + end + alias :urls :router + + def compiled_router + if @deferred_routes + deferred_routes.each { |routes| routes.each { |(route, dest)| route.to(dest) } } + @deferred_routes = nil + router.sort! + end + router + end + + def deferred_routes + @deferred_routes ||= ROUTE_PRIORITY.map{[]} + end + + def reset_router! + @deferred_routes = nil + router.reset! + end + + ## + # Recognize a given path. + # + # @param [String] path + # Path+Query to parse + # + # @return [Symbol, Hash] + # Returns controller and query params. + # + # @example Giving a controller like: + # controller :foo do + # get :bar, :map => 'foo-bar-:id'; ...; end + # end + # + # @example You should be able to reverse: + # MyApp.url(:foo_bar, :id => :mine) + # # => /foo-bar-mine + # + # @example Into this: + # MyApp.recognize_path('foo-bar-mine') + # # => [:foo_bar, :id => :mine] + # + def recognize_path(path) + responses = @router.recognize(Rack::MockRequest.env_for(path)) + responses = responses[0] if responses[0].is_a?(Array) + [responses[0].path.route.name, responses[0].params] + end + + ## + # Instance method for url generation. + # + # @example + # url(:show, :id => 1) + # url(:show, :name => 'test', :id => 24) + # url(:show, 1) + # url(:controller_name, :show, :id => 21) + # url(:controller_show, :id => 29) + # + def url(*args) + params = args.extract_options! # parameters is hash at end + names, params_array = args.partition{|a| a.is_a?(Symbol)} + name = names.join("_").to_sym # route name is concatenated with underscores + if params.is_a?(Hash) + params[:format] = params[:format].to_s unless params[:format].nil? + params = value_to_param(params) + end + url = + if params_array.empty? + compiled_router.path(name, params) + else + compiled_router.path(name, *(params_array << params)) + end + url[0,0] = conform_uri(uri_root) if defined?(uri_root) + url[0,0] = conform_uri(ENV['RACK_BASE_URI']) if ENV['RACK_BASE_URI'] + url = "/" if url.blank? + url + rescue HttpRouter::InvalidRouteException + route_error = "route mapping for url(#{name.inspect}) could not be found!" + raise Padrino::Routing::UnrecognizedException.new(route_error) + end + alias :url_for :url + + def get(path, *args, &block) + conditions = @conditions.dup + route('GET', path, *args, &block) + + @conditions = conditions + route('HEAD', path, *args, &block) + end + + private + # Parse params from the url method + def value_to_param(value) + case value + when Array + value.map { |v| value_to_param(v) }.compact + when Hash + value.inject({}) do |memo, (k,v)| + v = value_to_param(v) + memo[k] = v unless v.nil? + memo + end + when nil then nil + else value.respond_to?(:to_param) ? value.to_param : value + end + end + + # Add prefix slash if its not present and remove trailing slashes. + def conform_uri(uri_string) + uri_string.gsub(/^(?!\/)(.*)/, '/\1').gsub(/[\/]+$/, '') + end + + ## + # Rewrite default routes. + # + # @example + # get :index # => "/" + # get :index, "/" # => "/" + # get :index, :map => "/" # => "/" + # get :show, "/show-me" # => "/show-me" + # get :show, :map => "/show-me" # => "/show-me" + # get "/foo/bar" # => "/show" + # get :index, :parent => :user # => "/user/:user_id/index" + # get :show, :with => :id, :parent => :user # => "/user/:user_id/show/:id" + # get :show, :with => :id # => "/show/:id" + # get [:show, :id] # => "/show/:id" + # get :show, :with => [:id, :name] # => "/show/:id/:name" + # get [:show, :id, :name] # => "/show/:id/:name" + # get :list, :provides => :js # => "/list.{:format,js)" + # get :list, :provides => :any # => "/list(.:format)" + # get :list, :provides => [:js, :json] # => "/list.{!format,js|json}" + # get :list, :provides => [:html, :js, :json] # => "/list(.{!format,js|json})" + # get :list, :priority => :low # Defers route to be last + # get /pattern/, :name => :foo, :generate_with => '/foo' # Generates :foo as /foo + def route(verb, path, *args, &block) + options = case args.size + when 2 + args.last.merge(:map => args.first) + when 1 + map = args.shift if args.first.is_a?(String) + if args.first.is_a?(Hash) + map ? args.first.merge(:map => map) : args.first + else + {:map => map || args.first} + end + when 0 + {} + else raise + end + + # Do padrino parsing. We dup options so we can build HEAD request correctly. + route_options = options.dup + route_options[:provides] = @_provides if @_provides + + # CSRF protection is always active except when explicitly switched off. + if allow_disabled_csrf + unless route_options[:csrf_protection] == false + route_options[:csrf_protection] = true + end + end + + path, *route_options[:with] = path if path.is_a?(Array) + action = path + path, name, route_parents, options, route_options = *parse_route(path, route_options, verb) + options.reverse_merge!(@_conditions) if @_conditions + + # Sinatra defaults + method_name = "#{verb} #{path}" + unbound_method = generate_method(method_name, &block) + + block = block.arity != 0 ? + proc { |a,p| unbound_method.bind(a).call(*p) } : + proc { |a,p| unbound_method.bind(a).call } + + invoke_hook(:route_added, verb, path, block) + + # HTTPRouter route construction + route = router.add(path, route_options) + route.name = name if name + route.action = action + priority_name = options.delete(:priority) || :normal + priority = ROUTE_PRIORITY[priority_name] or raise("Priority #{priority_name} not recognized, try #{ROUTE_PRIORITY.keys.join(', ')}") + route.cache = options.key?(:cache) ? options.delete(:cache) : @_cache + route.parent = route_parents ? (route_parents.count == 1 ? route_parents.first : route_parents) : route_parents + route.add_request_method(verb.downcase.to_sym) + route.host = options.delete(:host) if options.key?(:host) + route.user_agent = options.delete(:agent) if options.key?(:agent) + if options.key?(:default_values) + defaults = options.delete(:default_values) + route.add_default_values(defaults) if defaults + end + options.delete_if do |option, _args| + if route.significant_variable_names.include?(option) + route.add_match_with(option => Array(_args).first) + true + end + end + + # Add Sinatra conditions. + options.each { |o, a| route.respond_to?(o) ? route.send(o, *a) : send(o, *a) } + conditions, @conditions = @conditions, [] + route.custom_conditions.concat(conditions) + + invoke_hook(:padrino_route_added, route, verb, path, args, options, block) + + # Add Application defaults. + route.before_filters.concat(@filters[:before]) + route.after_filters.concat(@filters[:after]) + if @_controller + route.use_layout = @layout + route.controller = Array(@_controller)[0].to_s + end + + deferred_routes[priority] << [route, block] + + route + end + + ## + # Returns the final parsed route details (modified to reflect all + # Padrino options) given the raw route. Raw route passed in could be + # a named alias or a string and is parsed to reflect provides formats, + # controllers, parents, 'with' parameters, and other options. + # + def parse_route(path, options, verb) + route_options = {} + + # We need check if path is a symbol, if that it's a named route. + map = options.delete(:map) + + # path i.e :index or :show + if path.kind_of?(Symbol) + name = path + path = map ? map.dup : (path == :index ? '/' : path.to_s) + end + + # Build our controller + controller = Array(@_controller).map(&:to_s) + + case path + when String # path i.e "/index" or "/show" + # Now we need to parse our 'with' params + if with_params = options.delete(:with) + path = process_path_for_with_params(path, with_params) + end + + # Now we need to parse our provides + options.delete(:provides) if options[:provides].nil? + + if @_use_format or format_params = options[:provides] + process_path_for_provides(path, format_params) + # options[:add_match_with] ||= {} + # options[:add_match_with][:format] = /[^\.]+/ + end + + absolute_map = map && map[0] == ?/ + + unless controller.empty? + # Now we need to add our controller path only if not mapped directly + if map.blank? and !absolute_map + controller_path = controller.join("/") + path.gsub!(%r{^\(/\)|/\?}, "") + path = File.join(controller_path, path) unless @_map + end + end + + # Now we need to parse our 'parent' params and parent scope. + if !absolute_map and parent_params = options.delete(:parent) || @_parents + parent_params = (Array(@_parents) + Array(parent_params)).uniq + path = process_path_for_parent_params(path, parent_params) + end + + # Add any controller level map to the front of the path. + path = "#{@_map}/#{path}".squeeze('/') unless absolute_map or @_map.blank? + + # Small reformats + path.gsub!(%r{/\?$}, '(/)') # Remove index path + path.gsub!(%r{//$}, '/') # Remove index path + path[0,0] = "/" if path !~ %r{^\(?/} # Paths must start with a / + path.sub!(%r{/(\))?$}, '\\1') if path != "/" # Remove latest trailing delimiter + path.gsub!(/\/(\(\.|$)/, '\\1') # Remove trailing slashes + path.squeeze!('/') + when Regexp + route_options[:path_for_generation] = options.delete(:generate_with) if options.key?(:generate_with) + end + + name = options.delete(:route_name) if name.nil? && options.key?(:route_name) + name = options.delete(:name) if name.nil? && options.key?(:name) + if name + controller_name = controller.join("_") + name = "#{controller_name}_#{name}".to_sym unless controller_name.blank? + end + + # Merge in option defaults. + options.reverse_merge!(:default_values => @_defaults) + + [path, name, parent_params, options, route_options] + end + + ## + # Processes the existing path and appends the 'with' parameters onto the route + # Used for calculating path in route method. + # + def process_path_for_with_params(path, with_params) + File.join(path, Array(with_params).map(&:inspect).join("/")) + end + + ## + # Processes the existing path and prepends the 'parent' parameters onto the route + # Used for calculating path in route method. + # + def process_path_for_parent_params(path, parent_params) + parent_prefix = parent_params.flatten.compact.uniq.map do |param| + map = (param.respond_to?(:map) && param.map ? param.map : param.to_s) + part = "#{map}/:#{param.to_s.singularize}_id/" + part = "(#{part})" if param.respond_to?(:optional) && param.optional? + part + end + + [parent_prefix, path].flatten.join("") + end + + ## + # Processes the existing path and appends the 'format' suffix onto the route. + # Used for calculating path in route method. + # + def process_path_for_provides(path, format_params) + path << "(.:format)" unless path[-10, 10] == '(.:format)' + end + + ## + # Allows routing by MIME-types specified in the URL or ACCEPT header. + # + # By default, if a non-provided mime-type is specified in a URL, the + # route will not match an thus return a 404. + # + # Setting the :treat_format_as_accept option to true allows treating + # missing mime types specified in the URL as if they were specified + # in the ACCEPT header and thus return 406. + # + # If no type is specified, the first in the provides-list will be + # returned. + # + # @example + # get "/a", :provides => [:html, :js] + # # => GET /a => :html + # # => GET /a.js => :js + # # => GET /a.xml => 404 + # + # get "/b", :provides => [:html] + # # => GET /b; ACCEPT: html => html + # # => GET /b; ACCEPT: js => 406 + # + # enable :treat_format_as_accept + # get "/c", :provides => [:html, :js] + # # => GET /c.xml => 406 + # + def provides(*types) + @_use_format = true + condition do + mime_types = types.map { |t| mime_type(t) }.compact + url_format = params[:format].to_sym if params[:format] + accepts = request.accept.map(&:to_str) + + # Per rfc2616-sec14: + # Assume */* if no ACCEPT header is given. + catch_all = (accepts.delete "*/*" || accepts.empty?) + matching_types = accepts.empty? ? mime_types.slice(0,1) : (accepts & mime_types) + if matching_types.empty? && types.include?(:any) + matching_types = accepts + end + + if !url_format && matching_types.first + type = ::Rack::Mime::MIME_TYPES.find { |k, v| v == matching_types.first }[0].sub(/\./,'').to_sym + accept_format = CONTENT_TYPE_ALIASES[type] || type + elsif catch_all && !types.include?(:any) + type = types.first + accept_format = CONTENT_TYPE_ALIASES[type] || type + end + + matched_format = types.include?(:any) || + types.include?(accept_format) || + types.include?(url_format) || + ((!url_format) && request.accept.empty? && types.include?(:html)) + + # Per rfc2616-sec14: + # Answer with 406 if accept is given but types to not match any + # provided type. + halt 406 if + (!url_format && !accepts.empty? && !matched_format) || + (settings.respond_to?(:treat_format_as_accept) && settings.treat_format_as_accept && url_format && !matched_format) + + if matched_format + @_content_type = url_format || accept_format || :html + content_type(@_content_type, :charset => 'utf-8') + end + + matched_format + end + end + + ## + # Implements CSRF checking when `allow_disabled_csrf` is set to true. + # + # This condition is always on, except when it is explicitly switched + # off. + # + # @example + # post("/", :csrf_protection => false) + # + def csrf_protection(on = true) + if on + condition { halt 403 if request.env['protection.csrf.failed'] } + end + end + end + + ## + # Instance methods related to recognizing and processing routes and serving static files. + # + module InstanceMethods + ## + # Instance method for URL generation. + # + # @example + # url(:show, :id => 1) + # url(:show, :name => :test) + # url(:show, 1) + # url("/foo") + # + # @see Padrino::Routing::ClassMethods#url + # + def url(*args) + # Delegate to Sinatra 1.2 for simple url("/foo") + # http://www.sinatrarb.com/intro#Generating%20URLs + return super if args.first.is_a?(String) && !args[1].is_a?(Hash) + + # Delegate to Padrino named route URL generation. + settings.url(*args) + end + alias :url_for :url + + ## + # Returns absolute url. Calls Sinatra::Helpers#uri to generate protocol version, hostname and port. + # + # @example + # absolute_url(:show, :id => 1) # => http://example.com/show?id=1 + # absolute_url(:show, 24) # => https://example.com/admin/show/24 + # + def absolute_url( *args ) + uri url(*args), true, false + end + + def recognize_path(path) + settings.recognize_path(path) + end + + ## + # Returns the current path within a route from specified +path_params+. + # + def current_path(*path_params) + if path_params.last.is_a?(Hash) + path_params[-1] = params.merge(path_params[-1]) + else + path_params << params + end + @route.path(*path_params) + end + + ## + # Returns the current route + # + # @example + # -if route.controller == :press + # %li=show_article + # + def route + @route + end + + ## + # This is mostly just a helper so request.path_info isn't changed when + # serving files from the public directory. + # + def static_file?(path_info) + return if (public_dir = settings.public_folder).nil? + public_dir = File.expand_path(public_dir) + path = File.expand_path(public_dir + unescape(path_info)) + return if path[0, public_dir.length] != public_dir + return unless File.file?(path) + return path + end + + # + # Method for deliver static files. + # + def static! + if path = static_file?(request.path_info) + env['sinatra.static_file'] = path + cache_control(*settings.static_cache_control) if settings.static_cache_control? + send_file(path, :disposition => nil) + end + end + + ## + # Return the request format, this is useful when we need to respond to + # a given Content-Type. + # + # @param [Symbol, nil] type + # + # @param [Hash] params + # + # @example + # get :index, :provides => :any do + # case content_type + # when :js then ... + # when :json then ... + # when :html then ... + # end + # end + # + def content_type(type=nil, params={}) + unless type.nil? + super(type, params) + @_content_type = type + end + @_content_type + end + + private + + def filter!(type, base=settings) + base.filters[type].each { |block| instance_eval(&block) } + end + + def dispatch! + invoke do + static! if settings.static? && (request.get? || request.head?) + route! + end + rescue ::Exception => boom + filter! :before if boom.kind_of? ::Sinatra::NotFound + invoke { @boom_handled = handle_exception!(boom) } + ensure + @boom_handled or begin + filter! :after unless env['sinatra.static_file'] + rescue ::Exception => boom + invoke { handle_exception!(boom) } unless @env['sinatra.error'] + end + end + + def route!(base=settings, pass_block=nil) + Thread.current['padrino.instance'] = self + if base.compiled_router and match = base.compiled_router.call(@request.env) + if match.respond_to?(:each) + route_eval do + match[1].each { |k,v| response[k] = v } + status match[0] + route_missing if match[0] == 404 + route_missing if allow = response['Allow'] and allow.include?(request.env['REQUEST_METHOD']) + end + end + else + filter! :before + end + + # Run routes defined in superclass. + if base.superclass.respond_to?(:router) + route!(base.superclass, pass_block) + return + end + + route_eval(&pass_block) if pass_block + + route_missing + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/showexceptions.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/showexceptions.rb new file mode 100644 index 00000000..000d7bb3 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/application/showexceptions.rb @@ -0,0 +1,21 @@ +module Padrino + ## + # This module extend Sinatra::ShowExceptions adding Padrino as "Framework". + # + # @private + class ShowExceptions < Sinatra::ShowExceptions + private + + def frame_class(frame) + if frame.filename =~ /lib\/sinatra.*\.rb|lib\/padrino.*\.rb/ + "framework" + elsif (defined?(Gem) && frame.filename.include?(Gem.dir)) || + frame.filename =~ /\/bin\/(\w+)$/ || + frame.filename =~ /Ruby\/Gems/ + "system" + else + "app" + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/caller.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/caller.rb new file mode 100644 index 00000000..6b7837b0 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/caller.rb @@ -0,0 +1,53 @@ +module Padrino + + # List of callers in a Padrino application that should be ignored as part of a stack trace. + PADRINO_IGNORE_CALLERS = [ + %r{lib/padrino-.*$}, + %r{/padrino-.*/(lib|bin)}, + %r{/bin/padrino$}, + %r{/sinatra(/(base|main|showexceptions))?\.rb$}, + %r{lib/tilt.*\.rb$}, + %r{lib/rack.*\.rb$}, + %r{lib/mongrel.*\.rb$}, + %r{lib/shotgun.*\.rb$}, + %r{bin/shotgun$}, + %r{\(.*\)}, + %r{shoulda/context\.rb$}, + %r{mocha/integration}, + %r{test/unit}, + %r{rake_test_loader\.rb}, + %r{custom_require\.rb$}, + %r{active_support}, + %r{/thor} + ] unless defined?(PADRINO_IGNORE_CALLERS) + + ## + # Add rubinius (and hopefully other VM implementations) ignore patterns ... + # + PADRINO_IGNORE_CALLERS.concat(RUBY_IGNORE_CALLERS) if defined?(RUBY_IGNORE_CALLERS) + + private + ## + # The filename for the file that is the direct caller (first caller). + # + # @return [String] + # The file the caller method exists in. + # + def self.first_caller + caller_files.first + end + + # + # Like +Kernel#caller+ but excluding certain magic entries and without + # line / method information; the resulting array contains filenames only. + # + # @return [Array] + # The files of the calling methods. + # + def self.caller_files + caller(1). + map { |line| line.split(/:(?=\d|in )/)[0,2] }. + reject { |file,line| PADRINO_IGNORE_CALLERS.any? { |pattern| file =~ pattern } }. + map { |file,line| file } + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/adapter.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/adapter.rb new file mode 100644 index 00000000..d50badd2 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/adapter.rb @@ -0,0 +1,24 @@ +module Padrino + module Cli + module Adapter + class << self + # Start for the given options a rackup handler + def start(options) + Padrino.run!(options.symbolize_keys) + end + + # Method that stop (if exist) a running Padrino.application + def stop(options) + options.symbolize_keys! + if File.exist?(options[:pid]) + pid = File.read(options[:pid]).to_i + print "=> Sending INT to process with pid #{pid} wait " + Process.kill(2, pid) rescue nil + else + puts "=> #{options[:pid]} not found!" + end + end + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/base.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/base.rb new file mode 100644 index 00000000..81b36de0 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/base.rb @@ -0,0 +1,159 @@ +require 'thor' + +module Padrino + module Cli + + class Base < Thor + include Thor::Actions + + class_option :chdir, :type => :string, :aliases => "-c", :desc => "Change to dir before starting." + class_option :environment, :type => :string, :aliases => "-e", :required => true, :default => :development, :desc => "Padrino Environment." + class_option :help, :type => :boolean, :desc => "Show help usage" + + desc "start", "Starts the Padrino application (alternatively use 's')." + map "s" => :start + method_option :server, :type => :string, :aliases => "-a", :desc => "Rack Handler (default: autodetect)" + method_option :host, :type => :string, :aliases => "-h", :required => true, :default => '127.0.0.1', :desc => "Bind to HOST address." + method_option :port, :type => :numeric, :aliases => "-p", :required => true, :default => 3000, :desc => "Use PORT." + method_option :daemonize, :type => :boolean, :aliases => "-d", :desc => "Run daemonized in the background." + method_option :pid, :type => :string, :aliases => "-i", :desc => "File to store pid." + method_option :debug, :type => :boolean, :desc => "Set debugging flags." + def start + prepare :start + require File.expand_path("../adapter", __FILE__) + require File.expand_path('config/boot.rb') + Padrino::Cli::Adapter.start(options) + end + + desc "stop", "Stops the Padrino application (alternatively use 'st')." + map "st" => :stop + method_option :pid, :type => :string, :aliases => "-p", :desc => "File to store pid", :default => 'tmp/pids/server.pid' + def stop + prepare :stop + require File.expand_path("../adapter", __FILE__) + Padrino::Cli::Adapter.stop(options) + end + + desc "rake", "Execute rake tasks." + method_option :environment, :type => :string, :aliases => "-e", :required => true, :default => :development + method_option :list, :type => :string, :aliases => "-T", :desc => "Display the tasks (matching optional PATTERN) with descriptions, then exit." + method_option :trace, :type => :boolean, :aliases => "-t", :desc => "Turn on invoke/execute tracing, enable full backtrace." + def rake(*args) + prepare :rake + args << "-T" if options[:list] + args << options[:list] unless options[:list].nil? || options[:list].to_s == "list" + args << "--trace" if options[:trace] + args << "--verbose" if options[:verbose] + ARGV.clear + ARGV.concat(args) + puts "=> Executing Rake #{ARGV.join(' ')} ..." + load File.expand_path('../rake.rb', __FILE__) + Rake.application.init + Rake.application.instance_variable_set(:@rakefile, __FILE__) + load File.expand_path('Rakefile') + Rake.application.top_level + end + + desc "console", "Boots up the Padrino application irb console (alternatively use 'c')." + map "c" => :console + def console(*args) + prepare :console + require File.expand_path("../../version", __FILE__) + ARGV.clear + require 'irb' + require "irb/completion" + require File.expand_path('config/boot.rb') + puts "=> Loading #{Padrino.env} console (Padrino v.#{Padrino.version})" + require File.expand_path('../console', __FILE__) + IRB.start + end + + desc "generate", "Executes the Padrino generator with given options (alternatively use 'gen' or 'g')." + map ["gen", "g"] => :generate + def generate(*args) + begin + # We try to load the vendored padrino-gen if exist + padrino_gen_path = File.expand_path('../../../../../padrino-gen/lib', __FILE__) + $:.unshift(padrino_gen_path) if File.directory?(padrino_gen_path) && !$:.include?(padrino_gen_path) + require 'padrino-core/command' + require 'padrino-gen/command' + ARGV.shift + ARGV << 'help' if ARGV.empty? + Padrino.bin_gen(*ARGV) + rescue + puts "<= You need padrino-gen! Run: gem install padrino-gen" + end + end + + desc "version", "Show current Padrino version." + map ["-v", "--version"] => :version + def version + require 'padrino-core/version' + puts "Padrino v. #{Padrino.version}" + end + + desc "runner", "Run a piece of code in the Padrino application environment (alternatively use 'run' or 'r')." + map ["run", "r"] => :runner + def runner(*args) + prepare :runner + + code_or_file = args.shift + abort "Please specify code or file" if code_or_file.nil? + + require File.expand_path('config/boot.rb') + + if File.exist?(code_or_file) + eval(File.read(code_or_file), nil, code_or_file) + else + eval(code_or_file) + end + end + + private + + def prepare(task) + if options.help? + help(task.to_s) + raise SystemExit + end + ENV["PADRINO_ENV"] ||= ENV["RACK_ENV"] ||= options.environment.to_s + chdir(options.chdir) + unless File.exist?('config/boot.rb') + puts "=> Could not find boot file in: #{options.chdir}/config/boot.rb !!!" + raise SystemExit + end + end + + protected + + def self.banner(task=nil, *args) + "padrino #{task.name}" + end + + def chdir(dir) + return unless dir + begin + Dir.chdir(dir.to_s) + rescue Errno::ENOENT + puts "=> Specified Padrino root '#{dir}' does not appear to exist!" + rescue Errno::EACCES + puts "=> Specified Padrino root '#{dir}' cannot be accessed by the current user!" + end + end + + def capture(stream) + begin + stream = stream.to_s + eval "$#{stream} = StringIO.new" + yield + result = eval("$#{stream}").string + ensure + eval("$#{stream} = #{stream.upcase}") + end + + result + end + alias :silence :capture + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/console.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/console.rb new file mode 100644 index 00000000..c1acde4e --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/console.rb @@ -0,0 +1,20 @@ +# Reloads classes +def reload! + Padrino.reload! +end + +# Show applications +def applications + puts "==== List of Mounted Applications ====\n\n" + Padrino.mounted_apps.each do |app| + puts " * %-10s mapped to %s" % [app.name, app.uri_root] + end + puts + Padrino.mounted_apps.map { |app| "#{app.name} => #{app.uri_root}" } +end + +# Load apps +Padrino.mounted_apps.each do |app| + puts "=> Loading Application #{app.app_class}" + app.app_obj.setup_application! +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/rake.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/rake.rb new file mode 100644 index 00000000..465ed755 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/rake.rb @@ -0,0 +1,47 @@ +require File.expand_path('../../tasks', __FILE__) +require 'rake' +require 'rake/dsl_definition' +require 'thor' +require 'securerandom' unless defined?(SecureRandom) +require 'padrino-gen' + +module PadrinoTasks + def self.init(init=false) + $LOAD_PATH.unshift(File.expand_path("lib")) + Padrino::Tasks.files.flatten.uniq.each { |rakefile| Rake.application.add_import(rakefile) rescue puts "<= Failed load #{ext}" } + load(File.expand_path('../rake_tasks.rb', __FILE__)) + Rake.application.load_imports + end + + def self.use(task) + tasks << task + end + + def self.tasks + @tasks ||= [] + end + + def self.load?(task, constant_present) + if constant_present && !PadrinoTasks.tasks.include?(task) + warn <<-WARNING.undent + Loading #{task} tasks automatically. + This functionality will be disabled in future versions. Please put + + PadrinoTasks.use(#{task.inspect}) + PadrinoTasks.init + + and remove + + require File.expand_path('../config/boot.rb', __FILE__) + + in you Rakefile instead. + WARNING + end + + constant_present || PadrinoTasks.tasks.include?(task) + end +end + +def shell + @_shell ||= Thor::Base.shell.new +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/rake_tasks.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/rake_tasks.rb new file mode 100644 index 00000000..bed51675 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/cli/rake_tasks.rb @@ -0,0 +1,52 @@ +Dir["{lib/tasks/**,tasks/**,test,spec}/*.rake"].each do |file| + begin + load(file) + rescue LoadError => e + warn "#{file}: #{e.message}" + end +end + +# Loads the Padrino applications mounted within the project. +# Setting up the required environment for Padrino. +task :environment do + require File.expand_path('config/boot.rb', Rake.application.original_dir) + + Padrino.mounted_apps.each do |app| + app.app_obj.setup_application! + end +end + +desc "Generate a secret key" +task :secret do + shell.say SecureRandom.hex(32) +end + +def list_app_routes(app, args) + app_routes = app.named_routes + app_routes.reject! { |r| r.identifier.to_s !~ /#{args.query}/ } if args.query.present? + app_routes.map! { |r| [r.verb, r.name, r.path] } + return if app_routes.empty? + shell.say "\nApplication: #{app.app_class}", :yellow + app_routes.unshift(["REQUEST", "URL", "PATH"]) + max_col_1 = app_routes.max { |a, b| a[0].size <=> b[0].size }[0].size + max_col_2 = app_routes.max { |a, b| a[1].size <=> b[1].size }[1].size + app_routes.each_with_index do |row, i| + message = [row[1].ljust(max_col_2+2), row[0].center(max_col_1+2), row[2]] + shell.say(" " + message.join(" "), i==0 ? :bold : nil) + end +end + +desc "Displays a listing of the named routes within a project, optionally only those matched by [query]" +task :routes, [:query] => :environment do |t, args| + Padrino.mounted_apps.each do |app| + list_app_routes(app, args) + end +end + +desc "Displays a listing of the named routes a given app [app]" +namespace :routes do + task :app, [:app] => :environment do |t, args| + app = Padrino.mounted_apps.find { |app| app.app_class == args.app } + list_app_routes(app, args) if app + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/command.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/command.rb new file mode 100644 index 00000000..4883b4d6 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/command.rb @@ -0,0 +1,38 @@ +require 'rbconfig' + +module Padrino + ## + # This method return the correct location of padrino bin or + # exec it using Kernel#system with the given args. + # + # @param [Array] args + # command or commands to execute + # + # @return [Boolean] + # + # @example + # Padrino.bin('start', '-e production') + # + def self.bin(*args) + @_padrino_bin ||= [self.ruby_command, File.expand_path("../../../bin/padrino", __FILE__)] + args.empty? ? @_padrino_bin : system(args.unshift(@_padrino_bin).join(" ")) + end + + ## + # Return the path to the ruby interpreter taking into account multiple + # installations and windows extensions. + # + # @return [String] + # path to ruby bin executable + # + def self.ruby_command + @ruby_command ||= begin + ruby = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name']) + ruby << RbConfig::CONFIG['EXEEXT'] + + # escape string in case path to ruby executable contain spaces. + ruby.sub!(/.*\s.*/m, '"\&"') + ruby + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/images/404.png b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/images/404.png new file mode 100644 index 00000000..2dc2538a Binary files /dev/null and b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/images/404.png differ diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/images/500.png b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/images/500.png new file mode 100644 index 00000000..87187a11 Binary files /dev/null and b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/images/500.png differ diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/loader.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/loader.rb new file mode 100644 index 00000000..894a0ca2 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/loader.rb @@ -0,0 +1,224 @@ +module Padrino + class << self + ## + # Hooks to be called before a load/reload. + # + # @yield [] + # The given block will be called before Padrino was loaded/reloaded. + # + # @return [Array] + # The load/reload before hooks. + # + # @example + # before_load do + # pre_initialize_something + # end + # + def before_load(&block) + @_before_load ||= [] + @_before_load << block if block_given? + @_before_load + end + + ## + # Hooks to be called after a load/reload. + # + # @yield [] + # The given block will be called after Padrino was loaded/reloaded. + # + # @return [Array] + # The load/reload hooks. + # + # @example + # after_load do + # DataMapper.finalize + # end + # + def after_load(&block) + @_after_load ||= [] + @_after_load << block if block_given? + @_after_load + end + + ## + # The used +$LOAD_PATHS+ from Padrino. + # + # @return [Array] + # The load paths used by Padrino. + # + def load_paths + @_load_paths_was = %w(lib models shared).map { |path| Padrino.root(path) } + @_load_paths ||= @_load_paths_was + end + + ## + # Requires necessary dependencies as well as application files from root + # lib and models. + # + # @return [Boolean] + # returns true if Padrino is not already bootstraped otherwise else. + # + def load! + return false if loaded? + t = Time.now + + @_called_from = first_caller + Padrino.set_encoding + Padrino.set_load_paths(*load_paths) + Padrino::Logger.setup! # Initialize our logger + Padrino.require_dependencies("#{root}/config/database.rb", :nodeps => true) # Be sure to don't remove constants from dbs. + Padrino::Reloader.lock! # Now we can remove constant from here to down + Padrino.before_load.each(&:call) # Run before hooks + Padrino.dependency_paths.each { |path| Padrino.require_dependencies(path) } + Padrino.after_load.each(&:call) # Run after hooks + Padrino::Reloader.run! + Thread.current[:padrino_loaded] = true + + Padrino.logger.devel "Loaded Padrino in #{Time.now - t} seconds" + end + + ## + # Clear the padrino env. + # + # @return [NilClass] + # + def clear! + Padrino.clear_middleware! + Padrino.mounted_apps.clear + @_load_paths = nil + @_dependency_paths = nil + @_global_configuration = nil + Padrino.before_load.clear + Padrino.after_load.clear + Padrino::Reloader.clear! + Thread.current[:padrino_loaded] = nil + end + + ## + # Method for reloading required applications and their files. + # + def reload! + return unless Padrino::Reloader.changed? + Padrino.before_load.each(&:call) # Run before hooks + Padrino::Reloader.reload! # detects the modified files + Padrino.after_load.each(&:call) # Run after hooks + end + + ## + # This adds the ability to instantiate {Padrino.load!} after + # {Padrino::Application} definition. + # + def called_from + @_called_from || first_caller + end + + ## + # Determines whether Padrino was loaded with {Padrino.load!}. + # + # @return [Boolean] + # Specifies whether Padrino was loaded. + # + def loaded? + Thread.current[:padrino_loaded] + end + + ## + # Attempts to require all dependency libs that we need. + # If you use this method we can perform correctly a Padrino.reload! + # Another good thing that this method are dependency check, for example: + # + # # models + # # \-- a.rb => require something of b.rb + # # \-- b.rb + # + # In the example above if we do: + # + # Dir["/models/*.rb"].each { |r| require r } + # + # We get an error, because we try to require first +a.rb+ that need + # _something_ of +b.rb+. + # + # With this method we don't have this problem. + # + # @param [Array] paths + # The paths to require. + # + # @example For require all our app libs we need to do: + # require_dependencies("#{Padrino.root}/lib/**/*.rb") + # + def require_dependencies(*paths) + options = paths.extract_options! + + # Extract all files to load + files = paths.flatten.map { |path| Dir[path] }.flatten.uniq.sort + + while files.present? + errors, failed = [], [] + + size_at_start = files.size + + # Now we try to require our dependencies, we dup files + # so we don't perform delete on the original array during + # iteration, this prevent problems with Rubinus + files.dup.each do |file| + begin + Padrino::Reloader.safe_load(file, options.dup) + files.delete(file) + rescue NameError, LoadError => e + Padrino.logger.devel "Problem while loading #{file}: #{e}" + errors << e + failed << file + rescue Exception => e + raise e + end + end + + # Stop processing if nothing loads or if everything has loaded + raise errors.last if files.size == size_at_start && files.present? + break if files.empty? + end + end + + ## + # Returns default list of path globs to load as dependencies. + # Appends custom dependency patterns to the be loaded for Padrino. + # + # @return [Array] + # The dependencey paths. + # + # @example + # Padrino.dependency_paths << "#{Padrino.root}/uploaders/*.rb" + # + def dependency_paths + @_dependency_paths ||= (dependency_paths_was + Array(module_paths)) + end + + ## + # Concat to +$LOAD_PATH+ the given paths. + # + # @param [Array] paths + # The paths to concat. + # + def set_load_paths(*paths) + $:.concat(paths); load_paths.concat(paths) + $:.uniq!; load_paths.uniq! + end + + private + + def module_paths + Padrino.modules.map(&:dependency_paths).flatten! + end + + def dependency_paths_was + [ + "#{root}/config/database.rb", + "#{root}/lib/**/*.rb", + "#{root}/shared/lib/**/*.rb", + "#{root}/models/**/*.rb", + "#{root}/shared/models/**/*.rb", + "#{root}/config/apps.rb" + ] + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/cs.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/cs.yml new file mode 100644 index 00000000..acd2d162 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/cs.yml @@ -0,0 +1,33 @@ +cs: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%d. %m. %Y" + short: "%d %b" + long: "%d. %B %Y" + only_day: "%e" + + day_names: [Neděle, Pondělí, Úterý, Středa, Čtvrtek, Pátek, Sobota] + abbr_day_names: [Ne, Po, Út, St, Čt, Pá, So] + month_names: [~, Leden, Únor, Březen, Duben, Květen, Červen, Červenec, Srpen, Září, Říjen, Listopad, Prosinec] + abbr_month_names: [~, Led, Úno, Bře, Dub, Kvě, Čvn, Čvc, Srp, Zář, Říj, Lis, Pro] + order: + - day + - month + - year + + time: + formats: + default: "%a %d. %B %Y %H:%M %z" + short: "%d. %m. %H:%M" + long: "%A %d. %B %Y %H:%M" + am: "dop" + pm: "odp" + + support: + array: + words_connector: ", " + two_words_connector: " a " + last_word_connector: " a " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/da.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/da.yml new file mode 100644 index 00000000..4eda8a74 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/da.yml @@ -0,0 +1,33 @@ +da: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%d.%m.%Y" + short: "%e. %b %Y" + long: "%e. %B %Y" + only_day: "%e" + + day_names: [søndag, mandag, tirsdag, onsdag, torsdag, fredag, lørdag] + abbr_day_names: [sø, ma, ti, 'on', to, fr, lø] + month_names: [~, januar, februar, marts, april, maj, juni, juli, august, september, oktober, november, december] + abbr_month_names: [~, jan, feb, mar, apr, maj, jun, jul, aug, sep, okt, nov, dec] + order: + - day + - month + - year + + time: + formats: + default: "%e. %B %Y, %H:%M" + short: "%e. %b %Y, %H:%M" + long: "%A, %e. %B %Y, %H:%M" + am: "" + pm: "" + + support: + array: + words_connector: ", " + two_words_connector: " og " + last_word_connector: " og " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/de.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/de.yml new file mode 100644 index 00000000..a7c757be --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/de.yml @@ -0,0 +1,33 @@ +de: + date: + formats: + # Benutze die strftime Parameter für die Formatierung + # Wenn keine Formate angegeben werden, wird "default" benutzt. + # Du kannst auch weitere Formate hinzufügen, wenn Du möchtest. + default: "&d.&m.%Y" + short: "%d. %b" + long: "%d. %B %Y" + only_day: "%e" + + day_names: [Sonntag, Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag] + abbr_day_names: [So, Mo, Di, Mi, Do, Fr, Sa] + month_names: [~, Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember] + abbr_month_names: [~, Jan, Feb, Mär, Apr, Mai, Jun, Jul, Aug, Sep, Okt, Nov, Dez] + order: + - day + - month + - year + + time: + formats: + default: "%a, %d. %b %Y %H:%M:%S %z" + short: "%d. %b %H:%M" + long: "%d. %B %Y %H:%M" + am: "am" + pm: "pm" + + support: + array: + words_connector: ", " + two_words_connector: " und " + last_word_connector: " und " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/en.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/en.yml new file mode 100644 index 00000000..eca8c0fa --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/en.yml @@ -0,0 +1,33 @@ +en: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%Y-%m-%d" + short: "%b %d" + long: "%B %d, %Y" + only_day: "%e" + + day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday] + abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat] + month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December] + abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec] + order: + - year + - month + - day + + time: + formats: + default: "%a, %d %b %Y %H:%M:%S %z" + short: "%d %b %H:%M" + long: "%B %d, %Y %H:%M" + am: "am" + pm: "pm" + + support: + array: + words_connector: ", " + two_words_connector: " and " + last_word_connector: ", and " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/es.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/es.yml new file mode 100644 index 00000000..d701b8ee --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/es.yml @@ -0,0 +1,33 @@ +es: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%d-%m-%Y" + short: "%b %d" + long: "%B %d, %Y" + only_day: "%e" + + day_names: [Domingo, Lunes, Martes, Miércoles, Jueves, Viernes, Sábado] + abbr_day_names: [Dom, Lun, Mar, Mie, Jue, Vie, Sab] + month_names: [~, Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto, Septiembre, Octubre, Noviembre, Diciembre] + abbr_month_names: [~, Ene, Feb, Mar, Abr, May, Jun, Jul, Ago, Sep, Oct, Nov, Dic] + order: + - day + - month + - year + + time: + formats: + default: "%a, %d %b %Y %H:%M:%S %z" + short: "%d %b %H:%M" + long: "%B %d, %Y %H:%M" + am: "am" + pm: "pm" + + support: + array: + words_connector: ", " + two_words_connector: " y " + last_word_connector: ", y " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/fr.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/fr.yml new file mode 100644 index 00000000..e724d47d --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/fr.yml @@ -0,0 +1,33 @@ +fr: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%d-%m-%Y" + short: "%b %d" + long: "%B %d, %Y" + only_day: "%e" + + day_names: [Dimanche, Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi] + abbr_day_names: [Dim, Lun, Mar, Mer, Jeu, Ven, Sam] + month_names: [~, Janvier, Février, Mars, Avril, Mai, Juin, Juillet, Août, Septembre, Octobre, Novembre, Décembre] + abbr_month_names: [~, Jan, Fev, Mar, Avr, Mai, Jun, Jul, Aou, Sep, Oct, Nov, Dec] + order: + - day + - month + - year + + time: + formats: + default: "%a, %d %b %Y %H:%M:%S %z" + short: "%d %b %H:%M" + long: "%B %d, %Y %H:%M" + am: "am" + pm: "pm" + + support: + array: + words_connector: ", " + two_words_connector: " et " + last_word_connector: ", et " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/hu.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/hu.yml new file mode 100644 index 00000000..fb910c8f --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/hu.yml @@ -0,0 +1,33 @@ +hu: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%Y-%m-%d" + short: "%b. %d." + long: "%Y. %B %d." + only_day: "%e" + + day_names: [vasárnap, hétfő, kedd, szerda, csütörtök, péntek, szombat] + abbr_day_names: [vas, hét, kedd, sze, csüt, pén, szo] + month_names: [~, január, február, március, április, május, június, július, augusztus, szeptember, oktober, november, december] + abbr_month_names: [~, jan, febr, márc, ápr, máj, jún, júl, aug, szept, okt, nov, dec] + order: + - year + - month + - day + + time: + formats: + default: "%Y. %B %d. %H:%M:%S %z, %A" + short: "%B %d. %H:%M" + long: "%Y. %B %d. %H:%M" + am: "de" + pm: "du" + + support: + array: + words_connector: ", " + two_words_connector: " és " + last_word_connector: " és " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/it.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/it.yml new file mode 100644 index 00000000..32a5d695 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/it.yml @@ -0,0 +1,39 @@ +it: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%d-%m-%Y" + short: "%d %b" + long: "%d %B %Y" + only_day: "%e" + + day_names: [Domenica, Lunedì, Martedì, Mercoledì, Giovedì, Venerdì, Sabato] + abbr_day_names: [Dom, Lun, Mar, Mer, Gio, Ven, Sab] + month_names: [~, Gennaio, Febbraio, Marzo, Aprile, Maggio, Giugno, Luglio, Agosto, Settembre, Ottobre, Novembre, Dicembre] + abbr_month_names: [~, Gen, Feb, Mar, Apr, Mag, Giu, Lug, Ago, Set, Ott, Nov, Dic] + order: + - day + - month + - year + + time: + formats: + default: "%a %d %b %Y, %H:%M:%S %z" + time: "%H:%M" + short: "%d %b %H:%M" + long: "%d %B %Y %H:%M" + only_second: "%S" + + datetime: + formats: + default: "%d-%m-%YT%H:%M:%S%Z" + + am: 'am' + pm: 'pm' + + support: + array: + sentence_connector: "e" + skip_last_comma: false diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/ja.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/ja.yml new file mode 100644 index 00000000..56bb6058 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/ja.yml @@ -0,0 +1,33 @@ +ja: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%Y/%m/%d" + short: "%m/%d" + long: "%Y年%m月%d日" + only_day: "%e" + + day_names: [日曜日, 月曜日, 火曜日, 水曜日, 木曜日, 金曜日, 土曜日] + abbr_day_names: [日, 月, 火, 水, 木, 金, 土] + month_names: [~, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月] + abbr_month_names: [~, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月] + order: + - year + - month + - day + + time: + formats: + default: "%Y/%m/%d %H:%M:%S" + short: "%m/%d %H:%M" + long: "%Y年%m月%d日 %H時%M分%S秒" + am: "午前" + pm: "午後" + + support: + array: + words_connector: ", " + two_words_connector: " と " + last_word_connector: ", と " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/lv.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/lv.yml new file mode 100644 index 00000000..bcb49066 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/lv.yml @@ -0,0 +1,33 @@ +lv: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%d.%m.%Y" + short: "%e. %B" + long: "%Y. gada %e. %B" + only_day: "%e" + + day_names: [Svētdiena, Pirmdiena, Otrdiena, Trešdiena, Ceturtdiena, Piektdiena, Sestdiena] + abbr_day_names: [Sv, P, O, T, C, P, S] + month_names: [~, Janvāris, Februāris, Marts, Aprīlis, Maijs, Jūnijs, Jūlijs, Augusts, Septembris, Oktobris, Novembris, Decembris] + abbr_month_names: [~, Janv, Febr, Marts, Apr, Maijs, Jūn, Jūl, Aug, Sept, Okt, Nov, Dec] + order: + - day + - month + - year + + time: + formats: + default: "%Y. gada %e. %B, %H:%M" + short: "%d.%m.%Y, %H:%M" + long: "%Y. gada %e. %B, %H:%M:%S" + am: "priekšpusdiena" + pm: "pēcpusdiena" + + support: + array: + words_connector: ", " + two_words_connector: " un " + last_word_connector: ", un " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/nl.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/nl.yml new file mode 100644 index 00000000..868087be --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/nl.yml @@ -0,0 +1,33 @@ +nl: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%d-%m-%Y" + short: "%d %b" + long: "%d %B %Y" + only_day: "%e" + + day_names: [zondag, maandag, dinsdag, woensdag, donderdag, vrijdag, zaterdag] + abbr_day_names: [zo, ma, di, wo, do, vr, za] + month_names: [~, januari, februari, maart, april, mei, juni, juli, augustus, september, oktober, november] + abbr_month_names: [~, jan, feb, maa, apr, mei, jun, jul, aug, sep, okt, nov, dec] + order: + - day + - month + - year + + time: + formats: + default: "%a %d %b %Y %H:%M:%S %z" + short: "%d %b %H:%M" + long: "%d %B %Y %H:%M" + am: "am" + pm: "pm" + + support: + array: + words_connector: ", " + two_words_connector: " en " + last_word_connector: " en " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/no.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/no.yml new file mode 100644 index 00000000..e86d53e8 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/no.yml @@ -0,0 +1,33 @@ +"no": + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%d.%m.%Y" + short: "%e. %b %Y" + long: "%e. %B %Y" + only_day: "%e" + + day_names: [søndag, mandag, tirsdag, onsdag, torsdag, fredag, lørdag] + abbr_day_names: [sø, ma, ti, 'on', to, fr, lø] + month_names: [~, januar, februar, mars, april, mai, juni, juli, august, september, oktober, november, desember] + abbr_month_names: [~, jan, feb, mar, apr, maj, jun, jul, aug, sep, okt, nov, des] + order: + - day + - month + - year + + time: + formats: + default: "%e. %B %Y, %H:%M" + short: "%e. %b %Y, %H:%M" + long: "%A, %e. %B %Y, %H:%M" + am: "" + pm: "" + + support: + array: + words_connector: ", " + two_words_connector: " og " + last_word_connector: " og " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/pl.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/pl.yml new file mode 100644 index 00000000..ef377aa7 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/pl.yml @@ -0,0 +1,33 @@ +pl: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%Y-%m-%d" + short: "%d %b" + long: "%d %B %Y" + only_day: "%e" + + day_names: [Niedziela, Poniedziałek, Wtorek, Środa, Czwartek, Piątek, Sobota] + abbr_day_names: [nie, pon, wto, śro, czw, pia, sob] + month_names: [~, Styczeń, Luty, Marzec, Kwiecień, Maj, Czerwiec, Lipiec, Sierpień, Wrzesień, Październik, Listopad, Grudzień] + abbr_month_names: [~, sty, lut, mar, kwi, maj, cze, lip, sie, wrz, paź, lis, gru] + order: + - year + - month + - day + + time: + formats: + default: "%a, %d %b %Y, %H:%M:%S %z" + short: "%d %b, %H:%M" + long: "%d %B %Y, %H:%M" + am: "przed południem" + pm: "po południu" + + support: + array: + words_connector: ", " + two_words_connector: " i " + last_word_connector: " i " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/pt_br.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/pt_br.yml new file mode 100644 index 00000000..cbb92c61 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/pt_br.yml @@ -0,0 +1,39 @@ +pt_br: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%d-%m-%Y" + short: "%d %b" + long: "%d %B %Y" + only_day: "%e" + + day_names: [Domingo, Segunda-feira, Terça-feira, Quarta-feira, Quinta-feira, Sexta-feira, Sábado] + abbr_day_names: [Dom, Seg, Ter, Qua, Qui, Sex, Sab] + month_names: [~, Janeiro, Fevereiro, Março, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro] + abbr_month_names: [~, Jan, Fev, Mar, Abr, Maio, Jun, Jul, Ago, Set, Out, Nov, Dez] + order: + - day + - month + - year + + time: + formats: + default: "%a %d %b %Y, %H:%M:%S %z" + time: "%H:%M" + short: "%d %b %H:%M" + long: "%d %B %Y %H:%M" + only_second: "%S" + + datetime: + formats: + default: "%d-%m-%YT%H:%M:%S%Z" + + am: 'am' + pm: 'pm' + + support: + array: + sentence_connector: "e" + skip_last_comma: false diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/ro.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/ro.yml new file mode 100644 index 00000000..96208425 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/ro.yml @@ -0,0 +1,33 @@ +ro: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%d.%m.%Y" + short: "%d %b" + long: "%d %B %Y" + only_day: "%e" + + day_names: [Duminică, Luni, Marți, Miercuri, Joi, Vineri, Sâmbătă] + abbr_day_names: [Dum, Lun, Mar, Mie, Joi, Vin, Sâm] + month_names: [~, Ianuarie, Februarie, Martie, Aprilie, Mai, Iunie, Iulie, August, Septembrie, Octombrie, Noiembrie, Decembrie] + abbr_month_names: [~, Ian, Feb, Mar, Apr, Mai, Iun, Iul, Aug, Sep, Oct, Noi, Dec] + order: + - day + - month + - year + + time: + formats: + default: "%a, %d %b %Y %H:%M:%S %z" + short: "%d %b %H:%M" + long: "%d, %B %Y %H:%M" + am: "am" + pm: "pm" + + support: + array: + words_connector: ", " + two_words_connector: " și " + last_word_connector: " și " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/ru.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/ru.yml new file mode 100644 index 00000000..641ab99b --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/ru.yml @@ -0,0 +1,34 @@ +ru: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%d.%m.%Y" + short: "%d %b" + long: "%e %B, %Y" + only_day: "%e" + + day_names: [Воскресенье, Понедельник, Вторник, Среда, Четверг, Пятница, Суббота] + abbr_day_names: [Вс, Пн, Вт, Ср, Чт, Пт, Сб] + month_names: [~, Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь] + abbr_month_names: [~, Янв, Фев, Мар, Апр, Май, Июн, Июл, Авг, Сен, Окт, Ноя, Дек] + order: + - year + - month + - day + + time: + formats: + default: "%a, %d %b %Y %H:%M:%S %z" + short: "%d %b %H:%M" + long: "%e %B, %Y %H:%M" + am: "д.п." + pm: "п.п." + + support: + array: + words_connector: ", " + two_words_connector: " и " + last_word_connector: " и " + diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/sv.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/sv.yml new file mode 100644 index 00000000..3ea795ef --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/sv.yml @@ -0,0 +1,33 @@ +sv: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%Y-%m-%d" + short: "%b %d" + long: "%B %d, %Y" + only_day: "%e" + + day_names: [söndag, måndag, tisdag, onsdag, torsdag, fredag, lördag] + abbr_day_names: [sön, mån, tis, ons, tors, fre, lör] + month_names: [~, januari, februari, mars, april, maj, juni, juli, augusti, september, oktober, november, december] + abbr_month_names: [~, jan, feb, mar, apr, may, jun, jul, aug, sep, okt, nov, dec] + order: + - år + - månad + - dag + + time: + formats: + default: "%a, %d %b %Y %H:%M:%S %z" + short: "%d %b %H:%M" + long: "%B %d, %Y %H:%M" + am: "fm" + pm: "em" + + support: + array: + words_connector: ", " + two_words_connector: " och " + last_word_connector: ", och " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/tr.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/tr.yml new file mode 100644 index 00000000..504a7e1a --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/tr.yml @@ -0,0 +1,33 @@ +tr: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%d/%m/%Y" + short: "%d %b" + long: "%d %B %Y" + only_day: "%e" + + day_names: [Pazar, Pazartesi, Salı, Çarşamba, Perşembe, Cuma, Cumartesi] + abbr_day_names: [Paz, Pts, Sal, Çar, Per, Cum, Cts] + month_names: [~, Ocak, Şubat, Mart, Nisan, Mayıs, Haziran, Temmuz, Ağustos, Eylül, Ekim, Kasım, Aralık] + abbr_month_names: [~, Oca, Şub, Mar, Nis, May, Haz, Tem, Ağu, Eyl, Eki, Kas, Ara] + order: + - day + - month + - year + + time: + formats: + default: "%a, %b %b %Y %H:%M:%S %z" + short: "%b %d %H:%M" + long: "%d %B, %Y %H:%M" + am: "öö" + pm: "ös" + + support: + array: + words_connector: ", " + two_words_connector: " ve " + last_word_connector: " ve " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/uk.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/uk.yml new file mode 100644 index 00000000..d864e7c6 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/uk.yml @@ -0,0 +1,33 @@ +uk: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%d.%m.%Y" + short: "%d %b" + long: "%e %B, %Y" + only_day: "%e" + + day_names: [Неділя, Понеділок, Вівторок, Середа, Четвер, Пятница, Субота] + abbr_day_names: [Нд, Пн, Вт, Ср, Чт, Пт, Сб] + month_names: [~, Січено, Лютий, Березень, Квітень, Травень, Червень, Липень, Серпень, Вересень, Жовтень, Листопад, Грудень] + abbr_month_names: [~, Січ, Лют, Бер, Кві, Тра, Чер, Лип, Сер, Вер, Жов, Лис, Гру] + order: + - year + - month + - day + + time: + formats: + default: "%a, %d %b %Y %H:%M:%S %z" + short: "%d %b %H:%M" + long: "%e %B, %Y %H:%M" + am: "д.п." + pm: "п.п" + + support: + array: + words_connector: ", " + two_words_connector: " і " + last_word_connector: ", і " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/zh_cn.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/zh_cn.yml new file mode 100644 index 00000000..1cde0a12 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/zh_cn.yml @@ -0,0 +1,33 @@ +zh_cn: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%Y 年 %m 月 %d 日" + short: "%b 月 %d 日" + long: "公元 %Y 年 %B 月 %d 日" + only_day: "%e" + + day_names: [星期日, 星期一, 星期二, 星期三, 星期四, 星期五, 星期六] + abbr_day_names: [日, 一, 二, 三, 四, 五, 六] + month_names: [~, 1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月] + abbr_month_names: [~, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + order: + - year + - month + - day + + time: + formats: + default: "%Y 年 %b 月 %d 日 %H:%M:%S %z" + short: "%d 月 %b 日 %H:%M" + long: "%Y 年 %B 月 %d 日 %H 时 %M 分" + am: "上午" + pm: "下午" + + support: + array: + words_connector: "," + two_words_connector: "和" + last_word_connector: ",还有" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/zh_tw.yml b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/zh_tw.yml new file mode 100644 index 00000000..26e56112 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/locale/zh_tw.yml @@ -0,0 +1,33 @@ +zh_tw: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%Y-%m-%d" + short: "%b%d日" + long: "%Y年%b%d日" + only_day: "%e" + + day_names: [星期日, 星期一, 星期二, 星期三, 星期四, 星期五, 星期六] + abbr_day_names: [日, 一, 二, 三, 四, 五, 六] + month_names: [~, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月] + abbr_month_names: [~, 1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月] + order: + - year + - month + - day + + time: + formats: + default: "%Y年%b%d日 %A %H:%M:%S %Z" + short: "%b%d日 %H:%M" + long: "%Y年%b%d日 %H:%M" + am: "上午" + pm: "下午" + + support: + array: + words_connector: ", " + two_words_connector: " 和 " + last_word_connector: ", 和 " diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/logger.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/logger.rb new file mode 100644 index 00000000..bd863f8b --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/logger.rb @@ -0,0 +1,438 @@ +# Defines the log level for a Padrino project. +PADRINO_LOG_LEVEL = ENV['PADRINO_LOG_LEVEL'] unless defined?(PADRINO_LOG_LEVEL) + +# Defines the logger used for a Padrino project. +PADRINO_LOGGER = ENV['PADRINO_LOGGER'] unless defined?(PADRINO_LOGGER) + +module Padrino + ## + # @return [Padrino::Logger] + # + # @example + # logger.debug "foo" + # logger.warn "bar" + # + def self.logger + Padrino::Logger.logger + end + + ## + # Set the padrino logger. + # + # @param [Object] value + # an object that respond to <<, write, puts, debug, warn etc.. + # + # @return [Object] + # The given value. + # + # @example using ruby default logger + # require 'logger' + # Padrino.logger = Logger.new(STDOUT) + # + # @example using ActiveSupport + # require 'active_support/buffered_logger' + # Padrino.logger = Buffered.new(STDOUT) + # + def self.logger=(value) + Padrino::Logger.logger = value + end + + ## + # Padrinos internal logger, using all of Padrino log extensions. + # + class Logger + ## + # Ruby (standard) logger levels: + # + # :fatal:: An not handleable error that results in a program crash + # :error:: A handleable error condition + # :warn:: A warning + # :info:: generic (useful) information about system operation + # :debug:: low-level information for developers + # :devel:: Development-related information that is unnecessary in debug mode + # + Levels = { + :fatal => 7, + :error => 6, + :warn => 4, + :info => 3, + :debug => 0, + :devel => -1, + } unless defined?(Levels) + + module Extensions + ## + # Generate the logging methods for {Padrino.logger} for each log level. + # + Padrino::Logger::Levels.each_pair do |name, number| + define_method(name) do |*args| + return if number < level + if args.size > 1 + bench(args[0], args[1], args[2], name) + else + push(args * '', name) + end + end + + define_method(:"#{name}?") do + number >= level + end + end + + ## + # Append a to development logger a given action with time. + # + # @param [string] action + # The action. + # + # @param [float] time + # Time duration for the given action. + # + # @param [message] string + # The message that you want to log. + # + # @example + # logger.bench 'GET', started_at, '/blog/categories' + # # => DEBUG - GET (0.0056s) - /blog/categories + # + def bench(action, began_at, message, level=:debug, color=:yellow) + @_pad ||= 8 + @_pad = action.to_s.size if action.to_s.size > @_pad + duration = Time.now - began_at + color = :red if duration > 1 + action = colorize(action.to_s.upcase.rjust(@_pad), color) + duration = colorize('%0.4fs' % duration, :bold, color) + push "#{action} (#{duration}) #{message}", level + end + + ## + # Appends a message to the log. The methods yield to an optional block and + # the output of this block will be appended to the message. + # + # @param [String] message + # The message that you want write to your stream. + # + # @param [String] level + # The level one of :debug, :warn etc. ... + # + # + def push(message = nil, level = nil) + add(Padrino::Logger::Levels[level], format(message, level)) + end + + ## + # Formats the log message. This method is a noop and should be implemented by other + # logger components such as {Padrino::Logger}. + # + # @param [String] message + # The message to format. + # + # @param [String,Symbol] level + # The log level, one of :debug, :warn ... + def format(message, level) + message + end + + ## + # The debug level, with some style added. May be reimplemented. + # + # @example + # stylized_level(:debug) => DEBUG + # + # @param [String,Symbol] level + # The log level. + # + def stylized_level(level) + level.to_s.upcase.rjust(7) + end + + ## + # Colorizes a string for colored console output. This is a noop and can be reimplemented + # to colorize the string as needed. + # + # @see + # ColorizedLogger + # + # @param [string] + # The string to be colorized. + # + # @param [Array] + # The colors to use. Should be applied in the order given. + def colorize(string, *colors) + string + end + + ## + # Turns a logger with LoggingExtensions into a logger with colorized output. + # + # @example + # Padrino.logger = Logger.new($stdout) + # Padrino.logger.colorize! + # Padrino.logger.debug("Fancy Padrino debug string") + def colorize! + self.extend(Colorize) + end + end + + module Colorize + # Colors for levels + ColoredLevels = { + :fatal => [:bold, :red], + :error => [:red], + :warn => [:yellow], + :info => [:green], + :debug => [:cyan], + :devel => [:magenta] + } unless defined?(ColoredLevels) + + ## + # Colorize our level. + # + # @param [String, Symbol] level + # + # @see Padrino::Logging::ColorizedLogger::ColoredLevels + # + def colorize(string, *colors) + colors.each do |c| + string = string.send(c) + end + string + end + + def stylized_level(level) + style = ColoredLevels[level].map { |c| "\e[%dm" % String.colors[c] } * '' + [style, super, "\e[0m"] * '' + end + end + + include Extensions + + attr_accessor :auto_flush, :level, :log_static + attr_reader :buffer, :colorize_logging, :init_args, :log + + ## + # Configuration for a given environment, possible options are: + # + # :log_level:: Once of [:fatal, :error, :warn, :info, :debug] + # :stream:: Once of [:to_file, :null, :stdout, :stderr] our your custom stream + # :log_level:: + # The log level from, e.g. :fatal or :info. Defaults to :warn in the + # production environment and :debug otherwise. + # :auto_flush:: + # Whether the log should automatically flush after new messages are + # added. Defaults to true. + # :format_datetime:: Format of datetime. Defaults to: "%d/%b/%Y %H:%M:%S" + # :format_message:: Format of message. Defaults to: ""%s - - [%s] \"%s\""" + # :log_static:: Whether or not to show log messages for static files. Defaults to: false + # :colorize_logging:: Whether or not to colorize log messages. Defaults to: true + # + # @example + # Padrino::Logger::Config[:development] = { :log_level => :debug, :stream => :to_file } + # # or you can edit our defaults + # Padrino::Logger::Config[:development][:log_level] = :error + # # or you can use your stream + # Padrino::Logger::Config[:development][:stream] = StringIO.new + # + # Defaults are: + # + # :production => { :log_level => :warn, :stream => :to_file } + # :development => { :log_level => :debug, :stream => :stdout } + # :test => { :log_level => :fatal, :stream => :null } + # + # In some cases, configuring the loggers before loading the framework is necessary. + # You can do so by setting PADRINO_LOGGER: + # + # PADRINO_LOGGER = { :staging => { :log_level => :debug, :stream => :to_file }} + # + Config = { + :production => { :log_level => :warn, :stream => :to_file }, + :development => { :log_level => :debug, :stream => :stdout, :format_datetime => '' }, + :test => { :log_level => :debug, :stream => :null } + } + Config.merge!(PADRINO_LOGGER) if PADRINO_LOGGER + + @@mutex = Mutex.new + def self.logger + @_logger || setup! + end + + def self.logger=(logger) + logger.extend(Padrino::Logger::Extensions) + + @_logger = logger + end + + ## + # Setup a new logger. + # + # @return [Padrino::Logger] + # A {Padrino::Logger} instance + # + def self.setup! + self.logger = begin + config_level = (PADRINO_LOG_LEVEL || Padrino.env || :test).to_sym # need this for PADRINO_LOG_LEVEL + config = Config[config_level] + + unless config + warn("No logging configuration for :#{config_level} found, falling back to :production") + config = Config[:production] + end + + stream = case config[:stream] + when :to_file + FileUtils.mkdir_p(Padrino.root('log')) unless File.exists?(Padrino.root('log')) + File.new(Padrino.root('log', "#{Padrino.env}.log"), 'a+') + when :null then StringIO.new + when :stdout then $stdout + when :stderr then $stderr + else config[:stream] # return itself, probabilly is a custom stream. + end + + Padrino::Logger.new(config.merge(:stream => stream)) + end + end + + ## + # To initialize the logger you create a new object, proxies to set_log. + # + # @param [Hash] options + # + # @option options [Symbol] :stream ($stdout) + # Either an IO object or a name of a logfile. Defaults to $stdout + # + # @option options [Symbol] :log_level (:production in the production environment and :debug otherwise) + # The log level from, e.g. :fatal or :info. + # + # @option options [Symbol] :auto_flush (true) + # Whether the log should automatically flush after new messages are + # added. Defaults to true. + # + # @option options [Symbol] :format_datetime (" [%d/%b/%Y %H:%M:%S] ") + # Format of datetime. + # + # @option options [Symbol] :format_message ("%s -%s%s") + # Format of message. + # + # @option options [Symbol] :log_static (false) + # Whether or not to show log messages for static files. + # + # @option options [Symbol] :colorize_logging (true) + # Whether or not to colorize log messages. Defaults to: true. + # + def initialize(options={}) + @buffer = [] + @auto_flush = options.has_key?(:auto_flush) ? options[:auto_flush] : true + @level = options[:log_level] ? Padrino::Logger::Levels[options[:log_level]] : Padrino::Logger::Levels[:debug] + @log = options[:stream] || $stdout + @log.sync = true + @format_datetime = options[:format_datetime] || "%d/%b/%Y %H:%M:%S" + @format_message = options[:format_message] || "%s - %s %s" + @log_static = options.has_key?(:log_static) ? options[:log_static] : false + @colorize_logging = options.has_key?(:colorize_logging) ? options[:colorize_logging] : true + colorize! if @colorize_logging + end + + ## + # Flush the entire buffer to the log object. + # + def flush + return unless @buffer.size > 0 + @@mutex.synchronize do + @log.write(@buffer.join('')) + @buffer.clear + end + end + + ## + # Close and remove the current log object. + # + # @return [NilClass] + # + def close + flush + @log.close if @log.respond_to?(:close) && !@log.tty? + @log = nil + end + + ## + # Adds a message to the log - for compatibility with other loggers. + # + def add(level, message = nil) + write(message) + end + + ## + # Directly append message to the log. + # + # @param [String] message + # The message + # + def <<(message = nil) + message << "\n" unless message[-1] == ?\n + @@mutex.synchronize { + @buffer << message + } + flush if @auto_flush + message + end + alias :write :<< + + def format(message, level) + @format_message % [stylized_level(level), colorize(Time.now.strftime(@format_datetime), :yellow), message.to_s.strip] + end + + ## + # Padrino::Logger::Rack forwards every request to an +app+ given, and + # logs a line in the Apache common log format to the +logger+, or + # rack.errors by default. + # + class Rack + def initialize(app, uri_root) + @app = app + @uri_root = uri_root.sub(/\/$/,"") + end + + def call(env) + env['rack.logger'] = Padrino.logger + began_at = Time.now + status, header, body = @app.call(env) + log(env, status, header, began_at) if logger.debug? + [status, header, body] + end + + private + + def log(env, status, header, began_at) + return if env['sinatra.static_file'] && (!logger.respond_to?(:log_static) || !logger.log_static) + logger.bench( + env["REQUEST_METHOD"], + began_at, + [ + @uri_root.to_s, + env["PATH_INFO"], + env["QUERY_STRING"].empty? ? "" : "?" + env["QUERY_STRING"], + ' - ', + logger.colorize(status.to_s[0..3], :bold), + ' ', + code_to_name(status) + ] * '', + :debug, + :magenta + ) + end + + def code_to_name(status) + ::Rack::Utils::HTTP_STATUS_CODES[status.to_i] || '' + end + end + end +end + +module Kernel + ## + # Define a logger available every where in our app + # + def logger + Padrino.logger + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/module.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/module.rb new file mode 100644 index 00000000..0037f0c0 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/module.rb @@ -0,0 +1,58 @@ +module Padrino + module Module + attr_accessor :root + + ## + # Register this module as being loaded from a gem. This automatically + # sets the root and therefore the dependency paths correctly. + # + # @param [String] name + # The name of the gem. Has to be the name as stated in the gemspec. + # + # @returns the gems root. + def gem!(name) + self.root = Padrino.gem(name, self) + end + + ## + # Helper method for file references within a Padrino module. + # + # @param [Array] args + # The directories to join to {Module.root}. + # + # @return [String] + # The absolute path. + # + # @example + # module MyModule + # extend Padrino::Module + # gem! 'my_gem' + # end + # Module.root! + def root(*args) + File.expand_path(File.join(@root, *args)) + end + + ## + # Returns the list of path globs to load as dependencies. + # Appends custom dependency patterns to the be loaded for Padrino. + # + # @return [Array] + # The dependency paths. + # + # @example + # module MyModule + # extend Padrino::Module + # gem! 'my_gem' + # end + # + # Module.dependency_paths << "#{MyModule.root}/uploaders/*.rb" + # + def dependency_paths + [ + "#{root}/lib/**/*.rb", "#{root}/shared/lib/**/*.rb", + "#{root}/models/**/*.rb", "#{root}/shared/models/**/*.rb" + ] + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/mounter.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/mounter.rb new file mode 100644 index 00000000..76901dab --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/mounter.rb @@ -0,0 +1,234 @@ +module Padrino + ## + # Represents a particular mounted Padrino application. + # Stores the name of the application (app folder name) and url mount path. + # + # @example + # Mounter.new("blog_app", :app_class => "Blog").to("/blog") + # Mounter.new("blog_app", :app_file => "/path/to/blog/app.rb").to("/blog") + # + class Mounter + class MounterException < RuntimeError + end + + attr_accessor :name, :uri_root, :app_file, :app_class, :app_root, :app_obj, :app_host + + ## + # @param [String, Padrino::Application] name + # The app name or the {Padrino::Application} class. + # + # @param [Hash] options + # @option options [Symbol] :app_class (Detected from name) + # @option options [Symbol] :app_file (Automatically detected) + # @option options [Symbol] :app_obj (Detected) + # @option options [Symbol] :app_root (Directory of :app_file) + # @option options [Symbol] :gem The gem to load the app from (Detected from name) + # + def initialize(name, options={}) + @name = name.to_s + @app_class = options[:app_class] || @name.camelize + @gem = options[:gem] || @app_class.split("::").first.underscore + @app_file = options[:app_file] || locate_app_file + @app_obj = options[:app_obj] || app_constant || locate_app_object + ensure_app_file! || ensure_app_object! + @app_root = options[:app_root] || File.dirname(@app_file) + @uri_root = "/" + Padrino::Reloader.exclude_constants << @app_class + end + + ## + # Registers the mounted application onto Padrino. + # + # @param [String] mount_url + # Path where we mount the app. + # + # @example + # Mounter.new("blog_app").to("/blog") + # + def to(mount_url) + @uri_root = mount_url + Padrino.insert_mounted_app(self) + self + end + + ## + # Registers the mounted application onto Padrino for the given host. + # + # @param [String] mount_host + # Host name. + # + # @example + # Mounter.new("blog_app").to("/blog").host("blog.padrino.org") + # Mounter.new("blog_app").host("blog.padrino.org") + # Mounter.new("catch_all").host(/.*\.padrino.org/) + # + def host(mount_host) + @app_host = mount_host + Padrino.insert_mounted_app(self) + self + end + + ## + # Maps Padrino application onto a Padrino::Router. + # For use in constructing a Rack application. + # + # @param [Padrino::Router] + # + # @return [Padrino::Router] + # + # @example + # @app.map_onto(router) + # + def map_onto(router) + app_data, app_obj = self, @app_obj + app_obj.set :uri_root, app_data.uri_root + app_obj.set :app_name, app_data.name + app_obj.set :app_file, app_data.app_file unless ::File.exist?(app_obj.app_file) + app_obj.set :root, app_data.app_root unless app_data.app_root.blank? + app_obj.set :public_folder, Padrino.root('public', app_data.uri_root) unless File.exists?(app_obj.public_folder) + app_obj.set :static, File.exist?(app_obj.public_folder) if app_obj.nil? + app_obj.setup_application! # Initializes the app here with above settings. + router.map(:to => app_obj, :path => app_data.uri_root, :host => app_data.app_host) + end + + ### + # Returns the route objects for the mounted application. + # + def routes + app_obj.routes + end + + ### + # Returns the basic route information for each named route. + # + # @return [Array] + # Array of routes. + # + def named_routes + app_obj.routes.map { |route| + name_array = "(#{route.name.to_s.split("_").map { |piece| %Q[:#{piece}] }.join(", ")})" + request_method = route.request_methods.first + next if route.name.blank? || request_method == 'HEAD' + original_path = route.original_path.is_a?(Regexp) ? route.original_path.inspect : route.original_path + full_path = File.join(uri_root, original_path) + OpenStruct.new(:verb => request_method, :identifier => route.name, :name => name_array, :path => full_path) + }.compact + end + + ## + # Makes two Mounters equal if they have the same name and uri_root. + # + # @param [Padrino::Mounter] other + # + def ==(other) + other.is_a?(Mounter) && self.app_class == other.app_class && self.uri_root == other.uri_root + end + + ## + # @return [Padrino::Application] + # the class object for the app if defined, nil otherwise. + # + def app_constant + klass = Object + for piece in app_class.split("::") + piece = piece.to_sym + if klass.const_defined?(piece) + klass = klass.const_get(piece) + else + return + end + end + klass + end + + protected + ## + # Locates and requires the file to load the app constant. + # + def locate_app_object + @_app_object ||= begin + ensure_app_file! + Padrino.require_dependencies(app_file) + app_constant + end + end + + ## + # Returns the determined location of the mounted application main file. + # + def locate_app_file + candidates = [] + candidates << app_constant.app_file if app_constant.respond_to?(:app_file) && File.exist?(app_constant.app_file.to_s) + candidates << Padrino.first_caller if File.identical?(Padrino.first_caller.to_s, Padrino.called_from.to_s) + candidates << Padrino.mounted_root(name.downcase, "app.rb") + simple_name = name.split("::").last.downcase + mod_name = name.split("::")[0..-2].join("::") + Padrino.modules.each do |mod| + if mod.name == mod_name + candidates << mod.root(simple_name, "app.rb") + end + end + candidates << Padrino.root("app", "app.rb") + candidates.find { |candidate| File.exist?(candidate) } + end + + ### + # Raises an exception unless app_file is located properly. + # + def ensure_app_file! + message = "Unable to locate source file for app '#{app_class}', try with :app_file => '/path/app.rb'" + raise MounterException, message unless @app_file + end + + ### + # Raises an exception unless app_obj is defined properly. + # + def ensure_app_object! + message = "Unable to locate app for '#{app_class}', try with :app_class => 'MyAppClass'" + raise MounterException, message unless @app_obj + end + end + + class << self + attr_writer :mounted_root # Set root directory where padrino searches mounted apps + + ## + # @param [Array] args + # + # @return [String] + # the root to the mounted apps base directory. + # + def mounted_root(*args) + Padrino.root(@mounted_root ||= "", *args) + end + + ## + # @return [Array] + # the mounted padrino applications (MountedApp objects) + # + def mounted_apps + @mounted_apps ||= [] + end + + ## + # Inserts a Mounter object into the mounted applications (avoids duplicates). + # + # @param [Padrino::Mounter] mounter + # + def insert_mounted_app(mounter) + Padrino.mounted_apps.push(mounter) unless Padrino.mounted_apps.include?(mounter) + end + + ## + # Mounts a new sub-application onto Padrino project. + # + # @see Padrino::Mounter#new + # + # @example + # Padrino.mount("blog_app").to("/blog") + # + def mount(name, options={}) + Mounter.new(name, options) + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/reloader.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/reloader.rb new file mode 100644 index 00000000..b785ca59 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/reloader.rb @@ -0,0 +1,341 @@ +require 'pathname' + +module Padrino + ## + # High performance source code reloader middleware + # + module Reloader + ## + # This reloader is suited for use in a many environments because each file + # will only be checked once and only one system call to stat(2) is made. + # + # Please note that this will not reload files in the background, and does so + # only when explicitly invoked. + # + + # The modification times for every file in a project. + MTIMES = {} + # The list of files loaded as part of a project. + LOADED_FILES = {} + # The list of object constants and classes loaded as part of the project. + LOADED_CLASSES = {} + + class << self + ## + # Specified folders can be excluded from the code reload detection process. + # Default excluded directories at Padrino.root are: test, spec, features, tmp, config, db and public + # + def exclude + @_exclude ||= %w(test spec tmp features config public db).map { |path| Padrino.root(path) } + end + + ## + # Specified constants can be excluded from the code unloading process. + # + def exclude_constants + @_exclude_constants ||= Set.new + end + + ## + # Specified constants can be configured to be reloaded on every request. + # Default included constants are: [none] + # + def include_constants + @_include_constants ||= Set.new + end + + ## + # Reload all files with changes detected. + # + def reload! + # Detect changed files + rotation do |file, mtime| + # Retrive the last modified time + new_file = MTIMES[file].nil? + previous_mtime = MTIMES[file] ||= mtime + logger.devel "Detected a new file #{file}" if new_file + # We skip to next file if it is not new and not modified + next unless new_file || mtime > previous_mtime + # Now we can reload our file + apps = mounted_apps_of(file) + if apps.present? + apps.each { |app| app.app_obj.reload! } + else + safe_load(file, :force => new_file) + # Reload also apps + Padrino.mounted_apps.each do |app| + app.app_obj.reload! if app.app_obj.dependencies.include?(file) + end + end + end + end + + ## + # Remove files and classes loaded with stat + # + def clear! + clear_modification_times + clear_loaded_classes + clear_loaded_files_and_features + end + + ## + # Returns true if any file changes are detected and populates the MTIMES cache + # + def changed? + changed = false + rotation do |file, mtime| + new_file = MTIMES[file].nil? + previous_mtime = MTIMES[file] + changed = true if new_file || mtime > previous_mtime + end + changed + end + alias :run! :changed? + + ## + # We lock dependencies sets to prevent reloading of protected constants + # + def lock! + klasses = ObjectSpace.classes do |klass| + klass._orig_klass_name.split('::')[0] + end + + klasses = klasses | Padrino.mounted_apps.map { |app| app.app_class } + Padrino::Reloader.exclude_constants.merge(klasses) + end + + ## + # A safe Kernel::require which issues the necessary hooks depending on results + # + def safe_load(file, options={}) + began_at = Time.now + force = options[:force] + file = figure_path(file) + reload = should_reload?(file) + m_time = modification_time(file) + + return if !force && m_time && !reload + + remove_loaded_file_classes(file) + remove_loaded_file_features(file) + + # Duplicate objects and loaded features before load file + klasses = ObjectSpace.classes + files = Set.new($LOADED_FEATURES.dup) + + reload_deps_of_file(file) + + # And finally load the specified file + begin + logger.devel :loading, began_at, file if !reload + logger.debug :reload, began_at, file if reload + + $LOADED_FEATURES.delete(file) if files.include?(file) + Padrino::Utils.silence_output + loaded = false + require(file) + loaded = true + update_modification_time(file) + rescue SyntaxError => e + logger.error "Cannot require #{file} due to a syntax error: #{e.message}" + ensure + Padrino::Utils.unsilence_output + new_constants = ObjectSpace.new_classes(klasses) + if loaded + process_loaded_file(:file => file, + :constants => new_constants, + :files => files) + else + logger.devel "Failed to load #{file}; removing partially defined constants" + unload_constants(new_constants) + end + end + end + + ## + # Returns true if the file is defined in our padrino root. + # + def figure_path(file) + return file if Pathname.new(file).absolute? + $:.each do |path| + found = File.join(path, file) + return File.expand_path(found) if File.exist?(found) + end + file + end + + ## + # Removes the specified class and constant. + # + def remove_constant(const) + return if exclude_constants.any? { |c| const._orig_klass_name.index(c) == 0 } && + !include_constants.any? { |c| const._orig_klass_name.index(c) == 0 } + begin + parts = const.to_s.sub(/^::(Object)?/, 'Object::').split('::') + object = parts.pop + base = parts.empty? ? Object : Inflector.constantize(parts * '::') + base.send :remove_const, object + logger.devel "Removed constant: #{const} from #{base}" + rescue NameError; end + end + + private + + ### + # Clear instance variables that keep track of # loaded features/files/mtimes. + # + def clear_modification_times + MTIMES.clear + end + + def clear_loaded_classes + LOADED_CLASSES.each do |file, klasses| + klasses.each { |klass| remove_constant(klass) } + LOADED_CLASSES.delete(file) + end + end + + def clear_loaded_files_and_features + LOADED_FILES.each do |file, dependencies| + dependencies.each { |dependency| $LOADED_FEATURES.delete(dependency) } + $LOADED_FEATURES.delete(file) + end + end + + ### + # Macro for mtime query. + # + def modification_time(file) + MTIMES[file] + end + + ### + # Macro for mtime update. + # + def update_modification_time(file) + MTIMES[file] = File.mtime(file) + end + + ### + # Tracks loaded file features/classes/constants: + # + def process_loaded_file(*args) + options = args.extract_options! + new_constants = options[:constants] + files = options[:files] + file = options[:file] + + # Store the file details + LOADED_CLASSES[file] = new_constants + LOADED_FILES[file] = Set.new($LOADED_FEATURES) - files - [file] + + # Track only features in our Padrino.root + LOADED_FILES[file].delete_if { |feature| !in_root?(feature) } + end + + ### + # Unloads all constants in new_constants. + # + def unload_constants(new_constants) + new_constants.each { |klass| remove_constant(klass) } + end + + ### + # Safe load dependencies of a file. + # + def reload_deps_of_file(file) + if features = LOADED_FILES.delete(file) + features.each { |feature| safe_load(feature, :force => true) } + end + end + + ## + # Check if file was changed or if force a reload. + # + def should_reload?(file) + MTIMES[file] && File.mtime(file) > MTIMES[file] + end + + ## + # Removes all classes declared in the specified file. + # + def remove_loaded_file_classes(file) + if klasses = LOADED_CLASSES.delete(file) + klasses.each { |klass| remove_constant(klass) } + end + end + + ## + # Remove all loaded fatures with our file. + # + def remove_loaded_file_features(file) + if features = LOADED_FILES[file] + features.each { |feature| $LOADED_FEATURES.delete(feature) } + end + end + + ## + # Return the mounted_apps providing the app location. + # Can be an array because in one app.rb we can define multiple Padrino::Application. + # + def mounted_apps_of(file) + file = figure_path(file) + Padrino.mounted_apps.find_all { |app| File.identical?(file, app.app_file) } + end + + ## + # Returns true if file is in our Padrino.root. + # + def in_root?(file) + # This is better but slow: + # Pathname.new(Padrino.root).find { |f| File.identical?(Padrino.root(f), figure_path(file)) } + figure_path(file).index(Padrino.root) == 0 + end + + ## + # Searches Ruby files in your +Padrino.load_paths+ , Padrino::Application.load_paths + # and monitors them for any changes. + # + def rotation + files_for_rotation.uniq.map do |file| + file = File.expand_path(file) + next if Padrino::Reloader.exclude.any? { |base| file.index(base) == 0 } || !File.exist?(file) + yield file, File.mtime(file) + end.compact + end + + ## + # Creates an array of paths for use in #rotation. + # + def files_for_rotation + files = Padrino.load_paths.map { |path| Dir["#{path}/**/*.rb"] }.flatten + files = files | Padrino.mounted_apps.map { |app| app.app_file } + files = files | Padrino.mounted_apps.map { |app| app.app_obj.dependencies }.flatten + end + end # self + + ## + # This class acts as a Rack middleware to be added to the application stack. + # This middleware performs a check and reload for source files at the start + # of each request, but also respects a specified cool down time + # during which no further action will be taken. + # + class Rack + def initialize(app, cooldown=1) + @app = app + @cooldown = cooldown + @last = (Time.now - cooldown) + end + + # Invoked in order to perform the reload as part of the request stack. + def call(env) + if @cooldown && Time.now > @last + @cooldown + Thread.list.size > 1 ? Thread.exclusive { Padrino.reload! } : Padrino.reload! + @last = Time.now + end + @app.call(env) + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/router.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/router.rb new file mode 100644 index 00000000..1d0a9af9 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/router.rb @@ -0,0 +1,95 @@ +module Padrino + ## + # This class is an extended version of Rack::URLMap. + # + # Padrino::Router like Rack::URLMap dispatches in such a way that the + # longest paths are tried first, since they are most specific. + # + # Features: + # + # * Map a path to the specified App + # * Ignore server names (this solve issues with vhost and domain aliases) + # * Use hosts instead of server name for mappings (this help us with our vhost and domain aliases) + # + # @example + # + # routes = Padrino::Router.new do + # map(:path => "/", :to => PadrinoWeb, :host => "padrino.local") + # map(:path => "/", :to => Admin, :host => "admin.padrino.local") + # end + # run routes + # + # routes = Padrino::Router.new do + # map(:path => "/", :to => PadrinoWeb, :host => /*.padrino.local/) + # end + # run routes + # + # @api semipublic + class Router + def initialize(*mapping, &block) + @mapping = [] + mapping.each { |m| map(m) } + instance_eval(&block) if block + end + + ## + # Map a route path and host to a specified application. + # + # @param [Hash] options + # The options to map. + # @option options [Sinatra::Application] :to + # The class of the application to mount. + # @option options [String] :path ("/") + # The path to map the specified application. + # @option options [String] :host + # The host to map the specified application. + # + # @example + # map(:path => "/", :to => PadrinoWeb, :host => "padrino.local") + # + # @return [Array] The sorted route mappings. + # @api semipublic + def map(options={}) + path = options[:path] || "/" + host = options[:host] + app = options[:to] + + raise ArgumentError, "paths need to start with /" if path[0] != ?/ + raise ArgumentError, "app is required" if app.nil? + + path = path.chomp('/') + match = Regexp.new("^#{Regexp.quote(path).gsub('/', '/+')}(.*)", nil, 'n') + host = Regexp.new("^#{Regexp.quote(host)}$", true, 'n') unless host.nil? || host.is_a?(Regexp) + + @mapping << [host, path, match, app] + sort! + end + + # The call handler setup to route a request given the mappings specified. + def call(env) + path_info = env["PATH_INFO"].to_s + script_name = env['SCRIPT_NAME'] + http_host = env['HTTP_HOST'] + + @mapping.each do |host, path, match, app| + next unless host.nil? || http_host =~ host + next unless path_info =~ match && rest = $1 + next unless rest.empty? || rest[0] == ?/ + + rest = "/" if rest.empty? + + return app.call( + env.merge( + 'SCRIPT_NAME' => (script_name + path), + 'PATH_INFO' => rest)) + end + [404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path_info}"]] + end + + private + + def sort! + @mapping = @mapping.sort_by { |h, p, m, a| -p.size } + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/server.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/server.rb new file mode 100644 index 00000000..f8dd3323 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/server.rb @@ -0,0 +1,77 @@ +module Padrino + ## + # Runs the Padrino apps as a self-hosted server using: + # thin, mongrel, or WEBrick in that order. + # + # @example + # Padrino.run! # with these defaults => host: "127.0.0.1", port: "3000", adapter: the first found + # Padrino.run!("0.0.0.0", "4000", "mongrel") # use => host: "0.0.0.0", port: "4000", adapter: "mongrel" + # + def self.run!(options={}) + Padrino.load! + Server.start(Padrino.application, options) + end + + ## + # This module builds a Padrino server to run the project based on available handlers. + # + class Server < Rack::Server + # Server Handlers + Handlers = [:thin, :puma, :mongrel, :trinidad, :webrick] + + # Starts the application on the available server with specified options. + def self.start(app, opts={}) + options = {}.merge(opts) # We use a standard hash instead of Thor::CoreExt::HashWithIndifferentAccess + options.symbolize_keys! + options[:Host] = options.delete(:host) || '127.0.0.1' + options[:Port] = options.delete(:port) || 3000 + options[:AccessLog] = [] + if options[:daemonize] + options[:pid] = File.expand_path(options[:pid].blank? ? 'tmp/pids/server.pid' : opts[:pid]) + FileUtils.mkdir_p(File.dirname(options[:pid])) + end + options[:server] = detect_rack_handler if options[:server].blank? + new(options, app).start + end + + def initialize(options, app) + @options, @app = options, app + end + + # Starts the application on the available server with specified options. + def start + puts "=> Padrino/#{Padrino.version} has taken the stage #{Padrino.env} at http://#{options[:Host]}:#{options[:Port]}" + [:INT, :TERM].each { |sig| trap(sig) { exit } } + super + ensure + puts "<= Padrino leaves the gun, takes the cannoli" unless options[:daemonize] + end + + # The application the server will run. + def app + @app + end + alias :wrapped_app :app + + def options + @options + end + + private + # Detects the supported handler to use. + # + # @example + # detect_rack_handler => + # + def self.detect_rack_handler + Handlers.each do |handler| + begin + return handler if Rack::Handler.get(handler.to_s.downcase) + rescue LoadError + rescue NameError + end + end + fail "Server handler (#{Handlers.join(', ')}) not found." + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/support_lite.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/support_lite.rb new file mode 100644 index 00000000..97cbe518 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/support_lite.rb @@ -0,0 +1,260 @@ +## +# This file loads certain extensions required by Padrino from ActiveSupport. +# +require 'active_support/core_ext/module/aliasing' # alias_method_chain +require 'active_support/core_ext/hash/keys' # symbolize_keys +require 'active_support/core_ext/hash/reverse_merge' # reverse_merge +require 'active_support/core_ext/hash/slice' # slice +require 'active_support/core_ext/object/blank' # present? +require 'active_support/core_ext/array/extract_options' # extract_options +require 'active_support/inflector/methods' # constantize +require 'active_support/inflector/inflections' # pluralize +require 'active_support/core_ext/string/output_safety' # SafeBuffer and html_safe +require 'active_support/inflections' # load default inflections +require 'yaml' unless defined?(YAML) # load yaml for i18n +require 'win32console' if RUBY_PLATFORM =~ /(win|m)32/ # ruby color support for win + +## +# This is an adapted version of active_support/core_ext/string/inflections.rb +# to prevent loading several dependencies including I18n gem. +# +# Issue: https://github.com/rails/rails/issues/1526 +# +class String + ## + # Returns the plural form of the word in the string. + # + # "post".pluralize # => "posts" + # "octopus".pluralize # => "octopi" + # "sheep".pluralize # => "sheep" + # "words".pluralize # => "words" + # "the blue mailman".pluralize # => "the blue mailmen" + # "CamelOctopus".pluralize # => "CamelOctopi" + # + def pluralize + ActiveSupport::Inflector.pluralize(self) + end + + ## + # Returns the singular form of the word in the string. + # + # "posts".singularize # => "post" + # "octopi".singularize # => "octopus" + # "sheep".singularize # => "sheep" + # "words".singularize # => "word" + # "the blue mailmen".singularize # => "the blue mailman" + # "CamelOctopi".singularize # => "CamelOctopus" + # + def singularize + ActiveSupport::Inflector.singularize(self) + end + + ## + # +constantize+ tries to find a declared constant with the name specified + # in the string. It raises a NameError when the name is not in CamelCase + # or is not initialized. + # + # "Module".constantize # => Module + # "Class".constantize # => Class + # + def constantize + ActiveSupport::Inflector.constantize(self) + end + + ## + # The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string. + # + # +underscore+ will also change '::' to '/' to convert namespaces to paths. + # + # "ActiveRecord".underscore # => "active_record" + # "ActiveRecord::Errors".underscore # => active_record/errors + # + def underscore + ActiveSupport::Inflector.underscore(self) + end + + ## + # By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize + # is set to :lower then camelize produces lowerCamelCase. + # + # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces. + # + # "active_record".camelize # => "ActiveRecord" + # "active_record".camelize(:lower) # => "activeRecord" + # "active_record/errors".camelize # => "ActiveRecord::Errors" + # "active_record/errors".camelize(:lower) # => "activeRecord::Errors" + # + def camelize(first_letter = :upper) + case first_letter + when :upper then ActiveSupport::Inflector.camelize(self, true) + when :lower then ActiveSupport::Inflector.camelize(self, false) + end + end + alias_method :camelcase, :camelize + + ## + # Create a class name from a plural table name like Rails does for table names to models. + # Note that this returns a string and not a class. (To convert to an actual class + # follow +classify+ with +constantize+.) + # + # "egg_and_hams".classify # => "EggAndHam" + # "posts".classify # => "Post" + # + # Singular names are not handled correctly. + # + # "business".classify # => "Busines" + # + def classify + ActiveSupport::Inflector.classify(self) + end +end + +module ObjectSpace + class << self + ## + # Returns all the classes in the object space. + # Optionally, a block can be passed, for example the following code + # would return the classes that start with the character "A": + # + # ObjectSpace.classes do |klass| + # if klass.to_s[0] == "A" + # klass + # end + # end + # + def classes(&block) + rs = Set.new + + ObjectSpace.each_object(Class).each do |klass| + if block + if r = block.call(klass) + # add the returned value if the block returns something + rs << r + end + else + rs << klass + end + end + + rs + end + + ## + # Returns a list of existing classes that are not included in "snapshot" + # This method is useful to get the list of new classes that were loaded + # after an event like requiring a file. + # Usage: + # + # snapshot = ObjectSpace.classes + # # require a file + # ObjectSpace.new_classes(snapshot) + # + def new_classes(snapshot) + self.classes do |klass| + if !snapshot.include?(klass) + klass + end + end + end + end +end + +## +# FileSet helper method for iterating and interacting with files inside a directory +# +module FileSet + extend self + ## + # Iterates over every file in the glob pattern and yields to a block + # Returns the list of files matching the glob pattern + # FileSet.glob('padrino-core/application/*.rb', __FILE__) { |file| load file } + # + def glob(glob_pattern, file_path=nil, &block) + glob_pattern = File.join(File.dirname(file_path), glob_pattern) if file_path + file_list = Dir.glob(glob_pattern).sort + file_list.each { |file| block.call(file) } + file_list + end + + ## + # Requires each file matched in the glob pattern into the application + # FileSet.glob_require('padrino-core/application/*.rb', __FILE__) + # + def glob_require(glob_pattern, file_path=nil) + glob(glob_pattern, file_path) { |f| require f } + end +end + +## +# Removes indentation +# Add colors +# +# @example +# help <<-EOS.undent +# Here my help usage +# sample_code +# +# Fix +# EOS +# puts help.red.bold +# +class String + def self.colors + @_colors ||= { + :clear => 0, + :bold => 1, + :black => 30, + :red => 31, + :green => 32, + :yellow => 33, + :blue => 34, + :magenta => 35, + :cyan => 36, + :white => 37 + } + end + + colors.each do |color, value| + define_method(color) do + ["\e[", value.to_s, "m", self, "\e[", self.class.colors[:clear], "m"] * '' + end + end + + def undent + gsub(/^.{#{slice(/^ +/).size}}/, '') + end +end + +## +# Make sure we can always use the class name +# In reloader for accessing class_name Foo._orig_klass_name +# +class Module + alias :_orig_klass_name :to_s +end + +## +# Loads our locale configuration files +# +I18n.load_path += Dir["#{File.dirname(__FILE__)}/locale/*.yml"] if defined?(I18n) + +## +# Used to determine if this file has already been required +# +module SupportLite; end + +module Padrino + class Utils + ### + # Silences output verbosity level so load + # errors are not visible when safe_load(file) + # + def self.silence_output + @verbosity_level, $-v = $-v, nil + end + + def self.unsilence_output + $-v = @verbosity_level + end + end +end \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/tasks.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/tasks.rb new file mode 100644 index 00000000..143c3b99 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/tasks.rb @@ -0,0 +1,21 @@ +module Padrino + ## + # This module it's used for bootstrap with padrino rake + # third party tasks, in your gem/plugin/extension you + # need only do this: + # + # @example + # Padrino::Tasks.files << yourtask.rb + # Padrino::Tasks.files.concat(Dir["/path/to/all/my/tasks/*.rb"]) + # Padrino::Tasks.files.unshift("yourtask.rb") + # + module Tasks + + ## + # Returns a list of files to handle with padrino rake + # + def self.files + @files ||= [] + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/version.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/version.rb new file mode 100644 index 00000000..d61bd265 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/lib/padrino-core/version.rb @@ -0,0 +1,20 @@ +# +# Manages current Padrino version for use in gem generation. +# +# We put this in a separate file so you can get padrino version +# without include full padrino core. +# +module Padrino + # The version constant for the current version of Padrino. + VERSION = '0.11.4' unless defined?(Padrino::VERSION) + + # + # The current Padrino version. + # + # @return [String] + # The version number. + # + def self.version + VERSION + end +end # Padrino diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/padrino-core.gemspec b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/padrino-core.gemspec new file mode 100755 index 00000000..114296fe --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/padrino-core.gemspec @@ -0,0 +1,43 @@ +#!/usr/bin/env gem build +# encoding: utf-8 + +require File.expand_path("../lib/padrino-core/version.rb", __FILE__) + +Gem::Specification.new do |s| + s.name = "padrino-core" + s.rubyforge_project = "padrino-core" + s.authors = ["Padrino Team", "Nathan Esquenazi", "Davide D'Agostino", "Arthur Chiu"] + s.email = "padrinorb@gmail.com" + s.summary = "The required Padrino core gem" + s.homepage = "http://www.padrinorb.com" + s.description = "The Padrino core gem required for use of this framework" + s.required_rubygems_version = ">= 1.3.6" + s.version = Padrino.version + s.date = Time.now.strftime("%Y-%m-%d") + + s.extra_rdoc_files = Dir["*.rdoc"] + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + s.require_paths = ["lib"] + s.rdoc_options = ["--charset=UTF-8"] + + # TODO remove after a couple versions + # s.post_install_message = "\e[32m" + ("*" * 20) + # s.post_install_message << "\n UPGRADE NOTES\n\n\e[31m When upgrading, please 'enable :sessions' for each application" + # s.post_install_message << " as shown here:\e[0m http://bit.ly/kODKMx\n" + # s.post_install_message << "\e[31m When upgrading, please 'register Padrino::Rendering' for each application" + # s.post_install_message << " as shown here:\e[0m https://gist.github.com/1d36a35794dbbd664ea4" + # s.post_install_message << "\n\e[32m" + ("*" * 20) + "\n\e[0m" + + s.add_dependency("tilt", "~> 1.4.1") + if ENV["SINATRA_EDGE"] + s.add_dependency("sinatra") + else + s.add_dependency("sinatra", "~> 1.4.2") + end + s.add_dependency("http_router", "~> 0.11.0") + s.add_dependency("thor", "~> 0.17.0") + s.add_dependency("activesupport", ">= 3.1", "< 4.0") + s.add_dependency("rack-protection", ">= 1.5.0") +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/Gemfile b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/Gemfile new file mode 100644 index 00000000..d3e36607 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +# Specify your gem's dependencies in app_gem.gemspec +gemspec diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/app/app.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/app/app.rb new file mode 100644 index 00000000..e3af462e --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/app/app.rb @@ -0,0 +1,3 @@ +class AppGem::App < Padrino::Application + set :version, AppGem::VERSION +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/app_gem.gemspec b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/app_gem.gemspec new file mode 100644 index 00000000..e94081c1 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/app_gem.gemspec @@ -0,0 +1,17 @@ +# -*- encoding: utf-8 -*- +require File.expand_path('../lib/app_gem/version', __FILE__) + +Gem::Specification.new do |gem| + gem.authors = ["Florian Gilcher"] + gem.email = ["florian.gilcher@asquera.de"] + gem.description = %q{TODO: Write a gem description} + gem.summary = %q{TODO: Write a gem summary} + gem.homepage = "" + + gem.files = `git ls-files`.split($\) + gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } + gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) + gem.name = "app_gem" + gem.require_paths = ["app", "lib"] + gem.version = AppGem::VERSION +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/lib/app_gem.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/lib/app_gem.rb new file mode 100644 index 00000000..e4a4b239 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/lib/app_gem.rb @@ -0,0 +1,7 @@ +require 'padrino' + +module AppGem + extend Padrino::Module + + gem! 'app_gem' +end \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/lib/app_gem/version.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/lib/app_gem/version.rb new file mode 100644 index 00000000..ec2d476c --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/app_gem/lib/app_gem/version.rb @@ -0,0 +1,3 @@ +module AppGem + VERSION = "0.0.1" +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/apps/.components b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/apps/.components new file mode 100644 index 00000000..516c4a23 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/apps/.components @@ -0,0 +1,6 @@ +--- +:test: bacon +:mock: mocha +:orm: datamapper +:renderer: erb +:script: jquery diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/apps/.gitignore b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/apps/.gitignore new file mode 100644 index 00000000..ba335e37 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/apps/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +log/**/* +tmp/**/* +vendor/gems/gems +vendor/gems/specifications +vendor/gems/doc +vendor/gems/environment.rb \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/apps/complex.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/apps/complex.rb new file mode 100644 index 00000000..1d0a3975 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/apps/complex.rb @@ -0,0 +1,32 @@ +PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT + +module LibDemo + def self.give_me_a_random + @rand ||= rand(100) + end +end + +class Complex1Demo < Padrino::Application + set :reload, true + get("/old"){ "Old Sinatra Way" } +end + +class Complex2Demo < Padrino::Application + set :reload, true + get("/old"){ "Old Sinatra Way" } + + controllers :var do + get(:destroy){ params.inspect } + end + + get("/"){ "The magick number is: 12!" } # Change only the number!!! +end + +Complex1Demo.controllers do + get("/"){ "Given random #{LibDemo.give_me_a_random}" } +end + +Complex2Demo.controllers do +end + +Padrino.load! diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/apps/simple.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/apps/simple.rb new file mode 100644 index 00000000..fd9d3bc8 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/apps/simple.rb @@ -0,0 +1,33 @@ +PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT +# Remove this comment if you want do some like this: ruby PADRINO_ENV=test app.rb +# +# require 'rubygems' +# require 'padrino-core' +# + +class SimpleDemo < Padrino::Application + set :reload, true + before { true } + after { true } + error(404) { "404" } +end + +SimpleDemo.controllers do + get "/" do + 'The magick number is: 2767356926488785838763860464013972991031534522105386787489885890443740254365!' # Change only the number!!! + end + + get "/rand" do + rand(2 ** 256).to_s + end +end + +## If you want use this as a standalone app uncomment: +# +# Padrino.mount("SimpleDemo").to("/") +# Padrino.run! unless Padrino.loaded? # If you enable reloader prevent to re-run the app +# +# Then run it from your console: ruby -I"lib" test/fixtures/apps/simple.rb +# + +Padrino.load! diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/a.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/a.rb new file mode 100644 index 00000000..eecc8410 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/a.rb @@ -0,0 +1,9 @@ +# This file will be safe loaded three times. +# The first one fail because B and C constant are not defined +# The second one file because B requires C constant so will not be loaded +# The third one B and C are defined + +# But here we need some of b.rb +A_result = [B, C] + +A = "A" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/b.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/b.rb new file mode 100644 index 00000000..a9fcf5ac --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/b.rb @@ -0,0 +1,4 @@ +# But here we need some of c.rb and a.rb +B_result = C + +B = "B" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/c.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/c.rb new file mode 100644 index 00000000..adb57549 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/c.rb @@ -0,0 +1 @@ +C = "C" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/circular/e.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/circular/e.rb new file mode 100644 index 00000000..780b0ff4 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/circular/e.rb @@ -0,0 +1,13 @@ +class E + def self.fields + @fields ||= [] + end + + def self.inherited(subclass) + subclass.fields.replace fields.dup + end + + G + + fields << "name" +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/circular/f.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/circular/f.rb new file mode 100644 index 00000000..96ceea1c --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/circular/f.rb @@ -0,0 +1,2 @@ +class F < E +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/circular/g.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/circular/g.rb new file mode 100644 index 00000000..a9ecb812 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/circular/g.rb @@ -0,0 +1,2 @@ +class G +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/d.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/d.rb new file mode 100644 index 00000000..851aae1f --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/fixtures/dependencies/d.rb @@ -0,0 +1,4 @@ +D = 0 unless defined?(D) +D += 1 + +raise "SomeThing" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/helper.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/helper.rb new file mode 100644 index 00000000..ba921acf --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/helper.rb @@ -0,0 +1,83 @@ +ENV['PADRINO_ENV'] = 'test' +PADRINO_ROOT = File.dirname(__FILE__) unless defined?(PADRINO_ROOT) + +require File.expand_path('../../../load_paths', __FILE__) +require File.expand_path('../mini_shoulda', __FILE__) +require 'padrino-core' +require 'json' +require 'rack/test' +require 'rack' + +# Rubies < 1.9 don't handle hashes in the properly order so to prevent +# this issue for now we remove extra values from mimetypes. +Rack::Mime::MIME_TYPES.delete(".xsl") # In this way application/xml respond only to .xml + +class Sinatra::Base + # Allow assertions in request context + include MiniTest::Assertions +end + +class MiniTest::Spec + include Rack::Test::Methods + + # Sets up a Sinatra::Base subclass defined with the block + # given. Used in setup or individual spec methods to establish + # the application. + def mock_app(base=Padrino::Application, &block) + @app = Sinatra.new(base, &block) + end + + def app + Rack::Lint.new(@app) + end + + # Asserts that a file matches the pattern + def assert_match_in_file(pattern, file) + assert File.exist?(file), "File '#{file}' does not exist!" + assert_match pattern, File.read(file) + end + + # Delegate other missing methods to response. + def method_missing(name, *args, &block) + if response && response.respond_to?(name) + response.send(name, *args, &block) + else + super(name, *args, &block) + end + rescue Rack::Test::Error # no response yet + super(name, *args, &block) + end + + alias :response :last_response + + def create_template(name, content, options={}) + FileUtils.mkdir_p(File.dirname(__FILE__) + "/views") + FileUtils.mkdir_p(File.dirname(__FILE__) + "/views/layouts") + path = "/views/#{name}" + path += ".#{options.delete(:locale)}" if options[:locale].present? + path += ".#{options[:format]}" if options[:format].present? + path += ".erb" unless options[:format].to_s =~ /haml|rss|atom/ + path += ".builder" if options[:format].to_s =~ /rss|atom/ + file = File.dirname(__FILE__) + path + File.open(file, 'w') { |io| io.write content } + file + end + alias :create_view :create_template + alias :create_layout :create_template + + def remove_views + FileUtils.rm_rf(File.dirname(__FILE__) + "/views") + end + + def with_template(name, content, options={}) + # Build a temp layout + template = create_template(name, content, options) + yield + ensure + # Remove temp layout + File.unlink(template) rescue nil + remove_views + end + alias :with_view :with_template + alias :with_layout :with_template +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/mini_shoulda.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/mini_shoulda.rb new file mode 100644 index 00000000..b61816a3 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/mini_shoulda.rb @@ -0,0 +1,45 @@ +gem 'minitest' +require 'minitest/autorun' +require 'minitest/spec' +require 'mocha/setup' + +begin + require 'ruby-debug' +rescue LoadError; end + +class MiniTest::Spec + class << self + alias :setup :before unless defined?(Rails) + alias :teardown :after unless defined?(Rails) + alias :should :it + alias :context :describe + def should_eventually(desc) + it("should eventually #{desc}") { skip("Should eventually #{desc}") } + end + end + alias :assert_no_match :refute_match + alias :assert_not_nil :refute_nil + alias :assert_not_equal :refute_equal +end + +class ColoredIO + def initialize(io) + @io = io + end + + def print(o) + case o + when "." then @io.send(:print, o.green) + when "E" then @io.send(:print, o.red) + when "F" then @io.send(:print, o.yellow) + when "S" then @io.send(:print, o.magenta) + else @io.send(:print, o) + end + end + + def puts(*o) + super + end +end + +MiniTest::Unit.output = ColoredIO.new(MiniTest::Unit.output) diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_application.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_application.rb new file mode 100644 index 00000000..5c8b5632 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_application.rb @@ -0,0 +1,125 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require 'haml' + +class PadrinoPristine < Padrino::Application; end +class PadrinoTestApp < Padrino::Application; end +class PadrinoTestApp2 < Padrino::Application; end + +describe "Application" do + before { Padrino.clear! } + after { remove_views } + + context 'for application functionality' do + + should 'check default options' do + assert File.identical?(__FILE__, PadrinoPristine.app_file) + assert_equal :padrino_pristine, PadrinoPristine.app_name + assert_equal :test, PadrinoPristine.environment + assert_equal Padrino.root('views'), PadrinoPristine.views + assert PadrinoPristine.raise_errors + assert !PadrinoPristine.logging + assert !PadrinoPristine.sessions + assert !PadrinoPristine.dump_errors + assert !PadrinoPristine.show_exceptions + assert PadrinoPristine.raise_errors + assert !Padrino.configure_apps + end + + should 'check haml options on production' do + assert defined?(Haml), 'Haml not defined' + assert_equal :test, PadrinoPristine.environment + assert !PadrinoPristine.haml[:ugly] + Padrino.stub :env, :production do + PadrinoPristine.send :default_configuration! + assert_equal :production, Padrino.env + assert_equal :production, PadrinoPristine.environment + assert PadrinoPristine.haml[:ugly] + PadrinoPristine.environment = :test + end + end + + should 'check padrino specific options' do + assert !PadrinoPristine.instance_variable_get(:@_configured) + PadrinoPristine.send(:setup_application!) + assert_equal :padrino_pristine, PadrinoPristine.app_name + assert_equal 'StandardFormBuilder', PadrinoPristine.default_builder + assert PadrinoPristine.instance_variable_get(:@_configured) + assert !PadrinoPristine.reload? + end + + should 'set global project settings' do + Padrino.configure_apps { enable :sessions; set :foo, "bar" } + PadrinoTestApp.send(:default_configuration!) + PadrinoTestApp2.send(:default_configuration!) + assert PadrinoTestApp.sessions, "should have sessions enabled" + assert_equal "bar", PadrinoTestApp.settings.foo, "should have foo assigned" + assert_equal PadrinoTestApp.session_secret, PadrinoTestApp2.session_secret + end + + should 'be able to configure_apps multiple times' do + Padrino.configure_apps { set :foo1, "bar" } + Padrino.configure_apps { set :foo1, "bam" } + Padrino.configure_apps { set :foo2, "baz" } + PadrinoTestApp.send(:default_configuration!) + assert_equal "bam", PadrinoTestApp.settings.foo1, "should have foo1 assigned to bam" + assert_equal "baz", PadrinoTestApp.settings.foo2, "should have foo2 assigned to baz" + end + + should "have shared sessions accessible in project" do + Padrino.configure_apps { enable :sessions; set :session_secret, 'secret' } + Padrino.mount("PadrinoTestApp").to("/write") + Padrino.mount("PadrinoTestApp2").to("/read") + PadrinoTestApp.send :default_configuration! + PadrinoTestApp.get('/') { session[:foo] = "shared" } + PadrinoTestApp2.send(:default_configuration!) + PadrinoTestApp2.get('/') { session[:foo] } + @app = Padrino.application + get '/write' + get '/read' + assert_equal 'shared', body + end + + # compare to: test_routing: allow global provides + should "set content_type to nil if none can be determined" do + mock_app do + provides :xml + + get("/foo"){ "Foo in #{content_type.inspect}" } + get("/bar"){ "Foo in #{content_type.inspect}" } + end + + get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' } + assert_equal 'Foo in :xml', body + get '/foo' + assert_equal 'Foo in :xml', body + + get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' } + assert_equal "Foo in nil", body + end + + context "errors" do + should "haven't mapped errors on development" do + mock_app { get('/'){ 'HI' } } + get "/" + assert @app.errors.empty? + end + + should "have mapped errors on production" do + mock_app { set :environment, :production; get('/'){ 'HI' } } + get "/" + assert_equal 1, @app.errors.size + end + + should "overide errors" do + mock_app do + set :environment, :production + get('/'){ raise } + error(::Exception){ 'custom error' } + end + get "/" + assert_equal 1, @app.errors.size + assert_equal 'custom error', body + end + end + end # application functionality +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_core.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_core.rb new file mode 100644 index 00000000..546b1686 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_core.rb @@ -0,0 +1,77 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +describe "Core" do + def setup + Padrino.clear! + end + + context 'for core functionality' do + + should 'check some global methods' do + assert_respond_to Padrino, :root + assert_respond_to Padrino, :env + assert_respond_to Padrino, :application + assert_respond_to Padrino, :set_encoding + assert_respond_to Padrino, :load! + assert_respond_to Padrino, :reload! + assert_respond_to Padrino, :version + assert_respond_to Padrino, :configure_apps + end + + + should 'validate global helpers' do + assert_equal :test, Padrino.env + assert_match /\/test/, Padrino.root + assert_not_nil Padrino.version + end + + should 'set correct utf-8 encoding' do + Padrino.set_encoding + if RUBY_VERSION <'1.9' + assert_equal 'UTF8', $KCODE + else + assert_equal Encoding.default_external, Encoding::UTF_8 + assert_equal Encoding.default_internal, Encoding::UTF_8 + end + end + + should 'have load paths' do + assert_equal [Padrino.root('lib'), Padrino.root('models'), Padrino.root('shared')], Padrino.load_paths + end + + should 'raise application error if I instantiate a new padrino application without mounted apps' do + assert_raises(Padrino::ApplicationLoadError) { Padrino.application.new } + end + + should "check before/after padrino load hooks" do + Padrino.before_load { @_foo = 1 } + Padrino.after_load { @_foo += 1 } + Padrino.load! + assert_equal 1, Padrino.before_load.size + assert_equal 1, Padrino.after_load.size + assert_equal 2, @_foo + end + + should "add middlewares in front if specified" do + test = Class.new { + def initialize(app) + @app = app + end + + def call(env) + status, headers, body = @app.call(env) + headers["Middleware-Called"] = "yes" + return status, headers, body + end + } + + class Foo < Padrino::Application; end + + Padrino.use(test) + Padrino.mount(Foo).to("/") + + res = Rack::MockRequest.new(Padrino.application).get("/") + assert_equal "yes", res["Middleware-Called"] + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_csrf_protection.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_csrf_protection.rb new file mode 100644 index 00000000..fd6c7bd7 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_csrf_protection.rb @@ -0,0 +1,80 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +describe "Application" do + before { Padrino.clear! } + after { remove_views } + + context 'CSRF protection' do + context "with CSRF protection on" do + before do + mock_app do + enable :sessions + enable :protect_from_csrf + post('/'){ 'HI' } + end + end + + should "not allow requests without tokens" do + post "/" + assert_equal 403, status + end + + should "allow requests with correct tokens" do + post "/", {"authenticity_token" => "a"}, 'rack.session' => {:csrf => "a"} + assert_equal 200, status + end + + should "not allow requests with incorrect tokens" do + post "/", {"authenticity_token" => "a"}, 'rack.session' => {:csrf => "b"} + assert_equal 403, status + end + end + + context "without CSRF protection on" do + before do + mock_app do + enable :sessions + disable :protect_from_csrf + post('/'){ 'HI' } + end + end + + should "allows requests without tokens" do + post "/" + assert_equal 200, status + end + + should "allow requests with correct tokens" do + post "/", {"authenticity_token" => "a"}, 'rack.session' => {:csrf => "a"} + assert_equal 200, status + end + + should "allow requests with incorrect tokens" do + post "/", {"authenticity_token" => "a"}, 'rack.session' => {:csrf => "b"} + assert_equal 200, status + end + end + + context "with optional CSRF protection" do + before do + mock_app do + enable :sessions + enable :protect_from_csrf + set :allow_disabled_csrf, true + post('/on') { 'HI' } + post('/off', :csrf_protection => false) { 'HI' } + end + end + + should "allow access to routes with csrf_protection off" do + post "/off" + assert_equal 200, status + end + + should "not allow access to routes with csrf_protection on" do + post "/on" + assert_equal 403, status + end + end + end +end \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_dependencies.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_dependencies.rb new file mode 100644 index 00000000..4e2cfdd0 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_dependencies.rb @@ -0,0 +1,44 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +describe "Dependencies" do + context 'when we require a dependency that have another dependency' do + + should 'raise an error without reloading it twice' do + capture_io do + assert_raises(RuntimeError) do + Padrino.require_dependencies( + Padrino.root("fixtures/dependencies/a.rb"), + Padrino.root("fixtures/dependencies/b.rb"), + Padrino.root("fixtures/dependencies/c.rb"), + Padrino.root("fixtures/dependencies/d.rb") + ) + end + end + assert_equal 1, D + end + + should 'resolve dependency problems' do + capture_io do + Padrino.require_dependencies( + Padrino.root("fixtures/dependencies/a.rb"), + Padrino.root("fixtures/dependencies/b.rb"), + Padrino.root("fixtures/dependencies/c.rb") + ) + end + assert_equal ["B", "C"], A_result + assert_equal "C", B_result + end + + should 'remove partially loaded constants' do + capture_io do + Padrino.require_dependencies( + Padrino.root("fixtures/dependencies/circular/e.rb"), + Padrino.root("fixtures/dependencies/circular/f.rb"), + Padrino.root("fixtures/dependencies/circular/g.rb") + ) + end + + assert_equal ["name"], F.fields + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_filters.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_filters.rb new file mode 100644 index 00000000..a7b615d6 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_filters.rb @@ -0,0 +1,348 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +describe "Filters" do + should "filters by accept header" do + mock_app do + get '/foo', :provides => [:xml, :js] do + request.env['HTTP_ACCEPT'] + end + end + + get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' } + assert ok? + assert_equal 'application/xml', body + assert_equal 'application/xml;charset=utf-8', response.headers['Content-Type'] + + get '/foo.xml' + assert ok? + assert_equal 'application/xml;charset=utf-8', response.headers['Content-Type'] + + get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript' } + assert ok? + assert_equal 'application/javascript', body + assert_equal 'application/javascript;charset=utf-8', response.headers['Content-Type'] + + get '/foo.js' + assert ok? + assert_equal 'application/javascript;charset=utf-8', response.headers['Content-Type'] + + get '/foo', {}, { "HTTP_ACCEPT" => 'text/html' } + assert_equal 406, status + end + + should "allow passing & halting in before filters" do + mock_app do + controller do + before { env['QUERY_STRING'] == 'secret' or pass } + get :index do + "secret index" + end + end + + controller do + before { env['QUERY_STRING'] == 'halt' and halt 401, 'go away!' } + get :index do + "index" + end + end + end + + get "/?secret" + assert_equal "secret index", body + + get "/?halt" + assert_equal "go away!", body + assert_equal 401, status + + get "/" + assert_equal "index", body + end + + should 'scope filters in the given controller' do + mock_app do + before { @global = 'global' } + after { @global = nil } + + controller :foo do + before { @foo = :foo } + after { @foo = nil } + get("/") { [@foo, @bar, @global].compact.join(" ") } + end + + get("/") { [@foo, @bar, @global].compact.join(" ") } + + controller :bar do + before { @bar = :bar } + after { @bar = nil } + get("/") { [@foo, @bar, @global].compact.join(" ") } + end + end + + get "/bar" + assert_equal "bar global", body + + get "/foo" + assert_equal "foo global", body + + get "/" + assert_equal "global", body + end + + should 'be able to access params in a before filter' do + username_from_before_filter = nil + + mock_app do + before do + username_from_before_filter = params[:username] + end + + get :users, :with => :username do + end + end + get '/users/josh' + assert_equal 'josh', username_from_before_filter + end + + should "be able to access params normally when a before filter is specified" do + mock_app do + before { } + get :index do + params.inspect + end + end + get '/?test=what' + assert_equal '{"test"=>"what"}', body + end + + should "be able to filter based on a path" do + mock_app do + before('/') { @test = "#{@test}before"} + get :index do + @test + end + get :main do + @test + end + end + get '/' + assert_equal 'before', body + get '/main' + assert_equal '', body + end + + should "be able to filter based on a symbol" do + mock_app do + before(:index) { @test = 'before'} + get :index do + @test + end + get :main do + @test + end + end + get '/' + assert_equal 'before', body + get '/main' + assert_equal '', body + end + + should "be able to filter based on a symbol for a controller" do + mock_app do + controller :foo do + before(:test) { @test = 'foo'} + get :test do + @test.to_s + " response" + end + end + controller :bar do + before(:test) { @test = 'bar'} + get :test do + @test.to_s + " response" + end + end + end + get '/foo/test' + assert_equal 'foo response', body + get '/bar/test' + assert_equal 'bar response', body + end + + should "be able to filter based on a symbol or path" do + mock_app do + before(:index, '/main') { @test = 'before'} + get :index do + @test + end + get :main do + @test + end + end + get '/' + assert_equal 'before', body + get '/main' + assert_equal 'before', body + end + + should "be able to filter based on a symbol or regexp" do + mock_app do + before(:index, /main/) { @test = 'before'} + get :index do + @test + end + get :main do + @test + end + get :profile do + @test + end + end + get '/' + assert_equal 'before', body + get '/main' + assert_equal 'before', body + get '/profile' + assert_equal '', body + end + + should "be able to filter excluding based on a symbol" do + mock_app do + before(:except => :index) { @test = 'before'} + get :index do + @test + end + get :main do + @test + end + end + get '/' + assert_equal '', body + get '/main' + assert_equal 'before', body + end + + should "be able to filter based on a request param" do + mock_app do + before(:agent => /IE/) { @test = 'before'} + get :index do + @test + end + end + get '/' + assert_equal '', body + get "/", {}, {'HTTP_USER_AGENT' => 'This is IE'} + assert_equal 'before', body + end + + should "be able to filter based on a symbol or path in multiple controller" do + mock_app do + controllers :foo do + before(:index, '/foo/main') { @test = 'before' } + get :index do + @test + end + get :main do + @test + end + end + controllers :bar do + before(:index, '/bar/main') { @test = 'also before' } + get :index do + @test + end + get :main do + @test + end + end + end + get '/foo' + assert_equal 'before', body + get '/bar' + assert_equal 'also before', body + get '/foo/main' + assert_equal 'before', body + get '/bar/main' + assert_equal 'also before', body + end + + should "call before filters even if there was no match" do + test = nil + mock_app do + before(:index, '/foo') { test = 'before' } + get :index do + '' + end + end + get '/foo' + assert_equal 'before', test + end + + should "call before filters only once" do + once = '' + mock_app do + error 500 do + 'error 500' + end + before do + once += 'before' + end + get :index do + raise Exception, 'Oops' + end + end + + get '/' + assert_equal 'before', once + end + + should 'catch exceptions in before filters' do + doodle = nil + mock_app do + after do + doodle = 'Been after' + end + before do + raise StandardError, "before" + end + get :index do + doodle = 'Been now' + end + error 500 do + "We broke #{env['sinatra.error'].message}" + end + end + + get '/' + assert_equal 'We broke before', body + assert_equal nil, doodle + end + + should 'catch exceptions in after filters if no exceptions caught before' do + doodle = '' + mock_app do + after do + doodle += ' and after' + raise StandardError, "after" + end + get :foo do + doodle = 'Been now' + raise StandardError, "now" + end + get :index do + doodle = 'Been now' + end + error 500 do + "We broke #{env['sinatra.error'].message}" + end + end + + get '/foo' + assert_equal 'We broke now', body + assert_equal 'Been now', doodle + + doodle = '' + get '/' + assert_equal 'We broke after', body + assert_equal 'Been now and after', doodle + end + +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_flash.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_flash.rb new file mode 100644 index 00000000..0e5bb8e9 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_flash.rb @@ -0,0 +1,168 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +describe Padrino::Flash do + context 'storage' do + before do + @storage = Padrino::Flash::Storage.new( + :success => 'Success msg', + :error => 'Error msg', + :notice => 'Notice msg', + :custom => 'Custom msg' + ) + @storage[:one] = 'One msg' + @storage[:two] = 'Two msg' + end + + should 'acts like hash' do + assert_respond_to @storage, :[] + end + + should 'know its size' do + assert_equal 4, @storage.length + assert_equal @storage.length, @storage.size + end + + should 'sweep its content' do + assert_equal 2, @storage.sweep.size + assert_empty @storage.sweep + end + + should 'discard everything' do + assert_empty @storage.discard.sweep + end + + should 'discard specified key' do + assert_equal 1, @storage.discard(:one).sweep.size + end + + should 'keep everything' do + assert_equal 2, @storage.sweep.keep.sweep.size + end + + should 'keep only specified key' do + assert_equal 1, @storage.sweep.keep(:one).sweep.size + end + + should 'not know the values you set right away' do + @storage[:foo] = 'bar' + assert_nil @storage[:foo] + end + + should 'knows the values you set next time' do + @storage[:foo] = 'bar' + @storage.sweep + assert_equal 'bar', @storage[:foo] + end + + should 'set values for now' do + @storage.now[:foo] = 'bar' + assert_equal 'bar', @storage[:foo] + end + + should 'forgets values you set only for now next time' do + @storage.now[:foo] = 'bar' + @storage.sweep + assert_nil @storage[:foo] + end + end + + routes = Proc.new do + get :index do + params[:key] ? flash[params[:key].to_sym].to_s : flash.now.inspect + end + + post :index do + params.each { |k,v| flash[k.to_sym] = v.to_s } + flash.next.inspect + end + + get :session do + settings.sessions?.inspect + end + + get :redirect do + redirect url(:index, :key => :foo), 301, :foo => 'redirected!' + end + + get :success do + flash.success = 'Yup' + end + + get :error do + flash.error = 'Arg' + end + + get :notice do + flash.notice = 'Mmm' + end + end + + context 'padrino application without sessions' do + before { mock_app(&routes) } + + should 'show nothing' do + get '/' + assert_equal '{}', body + end + + should 'set a flash' do + post '/', :foo => :bar + assert_equal '{:foo=>"bar"}', body + end + end + + context 'padrino application with sessions' do + before do + mock_app { enable :sessions; class_eval(&routes) } + end + + should 'be sure have sessions enabled' do + assert @app.sessions + get '/session' + assert_equal 'true', body + end + + should 'show nothing' do + get '/' + assert_equal '{}', body + end + + should 'set a flash' do + post '/', :foo => :bar + assert_equal '{:foo=>"bar"}', body + end + + should 'get a flash' do + post '/', :foo => :bar + get '/', :key => :foo + assert_equal 'bar', body + post '/' + assert_equal '{}', body + end + + should 'follow redirects with flash' do + get '/redirect' + follow_redirect! + assert_equal 'redirected!', body + assert 301, status + end + + should 'set success' do + get '/success' + get '/', :key => :success + assert_equal 'Yup', body + end + + should 'set error' do + get '/error' + get '/', :key => :error + assert_equal 'Arg', body + end + + should 'set notice' do + get '/notice' + get '/', :key => :notice + assert_equal 'Mmm', body + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_locale.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_locale.rb new file mode 100644 index 00000000..7972fc59 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_locale.rb @@ -0,0 +1,21 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +describe "Locales" do + Dir[File.expand_path("../../lib/padrino-core/locale/*.yml", __FILE__)].each do |file| + base_original = YAML.load_file(file) + name = File.basename(file, '.yml') + should "should have correct locale for #{name}" do + base = base_original[name]['date']['formats'] + assert base['default'].present? + assert base['short'].present? + assert base['long'].present? + assert base['only_day'].present? + base = base_original[name]['date'] + assert base['day_names'].present? + assert base['abbr_day_names'].present? + assert base['month_names'].present? + assert base['abbr_month_names'].present? + assert base['order'].present? + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_logger.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_logger.rb new file mode 100644 index 00000000..68c9f834 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_logger.rb @@ -0,0 +1,210 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require 'lumberjack' +require 'logger' + +describe "PadrinoLogger" do + + def setup + Padrino::Logger::Config[:test][:stream] = :null # The default + Padrino::Logger.setup! + end + + def setup_logger(options={}) + @log = StringIO.new + @logger = Padrino::Logger.new(options.merge(:stream => @log)) + end + + context 'for logger functionality' do + + context 'check stream config' do + + should 'use stdout if stream is nil' do + Padrino::Logger::Config[:test][:stream] = nil + Padrino::Logger.setup! + assert_equal $stdout, Padrino.logger.log + end + + should 'use StringIO as default for test' do + assert_instance_of StringIO, Padrino.logger.log + end + + should 'use a custom stream' do + my_stream = StringIO.new + Padrino::Logger::Config[:test][:stream] = my_stream + Padrino::Logger.setup! + assert_equal my_stream, Padrino.logger.log + end + end + + should 'log something' do + setup_logger(:log_level => :error) + @logger.error "You log this error?" + assert_match(/You log this error?/, @log.string) + @logger.debug "You don't log this error!" + assert_no_match(/You don't log this error!/, @log.string) + @logger << "Yep this can be logged" + assert_match(/Yep this can be logged/, @log.string) + end + + should 'respond to #write for Rack::CommonLogger' do + setup_logger(:log_level => :error) + @logger.error "Error message" + assert_match /Error message/, @log.string + @logger << "logged anyways" + assert_match /logged anyways/, @log.string + @logger.write "log via alias" + assert_match /log via alias/, @log.string + end + + should 'log an application' do + mock_app do + enable :logging + get("/"){ "Foo" } + end + get "/" + assert_equal "Foo", body + assert_match /GET/, Padrino.logger.log.string + end + + should 'log an application\'s status code' do + mock_app do + enable :logging + get("/"){ "Foo" } + end + get "/" + assert_match /\e\[1m200\e\[0m OK/, Padrino.logger.log.string + end + + context "static asset logging" do + should 'not log static assets by default' do + mock_app do + enable :logging + get("/images/something.png"){ env["sinatra.static_file"] = '/public/images/something.png'; "Foo" } + end + get "/images/something.png" + assert_equal "Foo", body + assert_match "", Padrino.logger.log.string + end + + should 'allow turning on static assets logging' do + Padrino.logger.instance_eval{ @log_static = true } + mock_app do + enable :logging + get("/images/something.png"){ env["sinatra.static_file"] = '/public/images/something.png'; "Foo" } + end + get "/images/something.png" + assert_equal "Foo", body + assert_match /GET/, Padrino.logger.log.string + Padrino.logger.instance_eval{ @log_static = false } + end + end + + context "health-check requests logging" do + def access_to_mock_app + mock_app do + enable :logging + get("/"){ "Foo" } + end + get "/" + end + + should 'output under debug level' do + Padrino.logger.instance_eval{ @level = Padrino::Logger::Levels[:debug] } + access_to_mock_app + assert_match /\e\[36m DEBUG\e\[0m/, Padrino.logger.log.string + + Padrino.logger.instance_eval{ @level = Padrino::Logger::Levels[:devel] } + access_to_mock_app + assert_match /\e\[36m DEBUG\e\[0m/, Padrino.logger.log.string + end + should 'not output over debug level' do + Padrino.logger.instance_eval{ @level = Padrino::Logger::Levels[:info] } + access_to_mock_app + assert_equal '', Padrino.logger.log.string + + Padrino.logger.instance_eval{ @level = Padrino::Logger::Levels[:error] } + access_to_mock_app + assert_equal '', Padrino.logger.log.string + end + end + end +end + +describe "alternate logger: Lumberjack" do + def setup_logger + @log = StringIO.new + Padrino.logger = Lumberjack::Logger.new(@log, :level => :debug) + end + + should "annotate the logger to support additional Padrino fancyness" do + setup_logger + Padrino.logger.debug("Debug message") + assert_match(/Debug message/, @log.string) + end + + should "colorize log output after colorize! is called" do + setup_logger + Padrino.logger.colorize! + + mock_app do + enable :logging + get("/"){ "Foo" } + end + get "/" + + assert_match /\e\[1m200\e\[0m OK/, @log.string + end +end + +describe "alternate logger: stdlib logger" do + def setup_logger + @log = StringIO.new + Padrino.logger = Logger.new(@log) + end + + should "annotate the logger to support additional Padrino fancyness" do + setup_logger + Padrino.logger.debug("Debug message") + assert_match(/Debug message/, @log.string) + end + + should "colorize log output after colorize! is called" do + setup_logger + Padrino.logger.colorize! + + mock_app do + enable :logging + get("/"){ "Foo" } + end + get "/" + + assert_match /\e\[1m200\e\[0m OK/, @log.string + end +end + +describe "options :colorize_logging" do + def access_to_mock_app + mock_app do + enable :logging + get("/"){ "Foo" } + end + get "/" + end + context 'default' do + should 'use colorize logging' do + Padrino::Logger.setup! + + access_to_mock_app + assert_match /\e\[1m200\e\[0m OK/, Padrino.logger.log.string + end + end + context 'set value is false' do + should 'not use colorize logging' do + Padrino::Logger::Config[:test][:colorize_logging] = false + Padrino::Logger.setup! + + access_to_mock_app + assert_match /200 OK/, Padrino.logger.log.string + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_mounter.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_mounter.rb new file mode 100644 index 00000000..097be4b7 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_mounter.rb @@ -0,0 +1,199 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +describe "Mounter" do + class ::TestApp < Padrino::Application; end + + def setup + $VERBOSE, @_verbose_was = nil, $VERBOSE + Padrino.clear! + end + + def teardown + $VERBOSE = @_verbose_was + end + + context 'for mounter functionality' do + should 'check methods' do + mounter = Padrino::Mounter.new("test_app", :app_file => "/path/to/test.rb") + mounter.to("/test_app") + assert_kind_of Padrino::Mounter, mounter + assert_respond_to Padrino::Mounter, :new + assert_respond_to mounter, :to + assert_respond_to mounter, :map_onto + assert_equal "test_app", mounter.name + assert_equal "TestApp", mounter.app_class + assert_equal "/path/to/test.rb", mounter.app_file + assert_equal "/test_app", mounter.uri_root + assert_equal File.dirname(mounter.app_file), mounter.app_root + end + + should 'check locate_app_file with __FILE__' do + mounter = Padrino::Mounter.new("test_app", :app_file => __FILE__) + mounter.to("/test_app") + assert_equal "test_app", mounter.name + assert_equal "TestApp", mounter.app_class + assert_equal __FILE__, mounter.app_file + assert_equal "/test_app", mounter.uri_root + assert_equal File.dirname(mounter.app_file), mounter.app_root + end + + should 'mount an app' do + class ::AnApp < Padrino::Application; end + Padrino.mount("an_app").to("/") + assert_equal AnApp, Padrino.mounted_apps.first.app_obj + assert_equal ["an_app"], Padrino.mounted_apps.map(&:name) + end + + should 'correctly mount an app in a namespace' do + module ::SomeNamespace + class AnApp < Padrino::Application; end + end + Padrino.mount("some_namespace/an_app").to("/") + assert_equal SomeNamespace::AnApp, Padrino.mounted_apps.first.app_obj + assert_equal ["some_namespace/an_app"], Padrino.mounted_apps.map(&:name) + end + + should 'mount a primary app to root uri' do + mounter = Padrino.mount("test_app", :app_file => __FILE__).to("/") + assert_equal "test_app", mounter.name + assert_equal "TestApp", mounter.app_class + assert_equal TestApp, mounter.app_obj + assert_equal __FILE__, mounter.app_file + assert_equal "/", mounter.uri_root + assert_equal File.dirname(mounter.app_file), mounter.app_root + end + + should 'mount a primary app to sub_uri' do + mounter = Padrino.mount("test_app", :app_file => __FILE__).to('/me') + assert_equal "test_app", mounter.name + assert_equal "TestApp", mounter.app_class + assert_equal TestApp, mounter.app_obj + assert_equal __FILE__, mounter.app_file + assert_equal "/me", mounter.uri_root + assert_equal File.dirname(mounter.app_file), mounter.app_root + end + + should "raise error when app has no located file" do + # TODO enabling this screws minitest + # assert_raises(Padrino::Mounter::MounterException) { Padrino.mount("tester_app").to('/test') } + assert_equal 0, Padrino.mounted_apps.size + end + + should "raise error when app has no located object" do + assert_raises(Padrino::Mounter::MounterException) { Padrino.mount("tester_app", :app_file => "/path/to/file.rb").to('/test') } + assert_equal 0, Padrino.mounted_apps.size + end + + should 'mount multiple apps' do + class ::OneApp < Padrino::Application; end + class ::TwoApp < Padrino::Application; end + + Padrino.mount("one_app").to("/one_app") + Padrino.mount("two_app").to("/two_app") + # And testing no duplicates + Padrino.mount("one_app").to("/one_app") + Padrino.mount("two_app").to("/two_app") + + assert_equal OneApp, Padrino.mounted_apps[0].app_obj + assert_equal TwoApp, Padrino.mounted_apps[1].app_obj + assert_equal 2, Padrino.mounted_apps.size, "should not mount duplicate apps" + assert_equal ["one_app", "two_app"], Padrino.mounted_apps.map(&:name) + end + + should 'change mounted_root' do + Padrino.mounted_root = "fixtures" + assert_equal Padrino.root("fixtures", "test", "app.rb"), Padrino.mounted_root("test", "app.rb") + Padrino.mounted_root = "apps" + assert_equal Padrino.root("apps", "test", "app.rb"), Padrino.mounted_root("test", "app.rb") + Padrino.mounted_root = nil + assert_equal Padrino.root("test", "app.rb"), Padrino.mounted_root("test", "app.rb") + end + + should "be able to access routes data for mounted apps" do + class ::OneApp < Padrino::Application + get("/test") { "test" } + get(:index, :provides => [:js, :json]) { "index" } + get(%r{/foo|/baz}) { "regexp" } + controllers :posts do + get(:index) { "index" } + get(:new, :provides => :js) { "new" } + get(:show, :provides => [:js, :html], :with => :id) { "show" } + post(:create, :provides => :js, :with => :id) { "create" } + get(:regexp, :map => %r{/foo|/baz}) { "regexp" } + end + end + class ::TwoApp < Padrino::Application + controllers :users do + get(:index) { "users" } + get(:new) { "users new" } + post(:create) { "users create" } + put(:update) { "users update" } + delete(:destroy) { "users delete" } + end + end + + Padrino.mount("one_app").to("/") + Padrino.mount("two_app").to("/two_app") + + assert_equal 15, Padrino.mounted_apps[0].routes.size + assert_equal 7, Padrino.mounted_apps[1].routes.size + assert_equal 6, Padrino.mounted_apps[0].named_routes.size + assert_equal 5, Padrino.mounted_apps[1].named_routes.size + + first_route = Padrino.mounted_apps[0].named_routes[3] + assert_equal "posts_show", first_route.identifier.to_s + assert_equal "(:posts, :show)", first_route.name + assert_equal "GET", first_route.verb + assert_equal "/posts/show/:id(.:format)", first_route.path + another_route = Padrino.mounted_apps[1].named_routes[2] + assert_equal "users_create", another_route.identifier.to_s + assert_equal "(:users, :create)", another_route.name + assert_equal "POST", another_route.verb + assert_equal "/two_app/users/create", another_route.path + regexp_route = Padrino.mounted_apps[0].named_routes[5] + assert_equal "posts_regexp", regexp_route.identifier.to_s + assert_equal "(:posts, :regexp)", regexp_route.name + assert_equal "/\\/foo|\\/baz/", regexp_route.path + end + + should 'correctly instantiate a new padrino application' do + mock_app do + get("/demo_1"){ "Im Demo 1" } + get("/demo_2"){ "Im Demo 2" } + end + + get '/demo_1' + assert_equal "Im Demo 1", response.body + get '/demo_2' + assert_equal "Im Demo 2", response.body + end + + should "not clobber the public setting when mounting an app" do + class ::PublicApp < Padrino::Application + set :root, "/root" + set :public_folder, File.expand_path(File.dirname(__FILE__)) + end + + Padrino.mount("public_app").to("/public") + res = Rack::MockRequest.new(Padrino.application).get("/public/test_mounter.rb") + assert res.ok? + assert_equal File.read(__FILE__), res.body + end + + should "load apps from gems" do + spec_file = Padrino.root("fixtures", "app_gem", "app_gem.gemspec") + spec = Gem::Specification.load(spec_file) + spec.activate + def spec.full_gem_path + Padrino.root("fixtures", "app_gem") + end + + require Padrino.root("fixtures", "app_gem", "lib", "app_gem") + + Padrino.mount("AppGem::App").to("/from_gem") + mounter = Padrino.mounted_apps[0] + assert_equal AppGem::App, mounter.app_obj + assert_equal Padrino.root('public'), mounter.app_obj.public_folder + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_reloader_complex.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_reloader_complex.rb new file mode 100644 index 00000000..d64af1a2 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_reloader_complex.rb @@ -0,0 +1,75 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require File.expand_path(File.dirname(__FILE__) + '/fixtures/apps/complex') + +describe "ComplexReloader" do + + context 'for complex reload functionality' do + setup do + Padrino.clear! + Padrino.mount("complex_1_demo").to("/complex_1_demo") + Padrino.mount("complex_2_demo").to("/complex_2_demo") + end + + should 'correctly instantiate Complex(1-2)Demo fixture' do + assert_equal ["/complex_1_demo", "/complex_2_demo"], Padrino.mounted_apps.map(&:uri_root) + assert_equal ["complex_1_demo", "complex_2_demo"], Padrino.mounted_apps.map(&:name) + assert Complex1Demo.reload? + assert Complex2Demo.reload? + assert_match %r{fixtures/apps/complex.rb}, Complex1Demo.app_file + assert_match %r{fixtures/apps/complex.rb}, Complex2Demo.app_file + end + + should 'correctly reload Complex(1-2)Demo fixture' do + assert_match %r{fixtures/apps/complex.rb}, Complex1Demo.app_file + @app = Padrino.application + + get "/" + assert_equal 404, status + + get "/complex_1_demo" + assert_equal "Given random #{LibDemo.give_me_a_random}", body + + get "/complex_2_demo" + assert_equal 200, status + + get "/complex_1_demo/old" + assert_equal 200, status + + get "/complex_2_demo/old" + assert_equal 200, status + + get "/complex_2_demo/var/destroy" + assert_equal '{}', body + + new_phrase = "The magick number is: #{rand(2**255)}!" + buffer = File.read(Complex1Demo.app_file) + new_buffer = buffer.gsub(/The magick number is: \d+!/, new_phrase) + new_buffer.gsub!(/get\(:destroy\)/, 'get(:destroy, :with => :id)') + begin + File.open(Complex1Demo.app_file, "w") { |f| f.write(new_buffer) } + sleep 1.2 # We need at least a cooldown of 1 sec. + get "/complex_2_demo" + assert_equal new_phrase, body + + # Re-Check that we didn't forget any route + get "/complex_1_demo" + assert_equal "Given random #{LibDemo.give_me_a_random}", body + + get "/complex_2_demo" + assert_equal 200, status + + get "/complex_1_demo/old" + assert_equal 200, status + + get "/complex_2_demo/old" + assert_equal 200, status + + get "/complex_2_demo/var/destroy/variable" + assert_equal '{:id=>"variable"}', body + ensure + # Now we need to prevent to commit a new changed file so we revert it + File.open(Complex1Demo.app_file, "w") { |f| f.write(buffer) } + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_reloader_simple.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_reloader_simple.rb new file mode 100644 index 00000000..ffcc37f4 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_reloader_simple.rb @@ -0,0 +1,98 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require File.expand_path(File.dirname(__FILE__) + '/fixtures/apps/simple') + +describe "SimpleReloader" do + + context 'for simple reset functionality' do + + should 'reset routes' do + mock_app do + (1..10).each do |i| + get("/#{i}") { "Foo #{i}" } + end + end + (1..10).each do |i| + get "/#{i}" + assert_equal "Foo #{i}", body + end + @app.reset_routes! + (1..10).each do |i| + get "/#{i}" + assert_equal 404, status + end + end + + should 'keep sinatra routes on development' do + mock_app do + set :environment, :development + get("/"){ "ok" } + end + assert_equal :development, @app.environment + get "/" + assert_equal 200, status + get "/__sinatra__/404.png" + assert_equal 200, status + assert_match /image\/png/, response["Content-Type"] + @app.reset_routes! + get "/" + assert_equal 404, status + get "/__sinatra__/404.png" + assert_equal 200, status + assert_match /image\/png/, response["Content-Type"] + end + end + + context 'for simple reload functionality' do + + should 'correctly instantiate SimpleDemo fixture' do + Padrino.clear! + Padrino.mount("simple_demo").to("/") + assert_equal ["simple_demo"], Padrino.mounted_apps.map(&:name) + assert SimpleDemo.reload? + assert_match %r{fixtures/apps/simple.rb}, SimpleDemo.app_file + end + + should_eventually 'correctly reload SimpleDemo fixture' do + # TODO fix this test + @app = SimpleDemo + get "/" + assert ok? + new_phrase = "The magick number is: #{rand(2**255)}!" + buffer = File.read(SimpleDemo.app_file) + new_buffer = buffer.gsub(/The magick number is: \d+!/, new_phrase) + File.open(SimpleDemo.app_file, "w") { |f| f.write(new_buffer) } + sleep 2 # We need at least a cooldown of 1 sec. + get "/" + assert_equal new_phrase, body + + # Now we need to prevent to commit a new changed file so we revert it + File.open(SimpleDemo.app_file, "w") { |f| f.write(buffer) } + Padrino.reload! + end + + should 'correctly reset SimpleDemo fixture' do + @app = SimpleDemo + @app.reload! + get "/rand" + assert ok? + last_body = body + assert_equal 2, @app.filters[:before].size # one is ours the other is default_filter for content type + assert_equal 1, @app.errors.size + assert_equal 2, @app.filters[:after].size # app + content-type + padrino-flash + assert_equal 0, @app.middleware.size + assert_equal 4, @app.routes.size # GET+HEAD of "/" + GET+HEAD of "/rand" = 4 + assert_equal 3, @app.extensions.size # [Padrino::Routing, Padrino::Rendering, Padrino::Flash] + assert_equal 0, @app.templates.size + @app.reload! + get "/rand" + assert_not_equal last_body, body + assert_equal 2, @app.filters[:before].size # one is ours the other is default_filter for content type + assert_equal 1, @app.errors.size + assert_equal 2, @app.filters[:after].size + assert_equal 0, @app.middleware.size + assert_equal 4, @app.routes.size # GET+HEAD of "/" = 2 + assert_equal 3, @app.extensions.size # [Padrino::Routing, Padrino::Rendering, Padrino::Flash] + assert_equal 0, @app.templates.size + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_rendering.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_rendering.rb new file mode 100644 index 00000000..8cceffaf --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_rendering.rb @@ -0,0 +1,545 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require 'i18n' +require 'slim' + +describe "Rendering" do + def setup + Padrino::Application.send(:register, Padrino::Rendering) + Padrino::Rendering::DEFAULT_RENDERING_OPTIONS[:strict_format] = false + end + + def teardown + remove_views + end + + context 'for application layout functionality' do + + should 'get no layout' do + mock_app do + get("/"){ "no layout" } + end + + get "/" + assert_equal "no layout", body + end + + should 'be compatible with sinatra layout' do + mock_app do + layout do + "this is a <%= yield %>" + end + + get("/"){ render :erb, "sinatra layout", :layout => true } + end + + get "/" + assert_equal "this is a sinatra layout", body + end + + should 'use rails way layout' do + with_layout :application, "this is a <%= yield %>" do + mock_app do + get("/"){ render :erb, "rails way layout" } + end + + get "/" + assert_equal "this is a rails way layout", body + end + end + + should 'use rails way for a custom layout' do + with_layout "layouts/custom", "this is a <%= yield %>" do + mock_app do + layout :custom + get("/"){ render :erb, "rails way custom layout" } + end + + get "/" + assert_equal "this is a rails way custom layout", body + end + end + + should 'not use layout' do + with_layout :application, "this is an <%= yield %>" do + with_view :index, "index" do + mock_app do + get("/with/layout"){ render :index } + get("/without/layout"){ render :index, :layout => false } + end + get "/with/layout" + assert_equal "this is an index", body + get "/without/layout" + assert_equal "index", body + end + end + end + + should 'not use layout with js format' do + create_layout :application, "this is an <%= yield %>" + create_view :foo, "erb file" + create_view :foo, "js file", :format => :js + mock_app do + get('/layout_test', :provides => [:html, :js]){ render :foo } + end + get "/layout_test" + assert_equal "this is an erb file", body + get "/layout_test.js" + assert_equal "js file", body + end + + should 'use correct layout for each format' do + create_layout :application, "this is an <%= yield %>" + create_layout :application, "document start <%= yield %> end", :format => :xml + create_view :foo, "erb file" + create_view :foo, "xml file", :format => :xml + mock_app do + get('/layout_test', :provides => [:html, :xml]){ render :foo } + end + get "/layout_test" + assert_equal "this is an erb file", body + get "/layout_test.xml" + assert_equal "document start xml file end", body + end + + should 'by default use html file when no other is given' do + create_layout :baz, "html file", :format => :html + + mock_app do + get('/content_type_test', :provides => [:html, :xml]) { render :baz } + end + + get "/content_type_test" + assert_equal "html file", body + get "/content_type_test.html" + assert_equal "html file", body + get "/content_type_test.xml" + assert_equal "html file", body + end + + should 'not use html file when DEFAULT_RENDERING_OPTIONS[:strict_format] == true' do + create_layout :foo, "html file", :format => :html + + mock_app do + get('/default_rendering_test', :provides => [:html, :xml]) { render :foo } + end + + @save = Padrino::Rendering::DEFAULT_RENDERING_OPTIONS + Padrino::Rendering::DEFAULT_RENDERING_OPTIONS[:strict_format] = true + + get "/default_rendering_test" + assert_equal "html file", body + assert_raises Padrino::Rendering::TemplateNotFound do + get "/default_rendering_test.xml" + end + + Padrino::Rendering::DEFAULT_RENDERING_OPTIONS.merge!(@save) + end + + should 'use correct layout with each controller' do + create_layout :foo, "foo layout at <%= yield %>" + create_layout :bar, "bar layout at <%= yield %>" + create_layout :baz, "baz layout at <%= yield %>" + create_layout :application, "default layout at <%= yield %>" + mock_app do + get("/"){ render :erb, "application" } + controller :foo do + layout :foo + get("/"){ render :erb, "foo" } + end + controller :bar do + layout :bar + get("/"){ render :erb, "bar" } + end + controller :baz do + layout :baz + get("/"){ render :erb, "baz", :layout => true } + end + controller :none do + get("/") { render :erb, "none" } + get("/with_foo_layout") { render :erb, "none with layout", :layout => :foo } + end + end + get "/foo" + assert_equal "foo layout at foo", body + get "/bar" + assert_equal "bar layout at bar", body + get "/baz" + assert_equal "baz layout at baz", body + get "/none" + assert_equal "default layout at none", body + get "/none/with_foo_layout" + assert_equal "foo layout at none with layout", body + get "/" + assert_equal "default layout at application", body + end + end + + should 'solve layout in layouts paths' do + create_layout :foo, "foo layout <%= yield %>" + create_layout :"layouts/bar", "bar layout <%= yield %>" + mock_app do + get("/") { render :erb, "none" } + get("/foo") { render :erb, "foo", :layout => :foo } + get("/bar") { render :erb, "bar", :layout => :bar } + end + get "/" + assert_equal "none", body + get "/foo" + assert_equal "foo layout foo", body + get "/bar" + assert_equal "bar layout bar", body + end + + should 'render correctly if layout was not found or not exist' do + create_layout :application, "application layout for <%= yield %>" + create_view :foo, "index", :format => :html + create_view :foo, "xml.rss", :format => :rss + mock_app do + get("/foo", :provides => [:html, :rss]) { render('foo') } + get("/baz", :provides => :js) { render(:erb, 'baz') } + get("/bar") { render :haml, "haml" } + end + get "/foo" + assert_equal "application layout for index", body + get "/foo.rss" + assert_equal "", body.chomp + get "/baz.js" + assert_equal "baz", body + get "/bar" + assert_equal "haml", body.chomp + end + + context 'for application render functionality' do + + should "work properly with logging and missing layout" do + create_view :index, "<%= foo %>" + mock_app do + enable :logging + get("/") { render "index", { :layout => nil }, { :foo => "bar" } } + end + get "/" + assert_equal "bar", body + end + + should "work properly with logging and layout" do + create_layout :application, "layout <%= yield %>" + create_view :index, "<%= foo %>" + mock_app do + enable :logging + get("/") { render "index", { :layout => true }, { :foo => "bar" } } + end + get "/" + assert_equal "layout bar", body + end + + should 'be compatible with sinatra render' do + mock_app do + get("/"){ render :erb, "<%= 1+2 %>" } + end + get "/" + assert_equal "3", body + end + + should "support passing locals into render" do + create_layout :application, "layout <%= yield %>" + create_view :index, "<%= foo %>" + mock_app do + get("/") { render "index", { :layout => true }, { :foo => "bar" } } + end + get "/" + assert_equal "layout bar", body + end + + should "support passing locals into sinatra render" do + create_layout :application, "layout <%= yield %>" + create_view :index, "<%= foo %>" + mock_app do + get("/") { render :erb, :index, { :layout => true }, { :foo => "bar" } } + end + get "/" + assert_equal "layout bar", body + end + + should "support passing locals into special nil engine render" do + create_layout :application, "layout <%= yield %>" + create_view :index, "<%= foo %>" + mock_app do + get("/") { render nil, :index, { :layout => true }, { :foo => "bar" } } + end + get "/" + assert_equal "layout bar", body + end + + should 'be compatible with sinatra views' do + with_view :index, "<%= 1+2 %>" do + mock_app do + get("/foo") { render :erb, :index } + get("/bar") { erb :index } + get("/dir") { "3" } + get("/inj") { erb "<%= 2+1 %>" } + get("/rnj") { render :erb, "<%= 2+1 %>" } + end + get "/foo" + assert_equal "3", body + get "/bar" + assert_equal "3", body + get "/dir" + assert_equal "3", body + get "/inj" + assert_equal "3", body + get "/rnj" + assert_equal "3", body + end + end + + should 'resolve template engine' do + with_view :index, "<%= 1+2 %>" do + mock_app do + get("/foo") { render :index } + get("/bar") { render "/index" } + end + get "/foo" + assert_equal "3", body + get "/bar" + assert_equal "3", body + end + end + + should 'resolve template content type' do + create_view :foo, "Im Js", :format => :js + create_view :foo, "Im Erb" + mock_app do + get("/foo", :provides => :js) { render :foo } + get("/bar.js") { render :foo } + end + get "/foo.js" + assert_equal "Im Js", body + # TODO: implement this! + # get "/bar.js" + # assert_equal "Im Js", body + end + + should 'resolve with explicit template format' do + create_view :foo, "Im Js", :format => :js + create_view :foo, "Im Haml", :format => :haml + create_view :foo, "Im Xml", :format => :xml + mock_app do + get("/foo_normal", :provides => :js) { render 'foo' } + get("/foo_haml", :provides => :js) { render 'foo.haml' } + get("/foo_xml", :provides => :js) { render 'foo.xml' } + end + get "/foo_normal.js" + assert_equal "Im Js", body + get "/foo_haml.js" + assert_equal "Im Haml\n", body + get "/foo_xml.js" + assert_equal "Im Xml", body + end + + should 'resolve without explict template format' do + create_view :foo, "Im Html" + create_view :foo, "xml.rss", :format => :rss + mock_app do + get(:index, :map => "/", :provides => [:html, :rss]){ render 'foo' } + end + get "/", {}, { 'HTTP_ACCEPT' => 'text/html;q=0.9' } + assert_equal "Im Html", body + get ".rss" + assert_equal "\n", body + end + + should "ignore files ending in tilde and not render them" do + create_view :foo, "Im Wrong", :format => 'haml~' + create_view :foo, "Im Haml", :format => :haml + create_view :bar, "Im Haml backup", :format => 'haml~' + mock_app do + get('/foo') { render 'foo' } + get('/bar') { render 'bar' } + end + get '/foo' + assert_equal "Im Haml\n", body + assert_raises(Padrino::Rendering::TemplateNotFound) { get '/bar' } + end + + should 'resolve template locale' do + create_view :foo, "Im English", :locale => :en + create_view :foo, "Im Italian", :locale => :it + mock_app do + get("/foo") { render :foo } + end + I18n.locale = :en + get "/foo" + assert_equal "Im English", body + I18n.locale = :it + get "/foo" + assert_equal "Im Italian", body + end + + should 'resolve template content_type and locale' do + create_view :foo, "Im Js", :format => :js + create_view :foo, "Im Erb" + create_view :foo, "Im English Erb", :locale => :en + create_view :foo, "Im Italian Erb", :locale => :it + create_view :foo, "Im English Js", :format => :js, :locale => :en + create_view :foo, "Im Italian Js", :format => :js, :locale => :it + mock_app do + get("/foo", :provides => [:html, :js]) { render :foo } + end + I18n.locale = :none + get "/foo.js" + assert_equal "Im Js", body + get "/foo" + assert_equal "Im Erb", body + I18n.locale = :en + get "/foo" + assert_equal "Im English Erb", body + I18n.locale = :it + get "/foo" + assert_equal "Im Italian Erb", body + I18n.locale = :en + get "/foo.js" + assert_equal "Im English Js", body + I18n.locale = :it + get "/foo.js" + assert_equal "Im Italian Js", body + I18n.locale = :en + get "/foo.pk" + assert_equal 404, status + end + + should 'resolve template content_type and locale with layout' do + create_layout :foo, "Hello <%= yield %> in a Js layout", :format => :js + create_layout :foo, "Hello <%= yield %> in a Js-En layout", :format => :js, :locale => :en + create_layout :foo, "Hello <%= yield %> in a Js-It layout", :format => :js, :locale => :it + create_layout :foo, "Hello <%= yield %> in a Erb-En layout", :locale => :en + create_layout :foo, "Hello <%= yield %> in a Erb-It layout", :locale => :it + create_layout :foo, "Hello <%= yield %> in a Erb layout" + create_view :bar, "Im Js", :format => :js + create_view :bar, "Im Erb" + create_view :bar, "Im English Erb", :locale => :en + create_view :bar, "Im Italian Erb", :locale => :it + create_view :bar, "Im English Js", :format => :js, :locale => :en + create_view :bar, "Im Italian Js", :format => :js, :locale => :it + create_view :bar, "Im a json", :format => :json + mock_app do + layout :foo + get("/bar", :provides => [:html, :js, :json]) { render :bar } + end + I18n.locale = :none + get "/bar.js" + assert_equal "Hello Im Js in a Js layout", body + get "/bar" + assert_equal "Hello Im Erb in a Erb layout", body + I18n.locale = :en + get "/bar" + assert_equal "Hello Im English Erb in a Erb-En layout", body + I18n.locale = :it + get "/bar" + assert_equal "Hello Im Italian Erb in a Erb-It layout", body + I18n.locale = :en + get "/bar.js" + assert_equal "Hello Im English Js in a Js-En layout", body + I18n.locale = :it + get "/bar.js" + assert_equal "Hello Im Italian Js in a Js-It layout", body + I18n.locale = :en + get "/bar.json" + assert_equal "Im a json", body + get "/bar.pk" + assert_equal 404, status + end + + should 'renders erb with blocks' do + mock_app do + def container + @_out_buf << "THIS." + yield + @_out_buf << "SPARTA!" + end + def is; "IS."; end + get '/' do + render :erb, '<% container do %> <%= is %> <% end %>' + end + end + get '/' + assert ok? + assert_equal 'THIS. IS. SPARTA!', body + end + + should 'render erb to a SafeBuffer' do + mock_app do + layout do + "this is a <%= yield %>" + end + get '/' do + render :erb, '

<%= %q{} %>

', :layout => false + end + get '/with_layout' do + render :erb, 'span', :layout => true + end + end + get '/' + assert ok? + assert_equal '

<script lang="ronin">alert("https://github.com/ronin-ruby/ronin")</script>

', body + + get '/with_layout' + assert ok? + assert_equal 'this is a span', body + end + + should 'render haml to a SafeBuffer' do + mock_app do + layout do + "%p= yield" + end + get '/' do + render :haml, '%p= %s{}', :layout => false + end + get '/with_layout' do + render :haml, "%div\n foo", :layout => true + end + end + get '/' + assert ok? + assert_equal '

<script lang="ronin">alert("https://github.com/ronin-ruby/ronin")</script>

', body.strip + + get 'with_layout' + assert ok? + assert_equal '

foo

', body.gsub(/\s+/, "") + end + + should 'render slim to a SafeBuffer' do + mock_app do + layout do + "p= yield" + end + get '/' do + render :slim, 'p = %q{}', :layout => false + end + get "/with_layout" do + render :slim, 'div foo', :layout => true + end + end + get '/' + assert ok? + assert_equal '

<script lang="ronin">alert("https://github.com/ronin-ruby/ronin")</script>

', body.strip + + get '/with_layout' + assert ok? + assert_equal '

foo

', body.strip + end + + should "render correct erb when use sinatra as middleware" do + class Bar < Sinatra::Base + get "/" do + render :erb, "<&'>" + end + end + mock_app do + use Bar + end + get "/" + assert_equal "<&'>", body + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_rendering_extensions.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_rendering_extensions.rb new file mode 100644 index 00000000..a6819046 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_rendering_extensions.rb @@ -0,0 +1,14 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +describe "Rendering Extensions" do + context 'for haml' do + should 'render haml_tag correctly' do + mock_app do + get('/') { render :haml, '-haml_tag :div'} + end + + get '/' + assert_match '
', last_response.body + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_restful_routing.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_restful_routing.rb new file mode 100644 index 00000000..6d22634e --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_restful_routing.rb @@ -0,0 +1,33 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +describe "Routing" do + should 'perform restul routing' do + mock_app do + controller :parent => :parents do + get :index do + "#{url_for(:index, params[:parent_id])} get" + end + + put :index, :with => :asset_id do + "#{url_for(:index, params[:parent_id], :asset_id => params[:asset_id])} put" + end + + post :index, :with => :asset_id do + "#{url_for(:index, :parent_id => params[:parent_id], :asset_id => params[:asset_id])} post" + end + + delete :index, :with => :asset_id do + "#{url_for(:index, params[:parent_id], :asset_id => params[:asset_id])} delete" + end + end + end + get "/parents/1" + assert_equal "/parents/1 get", body + put "/parents/1/hi" + assert_equal "/parents/1/hi put", body + post "/parents/1/hi" + assert_equal "/parents/1/hi post", body + delete "/parents/1/hi" + assert_equal "/parents/1/hi delete", body + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_router.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_router.rb new file mode 100644 index 00000000..0bb7767d --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_router.rb @@ -0,0 +1,146 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require File.expand_path(File.dirname(__FILE__) + '/fixtures/apps/simple') + +describe "Router" do + + def setup + Padrino.clear! + end + + should "dispatch paths correctly" do + app = lambda { |env| + [200, { + 'X-ScriptName' => env['SCRIPT_NAME'], + 'X-PathInfo' => env['PATH_INFO'], + 'Content-Type' => 'text/plain' + }, [""]] + } + map = Padrino::Router.new( + { :path => '/bar', :to => app }, + { :path => '/foo', :to => app }, + { :path => '/foo/bar', :to => app } + ) + + res = Rack::MockRequest.new(map).get("/") + assert res.not_found? + + res = Rack::MockRequest.new(map).get("/qux") + assert res.not_found? + + res = Rack::MockRequest.new(map).get("/foo") + assert res.ok? + assert_equal "/foo", res["X-ScriptName"] + assert_equal "/", res["X-PathInfo"] + + res = Rack::MockRequest.new(map).get("/foo/") + assert res.ok? + assert_equal "/foo", res["X-ScriptName"] + assert_equal "/", res["X-PathInfo"] + + res = Rack::MockRequest.new(map).get("/foo/bar") + assert res.ok? + assert_equal "/foo/bar", res["X-ScriptName"] + assert_equal "/", res["X-PathInfo"] + + res = Rack::MockRequest.new(map).get("/foo/bar/") + assert res.ok? + assert_equal "/foo/bar", res["X-ScriptName"] + assert_equal "/", res["X-PathInfo"] + + res = Rack::MockRequest.new(map).get("/foo///bar//quux") + assert_equal 200, res.status + assert res.ok? + assert_equal "/foo/bar", res["X-ScriptName"] + assert_equal "//quux", res["X-PathInfo"] + + res = Rack::MockRequest.new(map).get("/foo/quux", "SCRIPT_NAME" => "/bleh") + assert res.ok? + assert_equal "/bleh/foo", res["X-ScriptName"] + assert_equal "/quux", res["X-PathInfo"] + + res = Rack::MockRequest.new(map).get("/bar", 'HTTP_HOST' => 'foo.org') + assert res.ok? + assert_equal "/bar", res["X-ScriptName"] + assert_equal "/", res["X-PathInfo"] + + res = Rack::MockRequest.new(map).get("/bar/", 'HTTP_HOST' => 'foo.org') + assert res.ok? + assert_equal "/bar", res["X-ScriptName"] + assert_equal "/", res["X-PathInfo"] + end + + should "dispatches hosts correctly" do + map = Padrino::Router.new( + { :host => "foo.org", :to => lambda { |env| + [200, + { "Content-Type" => "text/plain", + "X-Position" => "foo.org", + "X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"], + }, [""]]}}, + { :host => "subdomain.foo.org", :to => lambda { |env| + [200, + { "Content-Type" => "text/plain", + "X-Position" => "subdomain.foo.org", + "X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"], + }, [""]]}}, + { :host => /.*\.bar.org/, :to => lambda { |env| + [200, + { "Content-Type" => "text/plain", + "X-Position" => "bar.org", + "X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"], + }, [""]]}} + ) + + res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "bar.org") + assert res.not_found? + + res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "at.bar.org") + assert res.ok? + assert_equal "bar.org", res["X-Position"] + + res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "foo.org") + assert res.ok? + assert_equal "foo.org", res["X-Position"] + + res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "subdomain.foo.org", "SERVER_NAME" => "foo.org") + assert res.ok? + assert_equal "subdomain.foo.org", res["X-Position"] + end + + should "works with padrino core applications" do + Padrino.mount("simple_demo").host("padrino.org") + assert_equal ["simple_demo"], Padrino.mounted_apps.map(&:name) + assert_equal ["padrino.org"], Padrino.mounted_apps.map(&:app_host) + + res = Rack::MockRequest.new(Padrino.application).get("/") + assert res.not_found? + + res = Rack::MockRequest.new(Padrino.application).get("/", "HTTP_HOST" => "bar.org") + assert res.not_found? + + res = Rack::MockRequest.new(Padrino.application).get("/", "HTTP_HOST" => "padrino.org") + assert res.ok? + end + + should "works with padrino applications" do + Padrino.mount("simple_demo").to("/foo").host(/.*\.padrino.org/) + + res = Rack::MockRequest.new(Padrino.application).get("/") + assert res.not_found? + + res = Rack::MockRequest.new(Padrino.application).get("/", "HTTP_HOST" => "bar.org") + assert res.not_found? + + res = Rack::MockRequest.new(Padrino.application).get("/", "HTTP_HOST" => "padrino.org") + assert res.not_found? + + res = Rack::MockRequest.new(Padrino.application).get("/none", "HTTP_HOST" => "foo.padrino.org") + assert res.not_found? + + res = Rack::MockRequest.new(Padrino.application).get("/foo", "HTTP_HOST" => "bar.padrino.org") + assert res.ok? + + res = Rack::MockRequest.new(Padrino.application).get("/foo/", "HTTP_HOST" => "bar.padrino.org") + assert res.ok? + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_routing.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_routing.rb new file mode 100644 index 00000000..dfad8e48 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_routing.rb @@ -0,0 +1,1927 @@ +#encoding: utf-8 +require File.expand_path(File.dirname(__FILE__) + '/helper') + +class FooError < RuntimeError; end + + +describe "Routing" do + setup do + Padrino::Application.send(:register, Padrino::Rendering) + Padrino::Rendering::DEFAULT_RENDERING_OPTIONS[:strict_format] = false + end + + should "serve static files with simple cache control" do + mock_app do + set :static_cache_control, :public + set :public_folder, File.dirname(__FILE__) + end + get "/#{File.basename(__FILE__)}" + assert headers.has_key?('Cache-Control') + assert_equal headers['Cache-Control'], 'public' + end # static simple + + should "serve static files with cache control and max_age" do + mock_app do + set :static_cache_control, [:public, :must_revalidate, {:max_age => 300}] + set :public_folder, File.dirname(__FILE__) + end + get "/#{File.basename(__FILE__)}" + assert headers.has_key?('Cache-Control') + assert_equal headers['Cache-Control'], 'public, must-revalidate, max-age=300' + end # static max_age + + should 'ignore trailing delimiters for basic route' do + mock_app do + get("/foo"){ "okey" } + get(:test) { "tester" } + end + get "/foo" + assert_equal "okey", body + get "/foo/" + assert_equal "okey", body + get "/test" + assert_equal "tester", body + get "/test/" + assert_equal "tester", body + end + + should 'fail with unrecognized route exception when not found' do + mock_app do + get(:index){ "okey" } + end + get @app.url_for(:index) + assert_equal "okey", body + assert_raises(Padrino::Routing::UnrecognizedException) { + get @app.url_for(:fake) + } + end + + should 'accept regexp routes' do + mock_app do + get(%r./fob|/baz.) { "regexp" } + get("/foo") { "str" } + get %r./([0-9]+)/. do |num| + "Your lucky number: #{num} #{params[:captures].first}" + end + get %r./page/([0-9]+)|/. do |num| + "My lucky number: #{num} #{params[:captures].first}" + end + end + get "/foo" + assert_equal "str", body + get "/fob" + assert_equal "regexp", body + get "/baz" + assert_equal "regexp", body + get "/321/" + assert_equal "Your lucky number: 321 321", body + get "/page/99" + assert_equal "My lucky number: 99 99", body + end + + should 'accept regexp routes with generate with :generate_with' do + mock_app do + get(%r{/fob|/baz}, :name => :foo, :generate_with => '/fob') { "regexp" } + end + assert_equal "/fob", @app.url(:foo) + end + + should "parse routes with question marks" do + mock_app do + get("/foo/?"){ "okey" } + post('/unauthenticated/?') { "no access" } + end + get "/foo" + assert_equal "okey", body + get "/foo/" + assert_equal "okey", body + post "/unauthenticated" + assert_equal "no access", body + post "/unauthenticated/" + assert_equal "no access", body + end + + should 'parse routes that are encoded' do + mock_app do + get('/щч') { 'success!' } + end + get(URI.escape('/щч')) + assert_equal 'success!', body + end + + should 'parse routes that include encoded slash' do + mock_app do + get('/:drive_alias/:path', :path => /.*/){ + "Show #{params[:drive_alias]} and #{params[:path]}" + } + end + get("/drive%2Ffoo/some/path") + assert_equal "Show drive/foo and some/path", body + end + + should 'encode params using UTF-8' do + skip unless ''.respond_to?(:encoding) # for 1.8.7 + + mock_app do + get('/:foo') { params[:foo].encoding.name } + end + get '/bar' + assert_equal 'UTF-8', body + end + + should 'match correctly similar paths' do + mock_app do + get("/my/:foo_id"){ params[:foo_id] } + get("/my/:bar_id/bar"){ params[:bar_id] } + end + get "/my/1" + assert_equal "1", body + get "/my/2/bar" + assert_equal "2", body + end + + should "match user agents" do + app = mock_app do + get("/main", :agent => /IE/){ "hello IE" } + get("/main"){ "hello" } + end + get "/main" + assert_equal "hello", body + get "/main", {}, {'HTTP_USER_AGENT' => 'This is IE'} + assert_equal "hello IE", body + end + + should "use regex for parts of a route" do + app = mock_app do + get("/main/:id", :id => /\d+/){ "hello #{params[:id]}" } + end + get "/main/123" + assert_equal "hello 123", body + get "/main/asd" + assert_equal 404, status + end + + should "parse params when use regex for parts of a route" do + mock_app do + post :index, :with => [:foo, :bar], :bar => /.+/ do + "show #{params[:foo]}" + end + + get :index, :map => '/mystuff/:a_id/boing/:boing_id' do + "show #{params[:a_id]} and #{params[:boing_id]}" + end + end + get "/mystuff/5/boing/2" + assert_equal "show 5 and 2", body + end + + should "not generate overlapping head urls" do + app = mock_app do + get("/main"){ "hello" } + post("/main"){ "hello" } + end + assert_equal 3, app.routes.size, "should generate GET, HEAD and PUT" + assert_equal "GET", app.routes[0].request_methods.first + assert_equal "HEAD", app.routes[1].request_methods.first + assert_equal "POST", app.routes[2].request_methods.first + end + + should 'generate basic urls' do + mock_app do + get(:foo){ "/foo" } + get(:foo, :with => :id){ |id| "/foo/#{id}" } + get([:foo, :id]){ |id| "/foo/#{id}" } + get(:hash, :with => :id){ url(:hash, :id => 1) } + get([:hash, :id]){ url(:hash, :id => 1) } + get(:array, :with => :id){ url(:array, 23) } + get([:array, :id]){ url(:array, 23) } + get(:hash_with_extra, :with => :id){ url(:hash_with_extra, :id => 1, :query => 'string') } + get([:hash_with_extra, :id]){ url(:hash_with_extra, :id => 1, :query => 'string') } + get(:array_with_extra, :with => :id){ url(:array_with_extra, 23, :query => 'string') } + get([:array_with_extra, :id]){ url(:array_with_extra, 23, :query => 'string') } + get("/old-bar/:id"){ params[:id] } + post(:mix, :map => "/mix-bar/:id"){ params[:id] } + get(:mix, :map => "/mix-bar/:id"){ params[:id] } + end + get "/foo" + assert_equal "/foo", body + get "/foo/123" + assert_equal "/foo/123", body + get "/hash/2" + assert_equal "/hash/1", body + get "/array/23" + assert_equal "/array/23", body + get "/hash_with_extra/1" + assert_equal "/hash_with_extra/1?query=string", body + get "/array_with_extra/23" + assert_equal "/array_with_extra/23?query=string", body + get "/old-bar/3" + assert_equal "3", body + post "/mix-bar/4" + assert_equal "4", body + get "/mix-bar/4" + assert_equal "4", body + end + + should 'generate url with format' do + mock_app do + get(:a, :provides => :any){ url(:a, :format => :json) } + get(:b, :provides => :js){ url(:b, :format => :js) } + get(:c, :provides => [:js, :json]){ url(:c, :format => :json) } + get(:d, :provides => [:html, :js]){ url(:d, :format => :js, :foo => :bar) } + end + get "/a.js" + assert_equal "/a.json", body + get "/b.js" + assert_equal "/b.js", body + get "/b.ru" + assert_equal 404, status + get "/c.js" + assert_equal "/c.json", body + get "/c.json" + assert_equal "/c.json", body + get "/c.ru" + assert_equal 404, status + get "/d" + assert_equal "/d.js?foo=bar", body + get "/d.js" + assert_equal "/d.js?foo=bar", body + get "/e.xml" + assert_equal 404, status + end + + should 'generate absolute urls' do + mock_app do + get(:hash, :with => :id){ absolute_url(:hash, :id => 1) } + end + get "/hash/2" + assert_equal "http://example.org/hash/1", body + get "https://example.org/hash/2" + assert_equal "https://example.org/hash/1", body + end + + should 'generate proper absolute urls for mounted apps' do + class Test < Padrino::Application + get :foo do + absolute_url(:foo, :id => 1) + end + end + Padrino.mount("Test").to("/test") + @app = Padrino.application + get('/test/foo') + assert_equal 'http://example.org/test/foo?id=1', body + end + + should 'allow regex url with format' do + mock_app do + get(/.*/, :provides => :any) { "regexp" } + end + get "/anything" + assert_equal "regexp", body + end + + should 'use padrino url method' do + mock_app do + end + + assert_equal @app.method(:url).owner, Padrino::Routing::ClassMethods + end + + should 'work correctly with sinatra redirects' do + mock_app do + get(:index) { redirect url(:index) } + get(:google) { redirect "http://google.com" } + get("/foo") { redirect "/bar" } + get("/bar") { "Bar" } + end + + get "/" + assert_equal "http://example.org/", headers['Location'] + get "/google" + assert_equal "http://google.com", headers['Location'] + get "/foo" + assert_equal "http://example.org/bar", headers['Location'] + end + + should "return 406 on Accept-Headers it does not provide" do + mock_app do + get(:a, :provides => [:html, :js]){ content_type } + end + + get "/a", {}, {"HTTP_ACCEPT" => "application/yaml"} + assert_equal 406, status + end + + should "return 406 on file extensions it does not provide and flag is set" do + mock_app do + enable :treat_format_as_accept + get(:a, :provides => [:html, :js]){ content_type } + end + + get "/a.xml", {}, {} + assert_equal 406, status + end + + should "return 404 on file extensions it does not provide and flag is not set" do + mock_app do + get(:a, :provides => [:html, :js]){ content_type } + end + + get "/a.xml", {}, {} + assert_equal 404, status + end + + should "not set content_type to :html if Accept */* and html not in provides" do + mock_app do + get("/foo", :provides => [:json, :xml]) { content_type.to_s } + end + + get '/foo', {}, { 'HTTP_ACCEPT' => '*/*;q=0.5' } + assert_equal 'json', body + end + + should "set content_type to :json if Accept contains */*" do + mock_app do + get("/foo", :provides => [:json]) { content_type.to_s } + end + + get '/foo', {}, { 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' } + assert_equal 'json', body + end + + should 'set and get content_type' do + mock_app do + get("/foo"){ content_type(:json); content_type.to_s } + end + get "/foo" + assert_equal 'application/json;charset=utf-8', content_type + assert_equal 'json', body + end + + should "send the appropriate number of params" do + mock_app do + get('/id/:user_id', :provides => [:json]) { |user_id, format| user_id} + end + get '/id/5.json' + assert_equal '5', body + end + + should "allow .'s in param values" do + skip + mock_app do + get('/id/:email', :provides => [:json]) { |email, format| [email, format] * '/' } + end + get '/id/foo@bar.com.json' + assert_equal 'foo@bar.com/json', body + end + + should "set correct content_type for Accept not equal to */* even if */* also provided" do + mock_app do + get("/foo", :provides => [:html, :js, :xml]) { content_type.to_s } + end + + get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript, */*;q=0.5' } + assert_equal 'js', body + end + + should "return the first content type in provides if accept header is empty" do + mock_app do + get(:a, :provides => [:js]){ content_type.to_s } + end + + get "/a", {}, {} + assert_equal "js", body + end + + should "not default to HTML if HTML is not provided and no type is given" do + mock_app do + get(:a, :provides => [:js]){ content_type } + end + + get "/a", {}, {} + assert_equal "application/javascript;charset=utf-8", content_type + end + + should "not match routes if url_format and http_accept is provided but not included" do + mock_app do + get(:a, :provides => [:js, :html]){ content_type } + end + + get "/a.xml", {}, {"HTTP_ACCEPT" => "text/html"} + assert_equal 404, status + end + + should "generate routes for format simple" do + mock_app do + get(:foo, :provides => [:html, :rss]) { render :haml, "Test" } + end + get "/foo" + assert_equal "Test\n", body + get "/foo.rss" + assert_equal "Test\n", body + end + + should "should inject the controller name into the request" do + mock_app do + controller :posts do + get(:index) { request.controller } + controller :mini do + get(:index) { request.controller } + end + end + end + get "/posts" + assert_equal "posts", body + get "/mini" + assert_equal "mini", body + end + + should "should inject the action name into the request" do + mock_app do + controller :posts do + get('/omnomnom(/:id)') { request.action.inspect } + controller :mini do + get([:a, :b, :c]) { request.action.inspect } + end + end + end + get "/posts/omnomnom" + assert_equal "\"/omnomnom(/:id)\"", body + get "/mini/a/b/c" + assert_equal ":a", body + end + + should "support not_found" do + mock_app do + not_found { 'whatever' } + + get :index, :map => "/" do + 'index' + end + end + get '/wrong' + assert_equal 404, status + assert_equal 'whatever', body + get '/' + assert_equal 'index', body + assert_equal 200, status + end + + should "should inject the route into the request" do + mock_app do + controller :posts do + get(:index) { request.route_obj.name.to_s } + end + end + get "/posts" + assert_equal "posts_index", body + end + + should "preserve the format if you set it manually" do + mock_app do + before do + params[:format] = "json" + end + + get "test", :provides => [:html, :json] do + content_type.inspect + end + end + get "/test" + assert_equal ":json", body + get "/test.html" + assert_equal ":json", body + get "/test.php" + assert_equal ":json", body + end + + should "correctly accept '.' in the route" do + mock_app do + get "test.php", :provides => [:html, :json] do + content_type.inspect + end + end + get "/test.php" + assert_equal ":html", body + get "/test.php.json" + assert_equal ":json", body + end + + should "correctly accept priority of format" do + mock_app do + get "test.php", :provides => [:html, :json, :xml] do + content_type.inspect + end + end + + get "/test.php" + assert_equal ":html", body + get "/test.php", {}, { 'HTTP_ACCEPT' => 'application/xml' } + assert_equal ":xml", body + get "/test.php?format=json", { 'HTTP_ACCEPT' => 'application/xml' } + assert_equal ":json", body + get "/test.php.json?format=html", { 'HTTP_ACCEPT' => 'application/xml' } + assert_equal ":json", body + end + + should "generate routes for format with controller" do + mock_app do + controller :posts do + get(:index, :provides => [:html, :rss, :atom, :js]) { render :haml, "Index.#{content_type}" } + get(:show, :with => :id, :provides => [:html, :rss, :atom]) { render :haml, "Show.#{content_type}" } + end + end + get "/posts" + assert_equal "Index.html\n", body + get "/posts.rss" + assert_equal "Index.rss\n", body + get "/posts.atom" + assert_equal "Index.atom\n", body + get "/posts.js" + assert_equal "Index.js\n", body + get "/posts/show/5" + assert_equal "Show.html\n", body + get "/posts/show/5.rss" + assert_equal "Show.rss\n", body + get "/posts/show/10.atom" + assert_equal "Show.atom\n", body + end + + should 'map routes' do + mock_app do + get(:bar){ "bar" } + end + get "/bar" + assert_equal "bar", body + assert_equal "/bar", @app.url(:bar) + end + + should 'remove index from path' do + mock_app do + get(:index){ "index" } + get("/accounts/index"){ "accounts" } + end + get "/" + assert_equal "index", body + assert_equal "/", @app.url(:index) + get "/accounts/index" + assert_equal "accounts", body + end + + should 'remove index from path with params' do + mock_app do + get(:index, :with => :name){ "index with #{params[:name]}" } + end + get "/bobby" + assert_equal "index with bobby", body + assert_equal "/john", @app.url(:index, :name => "john") + end + + should 'parse named params' do + mock_app do + get(:print, :with => :id){ "Im #{params[:id]}" } + end + get "/print/9" + assert_equal "Im 9", body + assert_equal "/print/9", @app.url(:print, :id => 9) + end + + should '405 on wrong request_method' do + mock_app do + post('/bar'){ "bar" } + end + get "/bar" + assert_equal 405, status + end + + should 'respond to' do + mock_app do + get(:a, :provides => :js){ "js" } + get(:b, :provides => :any){ "any" } + get(:c, :provides => [:js, :json]){ "js,json" } + get(:d, :provides => [:html, :js]){ "html,js"} + end + get "/a" + assert_equal 200, status + assert_equal "js", body + get "/a.js" + assert_equal "js", body + get "/b" + assert_equal "any", body + # TODO randomly fails in minitest :( + # assert_raises(RuntimeError) { get "/b.foo" } + get "/c" + assert_equal 200, status + assert_equal "js,json", body + get "/c.js" + assert_equal "js,json", body + get "/c.json" + assert_equal "js,json", body + get "/d" + assert_equal "html,js", body + get "/d.js" + assert_equal "html,js", body + end + + should 'respond_to and set content_type' do + Rack::Mime::MIME_TYPES['.foo'] = 'application/foo' + mock_app do + get :a, :provides => :any do + case content_type + when :js then "js" + when :json then "json" + when :foo then "foo" + when :html then "html" + end + end + end + get "/a.js" + assert_equal "js", body + assert_equal 'application/javascript;charset=utf-8', response["Content-Type"] + get "/a.json" + assert_equal "json", body + assert_equal 'application/json;charset=utf-8', response["Content-Type"] + get "/a.foo" + assert_equal "foo", body + assert_equal 'application/foo;charset=utf-8', response["Content-Type"] + get "/a" + assert_equal "html", body + assert_equal 'text/html;charset=utf-8', response["Content-Type"] + end + + should 'use controllers' do + mock_app do + controller "/admin" do + get("/"){ "index" } + get("/show/:id"){ "show #{params[:id]}" } + end + end + get "/admin" + assert_equal "index", body + get "/admin/show/1" + assert_equal "show 1", body + end + + should 'use named controllers' do + mock_app do + controller :admin do + get(:index, :with => :id){ params[:id] } + get(:show, :with => :id){ "show #{params[:id]}" } + end + controllers :foo, :bar do + get(:index){ "foo_bar_index" } + end + end + get "/admin/1" + assert_equal "1", body + get "/admin/show/1" + assert_equal "show 1", body + assert_equal "/admin/1", @app.url(:admin_index, :id => 1) + assert_equal "/admin/show/1", @app.url(:admin_show, :id => 1) + get "/foo/bar" + assert_equal "foo_bar_index", body + end + + should 'use map and with' do + mock_app do + get :index, :map => '/bugs', :with => :id do + params[:id] + end + end + get '/bugs/4' + assert_equal '4', body + assert_equal "/bugs/4", @app.url(:index, :id => 4) + end + + should "ignore trailing delimiters within a named controller" do + mock_app do + controller :posts do + get(:index, :provides => [:html, :js]){ "index" } + get(:new) { "new" } + get(:show, :with => :id){ "show #{params[:id]}" } + end + end + get "/posts" + assert_equal "index", body + get "/posts/" + assert_equal "index", body + get "/posts.js" + assert_equal "index", body + get "/posts.js/" + assert_equal "index", body + get "/posts/new" + assert_equal "new", body + get "/posts/new/" + assert_equal "new", body + end + + should "ignore trailing delimiters within a named controller for unnamed actions" do + mock_app do + controller :accounts do + get("/") { "account_index" } + get("/new") { "new" } + end + controller :votes do + get("/") { "vote_index" } + end + end + get "/accounts" + assert_equal "account_index", body + get "/accounts/" + assert_equal "account_index", body + get "/accounts/new" + assert_equal "new", body + get "/accounts/new/" + assert_equal "new", body + get "/votes" + assert_equal "vote_index", body + get "/votes/" + assert_equal "vote_index", body + end + + should 'use named controllers with array routes' do + mock_app do + controller :admin do + get(:index){ "index" } + get(:show, :with => :id){ "show #{params[:id]}" } + end + controllers :foo, :bar do + get(:index){ "foo_bar_index" } + end + end + get "/admin" + assert_equal "index", body + get "/admin/show/1" + assert_equal "show 1", body + assert_equal "/admin", @app.url(:admin, :index) + assert_equal "/admin/show/1", @app.url(:admin, :show, :id => 1) + get "/foo/bar" + assert_equal "foo_bar_index", body + end + + should "support a reindex action and remove index inside controller" do + mock_app do + controller :posts do + get(:index){ "index" } + get(:reindex){ "reindex" } + end + end + get "/posts" + assert_equal "index", body + get "/posts/reindex" + assert_equal "/posts/reindex", @app.url(:posts, :reindex) + assert_equal "reindex", body + end + + should 'use uri_root' do + mock_app do + get(:foo){ "foo" } + end + @app.uri_root = '/' + assert_equal "/foo", @app.url(:foo) + @app.uri_root = '/testing' + assert_equal "/testing/foo", @app.url(:foo) + @app.uri_root = '/testing/' + assert_equal "/testing/foo", @app.url(:foo) + @app.uri_root = 'testing/bar///' + assert_equal "/testing/bar/foo", @app.url(:foo) + end + + should 'use uri_root with controllers' do + mock_app do + controller :foo do + get(:bar){ "bar" } + end + end + @app.uri_root = '/testing' + assert_equal "/testing/foo/bar", @app.url(:foo, :bar) + end + + should 'use RACK_BASE_URI' do + mock_app do + get(:foo){ "foo" } + end + # Wish there was a side-effect free way to test this... + ENV['RACK_BASE_URI'] = '/' + assert_equal "/foo", @app.url(:foo) + ENV['RACK_BASE_URI'] = '/testing' + assert_equal "/testing/foo", @app.url(:foo) + ENV['RACK_BASE_URI'] = nil + end + + should 'reset routes' do + mock_app do + get("/"){ "foo" } + reset_router! + end + get "/" + assert_equal 404, status + end + + should "match params and format" do + app = mock_app do + get '/:id', :provides => [:json, :html] do |id, _| + id + end + + get 'format/:id', :provides => [:json, :html] do |id, format| + format + end + end + + get '/123.html' + assert_equal '123', body + + get 'format/123.html' + assert_equal 'html', body + end + + + should 'respect priorities' do + route_order = [] + mock_app do + get(:index, :priority => :normal) { route_order << :normal; pass } + get(:index, :priority => :low) { route_order << :low; "hello" } + get(:index, :priority => :high) { route_order << :high; pass } + end + get '/' + assert_equal [:high, :normal, :low], route_order + assert_equal "hello", body + end + + should 'catch all after controllers' do + mock_app do + get(:index, :with => :slug, :priority => :low) { "catch all" } + controllers :contact do + get(:index) { "contact"} + end + end + get "/contact" + assert_equal "contact", body + get "/foo" + assert_equal "catch all", body + end + + should 'allow optionals' do + mock_app do + get(:show, :map => "/stories/:type(/:category)") do + "#{params[:type]}/#{params[:category]}" + end + end + get "/stories/foo" + assert_equal "foo/", body + get "/stories/foo/bar" + assert_equal "foo/bar", body + end + + should 'apply maps' do + mock_app do + controllers :admin do + get(:index, :map => "/"){ "index" } + get(:show, :with => :id, :map => "/show"){ "show #{params[:id]}" } + get(:edit, :map => "/edit/:id/product"){ "edit #{params[:id]}" } + get(:wacky, :map => "/wacky-:id-:product_id"){ "wacky #{params[:id]}-#{params[:product_id]}" } + end + end + get "/" + assert_equal "index", body + get @app.url(:admin, :index) + assert_equal "index", body + get "/show/1" + assert_equal "show 1", body + get "/edit/1/product" + assert_equal "edit 1", body + get "/wacky-1-2" + assert_equal "wacky 1-2", body + end + + should 'apply maps when given path is kind of hash' do + mock_app do + controllers :admin do + get(:foobar, "/foo/bar"){ "foobar" } + end + end + get "/foo/bar" + assert_equal "foobar", body + end + + should "apply parent to route" do + mock_app do + controllers :project do + get(:index, :parent => :user) { "index #{params[:user_id]}" } + get(:index, :parent => [:user, :section]) { "index #{params[:user_id]} #{params[:section_id]}" } + get(:edit, :with => :id, :parent => :user) { "edit #{params[:id]} #{params[:user_id]}"} + get(:show, :with => :id, :parent => [:user, :product]) { "show #{params[:id]} #{params[:user_id]} #{params[:product_id]}"} + end + end + get "/user/1/project" + assert_equal "index 1", body + get "/user/1/section/3/project" + assert_equal "index 1 3", body + get "/user/1/project/edit/2" + assert_equal "edit 2 1", body + get "/user/1/product/2/project/show/3" + assert_equal "show 3 1 2", body + end + + should "respect parent precedence: controllers parents go before route parents" do + mock_app do + controllers :project do + get(:index, :parent => :user) { "index #{params[:user_id]}" } + end + + controllers :bar, :parent => :foo do + get(:index) { "index on foo #{params[:foo_id]} @ bar" } + get(:index, :parent => :baz) { "index on foo #{params[:foo_id]} @ baz #{params[:baz_id]} @ bar" } + end + end + + get "/user/1/project" + assert_equal "index 1", body + get "/foo/1/bar" + assert_equal "index on foo 1 @ bar", body + get "/foo/1/baz/2/bar" + assert_equal "index on foo 1 @ baz 2 @ bar", body + end + + should "keep a reference to the parent on the route" do + mock_app do + controllers :project do + get(:index, :parent => :user) { "index #{params[:user_id]}" } + get(:index, :parent => [:user, :section]) { "index #{params[:user_id]} #{params[:section_id]}" } + get(:edit, :with => :id, :parent => :user) { "edit #{params[:id]} #{params[:user_id]}"} + get(:show, :with => :id, :parent => [:user, :product]) { "show #{params[:id]} #{params[:user_id]} #{params[:product_id]}"} + end + + controllers :bar, :parent => :foo do + get(:index) { "index on foo/bar" } + get(:index, :parent => :baz) { "index on foo/baz/bar" } + end + end + + # get "/user/1/project" + assert_equal :user, @app.routes[0].parent + # get "/user/1/section/3/project" + assert_equal [:user, :section], @app.routes[2].parent + # get "/user/1/project/edit/2" + assert_equal :user, @app.routes[4].parent + # get "/user/1/product/2/project/show/3" + assert_equal [:user, :product], @app.routes[6].parent + # get "/foo/1/bar" + assert_equal :foo, @app.routes[8].parent + # get "/foo/1/baz/2/bar" + assert_equal [:foo, :baz], @app.routes[10].parent + end + + should "apply parent to controller" do + mock_app do + controller :project, :parent => :user do + get(:index) { "index #{params[:user_id]}"} + get(:edit, :with => :id, :parent => :user) { "edit #{params[:id]} #{params[:user_id]}"} + get(:show, :with => :id, :parent => :product) { "show #{params[:id]} #{params[:user_id]} #{params[:product_id]}"} + end + end + + user_project_url = "/user/1/project" + get user_project_url + assert_equal "index 1", body + assert_equal user_project_url, @app.url(:project, :index, :user_id => 1) + + user_project_edit_url = "/user/1/project/edit/2" + get user_project_edit_url + assert_equal "edit 2 1", body + assert_equal user_project_edit_url, @app.url(:project, :edit, :user_id => 1, :id => 2) + + user_product_project_url = "/user/1/product/2/project/show/3" + get user_product_project_url + assert_equal "show 3 1 2", body + assert_equal user_product_project_url, @app.url(:project, :show, :user_id => 1, :product_id => 2, :id => 3) + end + + should "apply parent with shallowing to controller" do + mock_app do + controller :project do + parent :user + parent :shop, :optional => true + get(:index) { "index #{params[:user_id]} #{params[:shop_id]}" } + get(:edit, :with => :id) { "edit #{params[:id]} #{params[:user_id]} #{params[:shop_id]}" } + get(:show, :with => :id, :parent => :product) { "show #{params[:id]} #{params[:user_id]} #{params[:product_id]} #{params[:shop_id]}" } + end + end + + assert_equal "/user/1/project", @app.url(:project, :index, :user_id => 1, :shop_id => nil) + assert_equal "/user/1/shop/23/project", @app.url(:project, :index, :user_id => 1, :shop_id => 23) + + user_project_url = "/user/1/project" + get user_project_url + assert_equal "index 1 ", body + assert_equal user_project_url, @app.url(:project, :index, :user_id => 1) + + user_project_edit_url = "/user/1/project/edit/2" + get user_project_edit_url + assert_equal "edit 2 1 ", body + assert_equal user_project_edit_url, @app.url(:project, :edit, :user_id => 1, :id => 2) + + user_product_project_url = "/user/1/product/2/project/show/3" + get user_product_project_url + assert_equal "show 3 1 2 ", body + assert_equal user_product_project_url, @app.url(:project, :show, :user_id => 1, :product_id => 2, :id => 3) + + user_project_url = "/user/1/shop/1/project" + get user_project_url + assert_equal "index 1 1", body + assert_equal user_project_url, @app.url(:project, :index, :user_id => 1, :shop_id => 1) + + user_project_edit_url = "/user/1/shop/1/project/edit/2" + get user_project_edit_url + assert_equal "edit 2 1 1", body + assert_equal user_project_edit_url, @app.url(:project, :edit, :user_id => 1, :id => 2, :shop_id => 1) + + user_product_project_url = "/user/1/shop/1/product/2/project/show/3" + get user_product_project_url + assert_equal "show 3 1 2 1", body + assert_equal user_product_project_url, @app.url(:project, :show, :user_id => 1, :product_id => 2, :id => 3, :shop_id => 1) + end + + should "respect map in parents with shallowing" do + mock_app do + controller :project do + parent :shop, :map => "/foo/bar" + get(:index) { "index #{params[:shop_id]}" } + end + end + + shop_project_url = "/foo/bar/1/project" + get shop_project_url + assert_equal "index 1", body + assert_equal shop_project_url, @app.url(:project, :index, :shop_id => 1) + end + + should "use default values" do + mock_app do + controller :lang => :it do + get(:index, :map => "/:lang") { "lang is #{params[:lang]}" } + end + # This is only for be sure that default values + # work only for the given controller + get(:foo, :map => "/foo") {} + end + assert_equal "/it", @app.url(:index) + assert_equal "/foo", @app.url(:foo) + get "/en" + assert_equal "lang is en", body + end + + should "transitions to the next matching route on pass" do + mock_app do + get '/:foo' do + pass + 'Hello Foo' + end + get '/:bar' do + 'Hello World' + end + end + + get '/za' + assert_equal 'Hello World', body + end + + should "filters by accept header" do + mock_app do + get '/foo', :provides => [:xml, :js] do + request.env['HTTP_ACCEPT'] + end + end + + get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' } + assert ok? + assert_equal 'application/xml', body + assert_equal 'application/xml;charset=utf-8', response.headers['Content-Type'] + + get '/foo.xml' + assert ok? + assert_equal 'application/xml;charset=utf-8', response.headers['Content-Type'] + + get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript' } + assert ok? + assert_equal 'application/javascript', body + assert_equal 'application/javascript;charset=utf-8', response.headers['Content-Type'] + + get '/foo.js' + assert ok? + assert_equal 'application/javascript;charset=utf-8', response.headers['Content-Type'] + + get '/foo', {}, { "HTTP_ACCEPT" => 'text/html' } + assert_equal 406, status + end + + should "does not allow global provides" do + mock_app do + provides :xml + + get("/foo"){ "Foo in #{content_type.inspect}" } + get("/bar"){ "Bar in #{content_type.inspect}" } + end + + get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' } + assert_equal 'Foo in :xml', body + get '/foo' + assert_equal 'Foo in :xml', body + + get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' } + assert_equal 'Bar in nil', body + end + + should "does not allow global provides in controller" do + mock_app do + controller :base do + provides :xml + + get(:foo, "/foo"){ "Foo in #{content_type.inspect}" } + get(:bar, "/bar"){ "Bar in #{content_type.inspect}" } + end + end + + get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' } + assert_equal 'Foo in :xml', body + get '/foo' + assert_equal 'Foo in :xml', body + + get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' } + assert_equal 'Bar in nil', body + end + + should "map non named routes in controllers" do + mock_app do + controller :base do + get("/foo") { "ok" } + get("/bar") { "ok" } + end + end + + get "/base/foo" + assert ok? + get "/base/bar" + assert ok? + end + + should "set content_type to :html for both empty Accept as well as Accept text/html" do + mock_app do + provides :html + + get("/foo"){ content_type.to_s } + end + + get '/foo', {}, {} + assert_equal 'html', body + + get '/foo', {}, { 'HTTP_ACCEPT' => 'text/html' } + assert_equal 'html', body + end + + should "set content_type to :html if Accept */*" do + mock_app do + get("/foo", :provides => [:html, :js]) { content_type.to_s } + end + get '/foo', {}, {} + assert_equal 'html', body + + get '/foo', {}, { 'HTTP_ACCEPT' => '*/*;q=0.5' } + assert_equal 'html', body + end + + should "set content_type to :js if Accept includes both application/javascript and */*;q=0.5" do + mock_app do + get("/foo", :provides => [:html, :js]) { content_type.to_s } + end + get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript, */*;q=0.5' } + assert_equal 'js', body + end + + should "set content_type to :html if Accept */* and provides of :any" do + mock_app do + get("/foo", :provides => :any) { content_type.to_s } + end + + get '/foo', {}, { 'HTTP_ACCEPT' => '*/*' } + assert_equal 'html', body + end + + should "set content_type to :js if Accept includes both application/javascript, */*;q=0.5 and provides of :any" do + mock_app do + get("/foo", :provides => :any) { content_type.to_s } + end + + get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript, */*;q=0.5' } + assert_equal 'js', body + end + + should 'allows custom route-conditions to be set via route options and halt' do + protector = Module.new do + def protect(*args) + condition { + unless authorize(params["user"], params["password"]) + halt 403, "go away" + end + } + end + end + + mock_app do + register protector + + helpers do + def authorize(username, password) + username == "foo" && password == "bar" + end + end + + get "/", :protect => true do + "hey" + end + end + + get "/" + assert forbidden? + assert_equal "go away", body + + get "/", :user => "foo", :password => "bar" + assert ok? + assert_equal "hey", body + end + + should 'allows custom route-conditions to be set via route options using two routes' do + protector = Module.new do + def protect(*args) + condition { authorize(params["user"], params["password"]) } + end + end + + mock_app do + register protector + + helpers do + def authorize(username, password) + username == "foo" && password == "bar" + end + end + + get "/", :protect => true do + "hey" + end + + get "/" do + "go away" + end + end + + get "/" + assert_equal "go away", body + + get "/", :user => "foo", :password => "bar" + assert ok? + assert_equal "hey", body + end + + should "allow concise routing" do + mock_app do + get :index, ":id" do + params[:id] + end + + get :map, "route/:id" do + params[:id] + end + end + + get "/123" + assert_equal "123", body + + get "/route/123" + assert_equal "123", body + end + + should "support halting with 404 and message" do + mock_app do + controller do + get :index do + halt 404, "not found" + end + end + end + + get "/" + assert_equal 404, status + assert_equal "not found", body + end + + should "allow passing & halting in before filters" do + mock_app do + controller do + before { env['QUERY_STRING'] == 'secret' or pass } + get :index do + "secret index" + end + end + + controller do + before { env['QUERY_STRING'] == 'halt' and halt 401, 'go away!' } + get :index do + "index" + end + end + end + + get "/?secret" + assert_equal "secret index", body + + get "/?halt" + assert_equal "go away!", body + assert_equal 401, status + + get "/" + assert_equal "index", body + end + + should 'scope filters in the given controller' do + mock_app do + before { @global = 'global' } + after { @global = nil } + + controller :foo do + before { @foo = :foo } + after { @foo = nil } + get("/") { [@foo, @bar, @global].compact.join(" ") } + end + + get("/") { [@foo, @bar, @global].compact.join(" ") } + + controller :bar do + before { @bar = :bar } + after { @bar = nil } + get("/") { [@foo, @bar, @global].compact.join(" ") } + end + end + + get "/bar" + assert_equal "bar global", body + + get "/foo" + assert_equal "foo global", body + + get "/" + assert_equal "global", body + end + + should 'works with optionals params' do + mock_app do + get("/foo(/:bar)") { params[:bar] } + end + + get "/foo/bar" + assert_equal "bar", body + + get "/foo" + assert_equal "", body + end + + should 'work with multiple dashed params' do + mock_app do + get "/route/:foo/:bar/:baz", :provides => :html do + "#{params[:foo]};#{params[:bar]};#{params[:baz]}" + end + end + + get "/route/foo/bar/baz" + assert_equal 'foo;bar;baz', body + + get "/route/foo/bar-whatever/baz" + assert_equal 'foo;bar-whatever;baz', body + end + + should 'work with arbitrary params' do + mock_app do + get(:testing) { params[:foo] } + end + + url = @app.url(:testing, :foo => 'bar') + assert_equal "/testing?foo=bar", url + get url + assert_equal "bar", body + end + + should 'ignore nil params' do + mock_app do + get(:testing, :provides => [:html, :json]) do + end + end + assert_equal '/testing.html', @app.url(:testing, :format => :html) + assert_equal '/testing', @app.url(:testing, :format => nil) + end + + should 'be able to access params in a before filter' do + username_from_before_filter = nil + + mock_app do + before do + username_from_before_filter = params[:username] + end + + get :users, :with => :username do + end + end + get '/users/josh' + assert_equal 'josh', username_from_before_filter + end + + should "be able to access params normally when a before filter is specified" do + mock_app do + before { } + get :index do + params.inspect + end + end + get '/?test=what' + assert_equal '{"test"=>"what"}', body + end + + should 'work with controller and arbitrary params' do + mock_app do + get(:testing) { params[:foo] } + controller :test1 do + get(:url1) { params[:foo] } + get(:url2, :provides => [:html, :json]) { params[:foo] } + end + end + + url = @app.url(:test1, :url1, :foo => 'bar1') + assert_equal "/test1/url1?foo=bar1", url + get url + assert_equal "bar1", body + + url = @app.url(:test1, :url2, :foo => 'bar2') + assert_equal "/test1/url2?foo=bar2", url + get url + assert_equal "bar2", body + end + + should "parse two routes with the same path but different http verbs" do + mock_app do + get(:index) { "This is the get index" } + post(:index) { "This is the post index" } + end + get "/" + assert_equal "This is the get index", body + post "/" + assert_equal "This is the post index", body + end + + should "use optionals params" do + mock_app do + get(:index, :map => "/(:foo(/:bar))") { "#{params[:foo]}-#{params[:bar]}" } + end + get "/foo" + assert_equal "foo-", body + get "/foo/bar" + assert_equal "foo-bar", body + end + + should "parse two routes with the same path but different http verbs and provides" do + mock_app do + get(:index, :provides => [:html, :json]) { "This is the get index.#{content_type}" } + post(:index, :provides => [:html, :json]) { "This is the post index.#{content_type}" } + end + get "/" + assert_equal "This is the get index.html", body + post "/" + assert_equal "This is the post index.html", body + get "/.json" + assert_equal "This is the get index.json", body + get "/.js" + assert_equal 404, status + post "/.json" + assert_equal "This is the post index.json", body + post "/.js" + assert_equal 404, status + end + + should "allow controller level mapping" do + mock_app do + controller :map => "controller-:id" do + get(:url3) { "#{params[:id]}" } + get(:url4, :map => 'test-:id2') { "#{params[:id]}, #{params[:id2]}" } + end + end + + url = @app.url(:url3, :id => 1) + assert_equal "/controller-1/url3", url + get url + assert_equal "1", body + + url = @app.url(:url4, 1, 2) + assert_equal "/controller-1/test-2", url + get url + assert_equal "1, 2", body + end + + should "replace name of named controller with mapping path" do + mock_app do + controller :ugly, :map => "/pretty/:id" do + get(:url3) { "#{params[:id]}" } + get(:url4, :map => 'test-:id2') { "#{params[:id]}, #{params[:id2]}" } + end + controller :voldemort, :map => "" do + get(:url5) { "okay" } + end + end + + url = @app.url(:ugly, :url3, :id => 1) + assert_equal "/pretty/1/url3", url + get url + assert_equal "1", body + + url = @app.url(:ugly, :url4, 3, 5) + assert_equal "/pretty/3/test-5", url + get url + assert_equal "3, 5", body + + url = @app.url(:voldemort, :url5) + assert_equal "/url5", url + get url + assert_equal 'okay', body + end + + should 'use absolute and relative maps' do + mock_app do + controller :one do + parent :three + get :index, :map => 'one' do; end + get :index2, :map => '/one' do; end + end + + controller :two, :map => 'two' do + parent :three + get :index, :map => 'two' do; end + get :index2, :map => '/two', :with => :id do; end + end + end + assert_equal "/three/three_id/one", @app.url(:one, :index, 'three_id') + assert_equal "/one", @app.url(:one, :index2) + assert_equal "/two/three/three_id/two", @app.url(:two, :index, 'three_id') + assert_equal "/two/four_id", @app.url(:two, :index2, 'four_id') + end + + should "work with params and parent options" do + mock_app do + controller :test2, :parent => :parent1, :parent1_id => 1 do + get(:url3) { params[:foo] } + get(:url4, :with => :with1) { params[:foo] } + get(:url5, :with => :with2, :provides => [:html]) { params[:foo] } + end + end + + url = @app.url(:test2, :url3, :foo => 'bar3') + assert_equal "/parent1/1/test2/url3?foo=bar3", url + get url + assert_equal "bar3", body + + url = @app.url(:test2, :url4, :with1 => 'awith1', :foo => 'bar4') + assert_equal "/parent1/1/test2/url4/awith1?foo=bar4", url + get url + assert_equal "bar4", body + + url = @app.url(:test2, :url5, :with2 => 'awith1', :foo => 'bar5') + assert_equal "/parent1/1/test2/url5/awith1?foo=bar5", url + get url + assert_equal "bar5", body + end + + should "parse params without explicit provides for every matching route" do + mock_app do + get(:index, :map => "/foos/:bar") { "get bar = #{params[:bar]}" } + post :create, :map => "/foos/:bar", :provides => [:html, :js] do + "post bar = #{params[:bar]}" + end + end + + get "/foos/hello" + assert_equal "get bar = hello", body + post "/foos/hello" + assert_equal "post bar = hello", body + post "/foos/hello.js" + assert_equal "post bar = hello", body + end + + should "properly route to first foo with two similar routes" do + mock_app do + controllers do + get('/foo/') { "this is foo" } + get(:show, :map => "/foo/:bar/:id") { "/foo/#{params[:bar]}/#{params[:id]}" } + end + end + get "/foo" + assert_equal "this is foo", body + get "/foo/" + assert_equal "this is foo", body + get '/foo/5/10' + assert_equal "/foo/5/10", body + end + + should "index routes should be optional when nested" do + mock_app do + controller '/users', :provides => [:json] do + get '/' do + "foo" + end + end + end + get "/users.json" + assert_equal "foo", body + end + + should "use provides as conditional" do + mock_app do + provides :json + get "/" do + "foo" + end + end + get "/.json" + assert_equal "foo", body + end + + should_eventually "reset provides for routes that didn't use it" do + mock_app do + get('/foo', :provides => :js){} + get('/bar'){} + end + get '/foo' + assert ok? + get '/foo.js' + assert ok? + get '/bar' + assert ok? + get '/bar.js' + assert_equal 404, status + end + + should "pass controller conditions to each route" do + counter = 0 + + mock_app do + self.class.send(:define_method, :increment!) do |*args| + condition { counter += 1 } + end + + controller :posts, :conditions => {:increment! => true} do + get("/foo") { "foo" } + get("/bar") { "bar" } + end + + end + + get "/posts/foo" + get "/posts/bar" + assert_equal 2, counter + end + + should "allow controller conditions to be overridden" do + counter = 0 + + mock_app do + self.class.send(:define_method, :increment!) do |increment| + condition { counter += 1 } if increment + end + + controller :posts, :conditions => {:increment! => true} do + get("/foo") { "foo" } + get("/bar", :increment! => false) { "bar" } + end + + end + + get "/posts/foo" + get "/posts/bar" + assert_equal 1, counter + end + + should "parse params with class level provides" do + mock_app do + controllers :posts, :provides => [:html, :js] do + post(:create, :map => "/foo/:bar/:baz/:id") { + "POST CREATE #{params[:bar]} - #{params[:baz]} - #{params[:id]}" + } + end + controllers :topics, :provides => [:js, :html] do + get(:show, :map => "/foo/:bar/:baz/:id") { render "topics/show" } + post(:create, :map => "/foo/:bar/:baz") { "TOPICS CREATE #{params[:bar]} - #{params[:baz]}" } + end + end + post "/foo/bar/baz.js" + assert_equal "TOPICS CREATE bar - baz", body, "should parse params with explicit .js" + post @app.url(:topics, :create, :format => :js, :bar => 'bar', :baz => 'baz') + assert_equal "TOPICS CREATE bar - baz", body, "should parse params from generated url" + post "/foo/bar/baz/5.js" + assert_equal "POST CREATE bar - baz - 5", body + post @app.url(:posts, :create, :format => :js, :bar => 'bar', :baz => 'baz', :id => 5) + assert_equal "POST CREATE bar - baz - 5", body + end + + should "parse params properly with inline provides" do + mock_app do + controllers :posts do + post(:create, :map => "/foo/:bar/:baz/:id", :provides => [:html, :js]) { + "POST CREATE #{params[:bar]} - #{params[:baz]} - #{params[:id]}" + } + end + controllers :topics do + get(:show, :map => "/foo/:bar/:baz/:id", :provides => [:html, :js]) { render "topics/show" } + post(:create, :map => "/foo/:bar/:baz", :provides => [:html, :js]) { "TOPICS CREATE #{params[:bar]} - #{params[:baz]}" } + end + end + post @app.url(:topics, :create, :format => :js, :bar => 'bar', :baz => 'baz') + assert_equal "TOPICS CREATE bar - baz", body, "should properly post to topics create action" + post @app.url(:posts, :create, :format => :js, :bar => 'bar', :baz => 'baz', :id => 5) + assert_equal "POST CREATE bar - baz - 5", body, "should properly post to create action" + end + + should "have overideable format" do + ::Rack::Mime::MIME_TYPES[".other"] = "text/html" + mock_app do + before do + params[:format] ||= :other + end + get("/format_test", :provides => [:html, :other]){ content_type.to_s } + end + get "/format_test" + assert_equal "other", body + ::Rack::Mime::MIME_TYPES.delete('.other') + end + + should 'invokes handlers registered with ::error when raised' do + mock_app do + set :raise_errors, false + error(FooError) { 'Foo!' } + get '/' do + raise FooError + end + end + get '/' + assert_equal 500, status + assert_equal 'Foo!', body + end + + should 'have MethodOverride middleware' do + mock_app do + put('/') { 'okay' } + end + assert @app.method_override? + post '/', {'_method'=>'PUT'}, {} + assert_equal 200, status + assert_equal 'okay', body + end + + should 'return value from params' do + mock_app do + get("/foo/:bar"){ raise "'bar' should be a string" unless params[:bar].kind_of? String} + end + get "/foo/50" + assert ok? + end + + should 'have MethodOverride middleware with more options' do + mock_app do + put('/hi', :provides => [:json]) { 'hi' } + end + post '/hi', {'_method'=>'PUT'} + assert_equal 200, status + assert_equal 'hi', body + post '/hi.json', {'_method'=>'PUT'} + assert_equal 200, status + assert_equal 'hi', body + post '/hi.json' + assert_equal 405, status + end + + should 'parse nested params' do + mock_app do + get(:index) { "%s %s" % [params[:account][:name], params[:account][:surname]] } + end + get "/?account[name]=foo&account[surname]=bar" + assert_equal 'foo bar', body + get @app.url(:index, "account[name]" => "foo", "account[surname]" => "bar") + assert_equal 'foo bar', body + end + + should 'render sinatra NotFound page' do + mock_app { set :environment, :development } + get "/" + assert_equal 404, status + assert_match %r{(Sinatra doesn’t know this ditty.|

Not Found

)}, body + end + + should 'render a custom NotFound page' do + mock_app do + error(Sinatra::NotFound) { "not found" } + end + get "/" + assert_equal 404, status + assert_match /not found/, body + end + + should 'render a custom 404 page using not_found' do + mock_app do + not_found { "custom 404 not found" } + end + get "/" + assert_equal 404, status + assert_equal "custom 404 not found", body + end + + should 'render a custom error page using error method' do + skip + mock_app do + error(404) { "custom 404 error" } + end + get "/" + assert_equal 404, status + assert_equal "custom 404 error", body + end + + should 'render a custom 403 page' do + mock_app do + error(403) { "custom 403 not found" } + get("/") { status 403 } + end + get "/" + assert_equal 403, status + assert_equal "custom 403 not found", body + end + + should 'recognize paths' do + mock_app do + controller :foo do + get(:bar, :map => "/my/:id/custom-route") { } + end + get(:simple, :map => "/simple/:id") { } + get(:with_format, :with => :id, :provides => :js) { } + end + assert_equal [:foo_bar, { :id => "fantastic" }], @app.recognize_path(@app.url(:foo, :bar, :id => :fantastic)) + assert_equal [:foo_bar, { :id => "18" }], @app.recognize_path(@app.url(:foo, :bar, :id => 18)) + assert_equal [:simple, { :id => "bar" }], @app.recognize_path(@app.url(:simple, :id => "bar")) + assert_equal [:simple, { :id => "true" }], @app.recognize_path(@app.url(:simple, :id => true)) + assert_equal [:simple, { :id => "9" }], @app.recognize_path(@app.url(:simple, :id => 9)) + assert_equal [:with_format, { :id => "bar", :format => "js" }], @app.recognize_path(@app.url(:with_format, :id => "bar", :format => :js)) + assert_equal [:with_format, { :id => "true", :format => "js" }], @app.recognize_path(@app.url(:with_format, :id => true, :format => "js")) + assert_equal [:with_format, { :id => "9", :format => "js" }], @app.recognize_path(@app.url(:with_format, :id => 9, :format => :js)) + end + + should 'have current_path' do + mock_app do + controller :foo do + get(:index) { current_path } + get :bar, :map => "/paginate/:page" do + current_path + end + get(:after) { current_path } + end + end + get "/paginate/10" + assert_equal "/paginate/10", body + get "/foo/after" + assert_equal "/foo/after", body + get "/foo" + assert_equal "/foo", body + end + + should 'accept :map and :parent' do + mock_app do + controller :posts do + get :show, :parent => :users, :map => "posts/:id" do + "#{params[:user_id]}-#{params[:id]}" + end + end + end + get '/users/123/posts/321' + assert_equal "123-321", body + end + + should 'change params in current_path' do + mock_app do + get :index, :map => "/paginate/:page" do + current_path(:page => 66) + end + end + get @app.url(:index, :page => 10) + assert_equal "/paginate/66", body + end + + should 'not route get :users, :with => :id to /users//' do + mock_app do + get(:users, :with => :id) { 'boo' } + end + get '/users//' + assert_equal 404, status + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_support_lite.rb b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_support_lite.rb new file mode 100644 index 00000000..8102b288 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-core-0.11.4/test/test_support_lite.rb @@ -0,0 +1,56 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +describe "ObjectSpace" do + def setup + end + + def teardown + end + + context "#classes" do + should "take an snapshot of the current loaded classes" do + snapshot = ObjectSpace.classes + assert_equal snapshot.include?(Padrino::Logger), true + end + + should "return a Set object" do + snapshot = ObjectSpace.classes + assert_equal snapshot.kind_of?(Set), true + end + + should "be able to process a the class name given a block" do + klasses = ObjectSpace.classes do |klass| + if klass.name =~ /^Padrino::/ + klass + end + end + + assert_equal (klasses.size > 1), true + klasses.each do |klass| + assert_match /^Padrino::/, klass.to_s + end + end + end + + context "#new_classes" do + setup do + @snapshot = ObjectSpace.classes + end + + should "return list of new classes" do + class OSTest; end + module OSTestModule; class B; end; end + + new_classes = ObjectSpace.new_classes(@snapshot) + + assert_equal new_classes.size, 2 + assert_equal new_classes.include?(OSTest), true + assert_equal new_classes.include?(OSTestModule::B), true + end + + should "return a Set object" do + new_classes = ObjectSpace.new_classes(@snapshot) + assert_equal new_classes.kind_of?(Set), true + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/.document b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/.document new file mode 100644 index 00000000..136eea59 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/.document @@ -0,0 +1,5 @@ +lib/**/*.rb +bin/* +- +README.rdoc +LICENSE.txt diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/.gitignore b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/.gitignore new file mode 100644 index 00000000..c1e0dafa --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/.gitignore @@ -0,0 +1,21 @@ +## MAC OS +.DS_Store + +## TEXTMATE +*.tmproj +tmtags + +## EMACS +*~ +\#* +.\#* + +## VIM +*.swp + +## PROJECT::GENERAL +coverage +rdoc +pkg + +## PROJECT::SPECIFIC diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/.yardopts b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/.yardopts new file mode 100644 index 00000000..57854bc2 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/.yardopts @@ -0,0 +1 @@ +--title 'Padrino Helpers Documentation' --protected diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/LICENSE.txt b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/LICENSE.txt new file mode 100644 index 00000000..8f1ef777 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2011 Padrino + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/README.rdoc b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/README.rdoc new file mode 100644 index 00000000..ec68bac6 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/README.rdoc @@ -0,0 +1,239 @@ += Application Extensions and Helpers (padrino-helpers) + +=== Overview + +This component provides a great deal of view helpers related to html markup generation. +There are helpers for generating tags, forms, links, images, and more. Most of the basic +methods should be very familiar to anyone who has used rails view helpers. + +=== Output Helpers + +Output helpers are a collection of important methods for managing, capturing and displaying output +in various ways and is used frequently to support higher-level helper functions. There are +three output helpers worth mentioning: content_for, capture_html, and concat_content + +The content_for functionality supports capturing content and then rendering this into a different place +such as within a layout. One such popular example is including assets onto the layout from a template: + + # app/views/site/index.erb + ... + <% content_for :assets do %> + <%= stylesheet_link_tag 'index', 'custom' %> + <% end %> + ... + +Added to a template, this will capture the includes from the block and allow them to be yielded into the layout: + + # app/views/layout.erb + ... + + Example + <%= stylesheet_link_tag 'style' %> + <%= yield_content :assets %> + + ... + +This will automatically insert the contents of the block (in this case a stylesheet include) into the +location the content is yielded within the layout. You can also check if content exists for a block using +content_for?(true) which returns true if content exists. + +The capture_html and the concat_content methods allow content to be manipulated and stored for use in building +additional helpers accepting blocks or displaying information in a template. One example is the use of +these in constructing a simplified 'form_tag' helper which accepts a block. + + # form_tag '/register' do ... end + def form_tag(url, options={}, &block) + # ... truncated ... + inner_form_html = capture_html(&block) + concat_content '
' + inner_form_html + '
' + end + +This will capture the template body passed into the form_tag block and then append the content +to the template through the use of concat_content. Note have been built to work for both haml and erb +templates using the same syntax. + +For more information on using output helpers, check out the guide for +{Padrino Helpers}[http://www.padrinorb.com/guides/application-helpers]. + +=== Tag Helpers + +Tag helpers are the basic building blocks used to construct html 'tags' within a view template. There +are three major functions for this category: tag, content_tag and input_tag. + +The tag and content_tag are for building arbitrary html tags with a name and specified options. If +the tag contains 'content' within then content_tag is used. For example: + + tag(:br, :style => 'clear:both') =>
+ content_tag(:p, "demo", :class => 'light') =>

demo

+ +The input_tag is used to build tags that are related to accepting input from the user: + + input_tag :text, :class => "demo" => + input_tag :password, :value => "secret", :class => "demo" + +Note that all of these accept html options and result in returning a string containing html tags. + +For more information on using tag helpers, check out the guide for +{Padrino Helpers}[http://www.padrinorb.com/guides/application-helpers]. + +=== Asset Helpers + +Asset helpers are intended to help insert useful html onto a view template such as 'flash' notices, +hyperlinks, mail_to links, images, stylesheets and javascript. An example of their uses would be on a +simple view template: + + # app/views/example.haml + ... + %head + = stylesheet_link_tag 'layout' + = javascript_include_tag 'application' + %body + ... + = flash_tag :notice + %p= link_to 'Blog', '/blog', :class => 'example' + %p Mail me at #{mail_to 'fake@faker.com', "Fake Email Link", :cc => "test@demo.com"} + %p= image_tag 'padrino.png', :width => '35', :class => 'logo' + +For more information on using asset helpers, check out the guide for +{Padrino Helpers}[http://www.padrinorb.com/guides/application-helpers]. + +=== Form Helpers + +Form helpers are the 'standard' form tag helpers you would come to expect when building forms. A simple +example of constructing a non-object form would be: + + - form_tag '/destroy', :class => 'destroy-form', :method => 'delete' do + = flash_tag(:notice) + - field_set_tag do + %p + = label_tag :username, :class => 'first' + = text_field_tag :username, :value => params[:username] + %p + = label_tag :password, :class => 'first' + = password_field_tag :password, :value => params[:password] + %p + = label_tag :strategy + = select_tag :strategy, :options => ['delete', 'destroy'], :selected => 'delete' + %p + = check_box_tag :confirm_delete + - field_set_tag(:class => 'buttons') do + = submit_tag "Remove" + +For more information on using form helpers, check out the guide for +{Padrino Helpers}[http://www.padrinorb.com/guides/application-helpers]. + +=== FormBuilders + +Form builders are full-featured objects allowing the construction of complex object-based forms +using a simple, intuitive syntax. + +A form_for using these basic fields might look like: + + - form_for @user, '/register', :id => 'register' do |f| + = f.error_messages + %p + = f.label :username, :caption => "Nickname" + = f.text_field :username + %p + = f.label :email + = f.text_field :email + %p + = f.label :password + = f.password_field :password + %p + = f.label :is_admin, :caption => "Admin User?" + = f.check_box :is_admin + %p + = f.label :color, :caption => "Favorite Color?" + = f.select :color, :options => ['red', 'black'] + %p + - fields_for @user.location do |location| + = location.text_field :street + = location.text_field :city + %p + = f.submit "Create", :class => 'button' + +Forms can also accept nested attributes using `fields_for` within the form builder in recent releases. Check out the guide for {Padrino Helpers}[http://www.padrinorb.com/guides/application-helpers] to learn more about nested forms. + +There is also an additional StandardFormBuilder which builds on the abstract fields that can be used within a form_for. + +A form_for using these standard fields might be: + + - form_for @user, '/register', :id => 'register' do |f| + = f.error_messages + = f.text_field_block :name, :caption => "Full name" + = f.text_field_block :email + = f.check_box_block :remember_me + = f.select_block :fav_color, :options => ['red', 'blue'] + = f.password_field_block :password + = f.submit_block "Create", :class => 'button' + +and would generate this html (with each input contained in a paragraph and containing a label): + +
+

+ ...omitted... +

+
+ +You can also easily build your own FormBuilder which allows for customized fields and behavior. + +For more information on using the Padrino form builders, check out the guide for +{Padrino Helpers}[http://www.padrinorb.com/guides/application-helpers]. + +=== Format Helpers + +Format helpers are several useful utilities for manipulating the format of text to achieve a goal. +The four format helpers are escape_html, time_ago_in_words, and js_escape_html. + +The escape_html and js_escape_html function are for taking an html string and escaping certain characters. +escape_html will escape ampersands, brackets and quotes to their HTML/XML entities. This is useful +to sanitize user content before displaying this on a template. js_escape_html is used for +passing javascript information from a js template to a javascript function. + + escape_html('&') # => <hello>&<goodbye> + +There is also an alias for escape_html called h for even easier usage within templates. + +Format helpers also includes a number of useful text manipulation functions such as simple_format, +pluralize, word_wrap, truncate and truncate_words. + + simple_format("hello\nworld") # => "

hello
world

" + pluralize(2, 'person') => '2 people' + word_wrap('Once upon a time', :line_width => 8) => "Once upon\na time" + truncate("Once upon a time in a world far far away", :length => 8) => "Once upon..." + truncate_words("Once upon a time in a world far far away", :length => 4) => "Once upon a time..." + +These helpers can be invoked from any route or view within your application. + +For more information on using the format helpers, check out the guide for +{Padrino Helpers}[http://www.padrinorb.com/guides/application-helpers]. + +=== Render Helpers + +This component provides a number of rendering helpers making the process of displaying templates a bit easier. +This plugin also has support for useful additions such as partials (with support for :collection) for the templating system. + +Using render plugin helpers is extremely simple. If you want to render an erb template in your view path: + + render :erb, 'path/to/erb/template' + +or using haml templates works just as well: + + render :haml, 'path/to/haml/template' + +There is also a method which renders the first view matching the path and removes the need to define an engine: + + render 'path/to/any/template' + +Finally, we have the all-important partials support for rendering mini-templates onto a page: + + partial 'photo/_item', :object => @photo, :locals => { :foo => 'bar' } + partial 'photo/_item', :collection => @photos + +For more information on using the render and partial helpers, check out the guide for +{Padrino Helpers}[http://www.padrinorb.com/guides/application-helpers]. + +== Copyright + +Copyright (c) 2011-2013 Padrino. See LICENSE for details. diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/Rakefile b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/Rakefile new file mode 100644 index 00000000..f33347d2 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/Rakefile @@ -0,0 +1,5 @@ +# coding:utf-8 +RAKE_ROOT = __FILE__ + +require 'rubygems' +require File.expand_path(File.dirname(__FILE__) + '/../gem_rake_helper') \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers.rb new file mode 100644 index 00000000..2d51c6fd --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers.rb @@ -0,0 +1,57 @@ +require 'padrino-core/support_lite' unless defined?(SupportLite) +require 'i18n' +require 'enumerator' +require 'active_support/time_with_zone' # next extension depends on this +require 'active_support/core_ext/string/conversions' # to_date +require 'active_support/option_merger' # with_options +require 'active_support/core_ext/object/with_options' # with_options +require 'active_support/inflector' # humanize + +FileSet.glob_require('padrino-helpers/**/*.rb', __FILE__) +I18n.load_path += Dir["#{File.dirname(__FILE__)}/padrino-helpers/locale/*.yml"] + +module Padrino + ## + # This component provides a variety of view helpers related to html markup generation. + # There are helpers for generating tags, forms, links, images, and more. + # Most of the basic methods should be very familiar to anyone who has used rails view helpers. + # + module Helpers + class << self + ## + # Registers these helpers into your application: + # + # Padrino::Helpers::OutputHelpers + # Padrino::Helpers::TagHelpers + # Padrino::Helpers::AssetTagHelpers + # Padrino::Helpers::FormHelpers + # Padrino::Helpers::FormatHelpers + # Padrino::Helpers::RenderHelpers + # Padrino::Helpers::NumberHelpers + # Padrino::Helpers::Breadcrumbs + # + # @param [Sinatra::Application] app + # The specified Padrino application. + # + # @example Register the helper module + # require 'padrino-helpers' + # class Padrino::Application + # register Padrino::Helpers + # end + # + def registered(app) + app.set :default_builder, 'StandardFormBuilder' + app.helpers Padrino::Helpers::OutputHelpers + app.helpers Padrino::Helpers::TagHelpers + app.helpers Padrino::Helpers::AssetTagHelpers + app.helpers Padrino::Helpers::FormHelpers + app.helpers Padrino::Helpers::FormatHelpers + app.helpers Padrino::Helpers::RenderHelpers + app.helpers Padrino::Helpers::NumberHelpers + app.helpers Padrino::Helpers::TranslationHelpers + app.helpers Padrino::Helpers::Breadcrumbs + end + alias :included :registered + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/asset_tag_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/asset_tag_helpers.rb new file mode 100644 index 00000000..d7c25265 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/asset_tag_helpers.rb @@ -0,0 +1,401 @@ +module Padrino + module Helpers + ### + # Helpers related to producing assets (images, stylesheets, js, etc) within templates. + # + module AssetTagHelpers + FRAGMENT_HASH = "#".html_safe.freeze + APPEND_ASSET_EXTENSIONS = ["js", "css"] + ABSOLUTE_URL_PATTERN = %r{^(https?://)} + + ## + # Creates a div to display the flash of given type if it exists. + # + # @param [Symbol] kind + # The type of flash to display in the tag. + # @param [Hash] options + # The html options for this section. + # use :bootstrap => true to support Twitter's bootstrap dismiss alert button. + # + # @return [String] Flash tag html with specified +options+. + # + # @example + # flash_tag(:notice, :id => 'flash-notice') + # # Generates:
flash-notice
+ # flash_tag(:error, :success) + # # Generates:
flash-error
+ # #
flash-success
+ # + def flash_tag(*args) + options = args.extract_options! + bootstrap = options.delete(:bootstrap) if options[:bootstrap] + args.inject(''.html_safe) do |html,kind| + flash_text = flash[kind] + next html if flash_text.blank? + flash_text << safe_content_tag(:button, "×", {:type => :button, :class => :close, :'data-dismiss' => :alert}) if bootstrap + html << safe_content_tag(:div, flash_text, options.reverse_merge(:class => kind)) + end + end + + ## + # Creates a link element with given name, url and options. + # + # @overload link_to(caption, url, options={}) + # @param [String] caption The text caption. + # @param [String] url The url href. + # @param [Hash] options The html options. + # @overload link_to(url, options={}, &block) + # @param [String] url The url href. + # @param [Hash] options The html options. + # @param [Proc] block The link content. + # + # @option options [String] :anchor + # The anchor for the link (i.e #something). + # @option options [String] :fragment + # Synonym for anchor. + # @option options [Boolean] :if + # If true, the link will appear, otherwise not. + # @option options [Boolean] :unless + # If false, the link will appear, otherwise not. + # @option options [Boolean] :remote + # If true, this link should be handled by an ajax ujs handler. + # @option options [String] :confirm + # Instructs ujs handler to alert confirm message. + # @option options [Symbol] :method + # Instructs ujs handler to use different http method (i.e :post, :delete). + # + # @return [String] Link tag html with specified +options+. + # + # @example + # link_to('click me', '/dashboard', :class => 'linky') + # link_to('click me', '/dashboard', :remote => true) + # link_to('click me', '/dashboard', :method => :delete) + # link_to('click me', :class => 'blocky') do; end + # + # Note that you can pass :+if+ or :+unless+ conditions, but if you provide :current as + # condition padrino return true/false if the request.path_info match the given url. + # + def link_to(*args, &block) + options = args.extract_options! + fragment = options.delete(:anchor).to_s if options[:anchor] + fragment = options.delete(:fragment).to_s if options[:fragment] + + url = ActiveSupport::SafeBuffer.new + if block_given? + if args[0] + url.concat(args[0]) + url.concat(FRAGMENT_HASH).concat(fragment) if fragment + else + url.concat(FRAGMENT_HASH) + url.concat(fragment) if fragment + end + options.reverse_merge!(:href => url) + link_content = capture_html(&block) + return '' unless parse_conditions(url, options) + result_link = content_tag(:a, link_content, options) + block_is_template?(block) ? concat_content(result_link) : result_link + else + if args[1] + url.concat(args[1]) + url.safe_concat(FRAGMENT_HASH).concat(fragment) if fragment + else + url = FRAGMENT_HASH + url.concat(fragment) if fragment + end + name = args[0] + return name unless parse_conditions(url, options) + options.reverse_merge!(:href => url) + content_tag(:a, name, options) + end + end + + ## + # Creates a link tag that browsers and news readers can use to auto-detect an RSS or ATOM feed. + # + # @param [Symbol] mime + # The mime type of the feed (i.e :atom or :rss). + # @param [String] url + # The url for the feed tag to reference. + # @param[Hash] options + # The options for the feed tag. + # @option options [String] :rel ("alternate") + # Specify the relation of this link. + # @option options [String] :type + # Override the auto-generated mime type. + # @option options [String] :title + # Specify the title of the link, defaults to the type. + # + # @return [String] Feed link html tag with specified +options+. + # + # @example + # feed_tag :atom, url(:blog, :posts, :format => :atom), :title => "ATOM" + # # Generates: + # feed_tag :rss, url(:blog, :posts, :format => :rss) + # # Generates: + # + def feed_tag(mime, url, options={}) + full_mime = (mime == :atom) ? 'application/atom+xml' : 'application/rss+xml' + tag(:link, options.reverse_merge(:rel => 'alternate', :type => full_mime, :title => mime, :href => url)) + end + + ## + # Creates a mail link element with given name and caption. + # + # @param [String] email + # The email address for the link. + # @param [String] caption + # The caption for the link. + # @param [Hash] mail_options + # The options for the mail link. Accepts html options. + # @option mail_options [String] cc The cc recipients. + # @option mail_options [String] bcc The bcc recipients. + # @option mail_options [String] subject The subject line. + # @option mail_options [String] body The email body. + # + # @return [String] Mail link html tag with specified +options+. + # + # @example + # # Generates: me@demo.com + # mail_to "me@demo.com" + # # Generates: My Email + # mail_to "me@demo.com", "My Email" + # + def mail_to(email, caption=nil, mail_options={}) + html_options = mail_options.slice!(:cc, :bcc, :subject, :body) + mail_query = Rack::Utils.build_query(mail_options).gsub(/\+/, '%20').gsub('%40', '@').gsub('&', '&') + mail_href = "mailto:#{email}"; mail_href << "?#{mail_query}" if mail_query.present? + link_to((caption || email), mail_href, html_options) + end + + ## + # Creates a meta element with the content and given options. + # + # @param [String] content + # The content for the meta tag. + # @param [Hash] options + # The html options for the meta tag. + # + # @return [String] Meta html tag with specified +options+. + # + # @example + # # Generates: + # meta_tag "weblog,news", :name => "keywords" + # + # # Generates: + # meta_tag "text/html; charset=UTF-8", 'http-equiv' => "Content-Type" + # + def meta_tag(content, options={}) + options.reverse_merge!("content" => content) + tag(:meta, options) + end + + ## + # Generates a favicon link. Looks inside images folder + # + # @param [String] source + # The source image path for the favicon link tag. + # @param [Hash] options + # The html options for the favicon link tag. + # + # @return [String] The favicon link html tag with specified +options+. + # + # @example + # favicon_tag 'favicon.png' + # favicon_tag 'icons/favicon.png' + # # or override some options + # favicon_tag 'favicon.png', :type => 'image/ico' + # + def favicon_tag(source, options={}) + type = File.extname(source).gsub('.','') + options = options.dup.reverse_merge!(:href => image_path(source), :rel => 'icon', :type => "image/#{type}") + tag(:link, options) + end + + ## + # Creates an image element with given url and options. + # + # @param [String] url + # The source path for the image tag. + # @param [Hash] options + # The html options for the image tag. + # + # @return [String] Image html tag with +url+ and specified +options+. + # + # @example + # image_tag('icons/avatar.png') + # + def image_tag(url, options={}) + options.reverse_merge!(:src => image_path(url)) + tag(:img, options) + end + + ## + # Returns an html script tag for each of the sources provided. + # You can pass in the filename without extension or a symbol and we search it in your +appname.public_folder+ + # like app/public/stylesheets for inclusion. You can provide also a full path. + # + # @overload stylesheet_link_tag(*sources, options={}) + # @param [Array] sources Splat of css source paths + # @param [Hash] options The html options for the link tag + # + # @return [String] Stylesheet link html tag for +sources+ with specified +options+. + # + # @example + # stylesheet_link_tag 'style', 'application', 'layout' + # + # @api public. + def stylesheet_link_tag(*sources) + options = sources.extract_options!.symbolize_keys + options.reverse_merge!(:media => 'screen', :rel => 'stylesheet', :type => 'text/css') + sources.flatten.map { |source| + tag(:link, options.reverse_merge(:href => asset_path(:css, source))) + }.join("\n").html_safe + end + + ## + # Returns an html script tag for each of the sources provided. + # You can pass in the filename without extension or a symbol and we search it in your +appname.public_folder+ + # like app/public/javascript for inclusion. You can provide also a full path. + # + # @overload javascript_include_tag(*sources, options={}) + # @param [Array] sources Splat of js source paths + # @param [Hash] options The html options for the script tag + # + # @return [String] Script tag for +sources+ with specified +options+. + # + # @example + # javascript_include_tag 'application', :extjs + # + def javascript_include_tag(*sources) + options = sources.extract_options!.symbolize_keys + options.reverse_merge!(:type => 'text/javascript') + sources.flatten.map { |source| + content_tag(:script, nil, options.reverse_merge(:src => asset_path(:js, source))) + }.join("\n").html_safe + end + + ## + # Returns the path to the image, either relative or absolute. We search it in your +appname.public_folder+ + # like app/public/images for inclusion. You can provide also a full path. + # + # @param [String] src + # The path to the image file (relative or absolute). + # + # @return [String] Path to an image given the +kind+ and +source+. + # + # @example + # # Generates: /images/foo.jpg?1269008689 + # image_path("foo.jpg") + # + # @api public + def image_path(src) + asset_path(:images, src) + end + + ## + # Returns the path to the specified asset (css or javascript). + # + # @param [String] kind + # The kind of asset (i.e :images, :js, :css). + # @param [String] source + # The path to the asset (relative or absolute). + # + # @return [String] Path for the asset given the +kind+ and +source+. + # + # @example + # # Generates: /javascripts/application.js?1269008689 + # asset_path :js, :application + # + # # Generates: /stylesheets/application.css?1269008689 + # asset_path :css, :application + # + # # Generates: /images/example.jpg?1269008689 + # asset_path :images, 'example.jpg' + # + def asset_path(kind, source) + source = asset_normalize_extension(kind, URI.escape(source.to_s)) + return source if source =~ ABSOLUTE_URL_PATTERN || source =~ /^\// # absolute source + source = File.join(asset_folder_name(kind), source) + timestamp = asset_timestamp(source) + result_path = uri_root_path(source) + "#{result_path}#{timestamp}" + end + + private + ## + # Returns the URI root of the application with optional paths appended. + # + # @example + # uri_root_path("/some/path") => "/root/some/path" + # uri_root_path("javascripts", "test.js") => "/uri/root/javascripts/test.js" + # + def uri_root_path(*paths) + root_uri = self.class.uri_root if self.class.respond_to?(:uri_root) + File.join(ENV['RACK_BASE_URI'].to_s, root_uri || '/', *paths) + end + + ## + # Returns the timestamp mtime for an asset. + # + # @example + # asset_timestamp("some/path/to/file.png") => "?154543678" + # + def asset_timestamp(file_path) + return nil if file_path =~ /\?/ || (self.class.respond_to?(:asset_stamp) && !self.class.asset_stamp) + public_path = self.class.public_folder if self.class.respond_to?(:public_folder) + public_path ||= Padrino.root("public") if Padrino.respond_to?(:root) + public_file_path = File.join(public_path, file_path) if public_path + stamp = File.mtime(public_file_path).to_i if public_file_path && File.exist?(public_file_path) + stamp ||= Time.now.to_i + "?#{stamp}" + end + + ### + # Returns the asset folder given a kind. + # + # @example + # asset_folder_name(:css) => 'stylesheets' + # asset_folder_name(:js) => 'javascripts' + # asset_folder_name(:images) => 'images' + # + def asset_folder_name(kind) + case kind + when :css then 'stylesheets' + when :js then 'javascripts' + else kind.to_s + end + end + + ## + # Normalizes the extension for a given asset. + # + # @example + # + # asset_normalize_extension(:images, "/foo/bar/baz.png") => "/foo/bar/baz.png" + # asset_normalize_extension(:js, "/foo/bar/baz") => "/foo/bar/baz.js" + # + def asset_normalize_extension(kind, source) + ignore_extension = !APPEND_ASSET_EXTENSIONS.include?(kind.to_s) + source << ".#{kind}" unless ignore_extension || source =~ /\.#{kind}/ || source =~ ABSOLUTE_URL_PATTERN + source + end + + ## + # Parses link_to options for given correct conditions. + # + # @example + # parse_conditions("/some/url", :if => false) => true + # + def parse_conditions(url, options) + if options.has_key?(:if) + condition = options.delete(:if) + condition == :current ? url == request.path_info : condition + elsif condition = options.delete(:unless) + condition == :current ? url != request.path_info : !condition + else + true + end + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/breadcrumb_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/breadcrumb_helpers.rb new file mode 100644 index 00000000..dc0785f1 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/breadcrumb_helpers.rb @@ -0,0 +1,183 @@ +module Padrino + module Helpers + class Breadcrumb + attr_accessor :home, :items + + DEFAULT_URL = "/" + DEFAULT_CAPTION ="Home Page" + + ## + # Initialize breadcrumbs with default value. + # + # @example + # before do + # @breadcrumbs = breadcrumbs.new + # end + # + def initialize + reset! + end + + ## + # Set the custom home (Parent) link. + # + # @param [String] url + # The url href. + # + # @param [String] caption + # The text caption. + # + # @param [Hash] options + # The HTML options to include in li. + # + # @example + # breadcrumbs.set_home "/HomeFoo", "Foo Home", :id => "home-breadcrumb" + # + def set_home(url, caption, options = {}) + self.home = { + :url => url.to_s, + :caption => caption.to_s.humanize.html_safe, + :name => :home, + :options => options + } + reset + end + + ## + # Reset breadcrumbs to default or personal home. + # + # @example + # breadcrumbs.reset + # + def reset + self.items = [] + self.items << home + end + + ## + # Reset breadcrumbs to default home. + # + # @example + # breadcrumbs.reset! + # + def reset! + self.home = { + :name => :home, + :url => DEFAULT_URL, + :caption => DEFAULT_CAPTION, + :options => {} + } + reset + end + + ## + # Add a new breadcrumbs. + # + # @param [String] name + # The name of resource. + # @param [Symbol] name + # The name of resource. + # + # @param [String] url + # The url href. + # + # @param [String] caption + # The text caption. + # + # @param [Hash] options + # The HTML options to include in li. + # + # @example + # breadcrumbs.add "foo", "/foo", "Foo Link", :id => "foo-id" + # breadcrumbs.add :foo, "/foo", "Foo Link", :class => "foo-class" + # + def add(name, url, caption, options = {}) + items << { + :name => name.to_sym, + :url => url.to_s, + :caption => caption.to_s.humanize.html_safe, + :options => options + } + end + alias :<< :add + + ## + # Remove a breadcrumb. + # + # @param [String] name + # The name of resource to delete from breadcrumbs list. + # + # @example + # breadcrumbs.del "foo" + # breadcrumbs.del :foo + # + def del(name) + items.delete_if { |item| item[:name] == name.to_sym } + end + end + + module Breadcrumbs + ## + # Render breadcrumbs to view. + # + # @param [Breadcrumbs] breadcrumbs + # The breadcrumbs to render into view. + # + # @param [Boolean] bootstrap + # If true, render separation (useful with Twitter Bootstrap). + # + # @param [String] active + # CSS class style set to active breadcrumb. + # + # @param [Hash] options + # The HTML options to include in ul. + # + # @return [String] Unordered list with breadcrumbs + # + # @example + # = breadcrumbs @breacrumbs + # # Generates: + # # + # + def breadcrumbs(breadcrumbs, bootstrap = false, active = "active", options = {}) + content = "" + breadcrumbs.items[0..-2].each do |item| + content << render_item(item, bootstrap) + end + last = breadcrumbs.items.last + last_options = last[:options] + last = link_to(last[:caption], last[:url]) + + classes = [options[:class], last_options[:class]].map { |class_name| class_name.to_s.split(/\s/) } + classes[0] << "breadcrumb" + classes[1] << active if active + options[:class], last_options[:class] = classes.map { |class_name| class_name * " " } + + content << safe_content_tag(:li, last, last_options) + safe_content_tag(:ul, content, options) + end + + private + ## + # Private method to return list item. + # + # @param [Hash] item + # The breadcrumb item. + # + # @param [Boolean] bootstrap + # If true, render separation (useful with Twitter Bootstrap). + # + # @return [String] List item with breadcrumb + # + def render_item(item, bootstrap) + content = "" + content << link_to(item[:caption], item[:url]) + content << safe_content_tag(:span, "/", :class => "divider") if bootstrap + safe_content_tag(:li, content, item[:options]) + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/form_builder/abstract_form_builder.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/form_builder/abstract_form_builder.rb new file mode 100644 index 00000000..efbf1c30 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/form_builder/abstract_form_builder.rb @@ -0,0 +1,317 @@ +module Padrino + module Helpers + module FormBuilder + class AbstractFormBuilder + attr_accessor :template, :object, :multipart + + def initialize(template, object, options={}) + @template = template + @object = build_object(object) + @options = options + raise "FormBuilder template must be initialized!" unless template + raise "FormBuilder object must not be a nil value. If there's no object, use a symbol instead! (i.e :user)" unless object + end + + def error_messages(*params) + params.unshift object + @template.error_messages_for(*params) + end + + def error_message_on(field, options={}) + @template.error_message_on(object, field, options) + end + + def label(field, options={}, &block) + options.reverse_merge!(:caption => "#{field_human_name(field)}: ") + @template.label_tag(field_id(field), options, &block) + end + + def hidden_field(field, options={}) + options.reverse_merge!(:value => field_value(field), :id => field_id(field)) + @template.hidden_field_tag field_name(field), options + end + + def text_field(field, options={}) + options.reverse_merge!(:value => field_value(field), :id => field_id(field)) + options.merge!(:class => field_error(field, options)) + @template.text_field_tag field_name(field), options + end + + def number_field(field, options={}) + options.reverse_merge!(:value => field_value(field), :id => field_id(field)) + options.merge!(:class => field_error(field, options)) + @template.number_field_tag field_name(field), options + end + + def telephone_field(field, options={}) + options.reverse_merge!(:value => field_value(field), :id => field_id(field)) + options.merge!(:class => field_error(field, options)) + @template.telephone_field_tag field_name(field), options + end + alias_method :phone_field, :telephone_field + + def email_field(field, options={}) + options.reverse_merge!(:value => field_value(field), :id => field_id(field)) + options.merge!(:class => field_error(field, options)) + @template.email_field_tag field_name(field), options + end + + def search_field(field, options={}) + options.reverse_merge!(:value => field_value(field), :id => field_id(field)) + options.merge!(:class => field_error(field, options)) + @template.search_field_tag field_name(field), options + end + + def url_field(field, options={}) + options.reverse_merge!(:value => field_value(field), :id => field_id(field)) + options.merge!(:class => field_error(field, options)) + @template.url_field_tag field_name(field), options + end + + def text_area(field, options={}) + options.reverse_merge!(:value => field_value(field), :id => field_id(field)) + options.merge!(:class => field_error(field, options)) + @template.text_area_tag field_name(field), options + end + + def password_field(field, options={}) + options.reverse_merge!(:value => field_value(field), :id => field_id(field)) + options.merge!(:class => field_error(field, options)) + @template.password_field_tag field_name(field), options + end + + def select(field, options={}) + options.reverse_merge!(:id => field_id(field), :selected => field_value(field)) + options.merge!(:class => field_error(field, options)) + @template.select_tag field_name(field), options + end + + def check_box_group(field, options={}) + selected_values = Array(options[:selected] || field_value(field)) + if options[:collection] + fields = options[:fields] || [:name, :id] + selected_values = selected_values.map{ |v| (v.respond_to?(fields[0]) ? v.send(fields[1]) : v).to_s } + end + labeled_group( field, options ) do |variant| + @template.check_box_tag( field_name(field)+'[]', :value => variant[1], :id => variant[2], :checked => selected_values.include?(variant[1]) ) + end + end + + def radio_button_group(field, options={}) + fields = options[:fields] || [:name, :id] + selected_value = options[:selected] || field_value(field) + selected_value = selected_value.send(fields[1]) if selected_value.respond_to?(fields[0]) + labeled_group( field, options ) do |variant| + @template.radio_button_tag( field_name(field), :value => variant[1], :id => variant[2], :checked => variant[1] == selected_value.to_s ) + end + end + + def check_box(field, options={}) + html = ActiveSupport::SafeBuffer.new + unchecked_value = options.delete(:uncheck_value) || '0' + options.reverse_merge!(:id => field_id(field), :value => '1') + options.reverse_merge!(:checked => true) if values_matches_field?(field, options[:value]) + html << @template.hidden_field_tag(options[:name] || field_name(field), :value => unchecked_value, :id => nil) + html << @template.check_box_tag(field_name(field), options) + end + + def radio_button(field, options={}) + options.reverse_merge!(:id => field_id(field, options[:value])) + options.reverse_merge!(:checked => true) if values_matches_field?(field, options[:value]) + @template.radio_button_tag field_name(field), options + end + + def file_field(field, options={}) + self.multipart = true + options.reverse_merge!(:id => field_id(field)) + options.merge!(:class => field_error(field, options)) + @template.file_field_tag field_name(field), options + end + + def submit(*args) + options = args[-1].is_a?(Hash) ? args.pop : {} + caption = args.length >= 1 ? args.shift : "Submit" + @template.submit_tag caption, options + end + + def image_submit(source, options={}) + @template.image_submit_tag source, options + end + + ## + # Supports nested fields for a child model within a form. + # f.fields_for :addresses + # f.fields_for :addresses, address + # f.fields_for :addresses, @addresses + def fields_for(child_association, instance_or_collection=nil, &block) + default_collection = self.object.send(child_association) + include_index = default_collection.respond_to?(:each) + nested_options = { :parent => self, :association => child_association } + nested_objects = instance_or_collection ? Array(instance_or_collection) : Array(default_collection) + nested_objects.each_with_index.map do |child_instance, index| + nested_options[:index] = include_index ? index : nil + @template.fields_for(child_instance, { :nested => nested_options }, &block) + end.join("\n").html_safe + end + + def csrf_token_field + @template.csrf_token_field + end + + protected + # Returns the known field types for a Formbuilder. + def self.field_types + [:hidden_field, :text_field, :text_area, :password_field, :file_field, :radio_button, :check_box, :select] + end + + ## + # Returns true if the value matches the value in the field. + # field_has_value?(:gender, 'male') + def values_matches_field?(field, value) + value.present? && (field_value(field).to_s == value.to_s || field_value(field).to_s == 'true') + end + + ## + # Add a :invalid css class to the field if it contain an error. + # + def field_error(field, options) + error = @object.errors[field] rescue nil + error.blank? ? options[:class] : [options[:class], :invalid].flatten.compact.join(" ") + end + + ## + # Returns the human name of the field. Look that use builtin I18n. + # + def field_human_name(field) + I18n.translate("#{object_model_name}.attributes.#{field}", :count => 1, :default => field.to_s.humanize, :scope => :models) + end + + ## + # Returns the name for the given field. + # field_name(:username) => "user[username]" + # field_name(:number) => "user[telephone_attributes][number]" + # field_name(:street) => "user[addresses_attributes][0][street]" + def field_name(field=nil) + result = field_result + result << field_name_fragment if nested_form? + result << "[#{field}]" unless field.blank? + result.flatten.join + end + + ## + # Returns the id for the given field. + # field_id(:username) => "user_username" + # field_id(:gender, :male) => "user_gender_male" + # field_name(:number) => "user_telephone_attributes_number" + # field_name(:street) => "user_addresses_attributes_0_street" + def field_id(field=nil, value=nil) + result = [] + result << "#{@options[:namespace]}_" if @options[:namespace] && root_form? + result << field_result + result << field_id_fragment if nested_form? + result << "_#{field}" unless field.blank? + result << "_#{value}" unless value.blank? + result.flatten.join + end + + ## + # Returns the child object if it exists. + # + def nested_object_id + nested_form? && object.respond_to?(:new_record?) && !object.new_record? && object.id + end + + ## + # Returns true if this form object is nested in a parent form. + # + def nested_form? + @options[:nested] && @options[:nested][:parent] && @options[:nested][:parent].respond_to?(:object) + end + + ## + # Returns the value for the object's field. + # + def field_value(field) + @object && @object.respond_to?(field) ? @object.send(field) : "" + end + + ## + # Returns a new record of the type specified in the object + # + def build_object(object_or_symbol) + object_or_symbol.is_a?(Symbol) ? @template.instance_variable_get("@#{object_or_symbol}") || object_class(object_or_symbol).new : object_or_symbol + end + + ## + # Returns the object's models name. + # + def object_model_name(explicit_object=object) + explicit_object.is_a?(Symbol) ? explicit_object : explicit_object.class.to_s.underscore.gsub(/\//, '_') + end + + ## + # Returns the class type for the given object. + # + def object_class(explicit_object) + explicit_object.is_a?(Symbol) ? explicit_object.to_s.camelize.constantize : explicit_object.class + end + + ## + # Returns true if this form is the top-level (not nested). + # + def root_form? + !nested_form? + end + + ## + # Builds a group of labels for radios or checkboxes. + # + def labeled_group(field, options={}) + options.reverse_merge!(:id => field_id(field), :selected => field_value(field)) + options.merge!(:class => field_error(field, options)) + variants = case + when options[:options] + options[:options].map{ |caption, value| [caption.to_s, (value||caption).to_s] } + when options[:collection] + fields = options[:fields] || [:name, :id] + options[:collection].map{ |variant| [variant.send(fields.first).to_s, variant.send(fields.last).to_s] } + else + [] + end + variants.inject(''.html_safe) do |html, variant| + variant[2] = "#{field_id(field)}_#{variant[1]}" + html << @template.label_tag("#{field_name(field)}[]", :for => variant[2], :caption => "#{yield(variant)} #{variant[0]}") + end + end + + private + + def field_result + result = [] + result << object_model_name if root_form? + result + end + + def field_name_fragment + fragment = [result_options[:parent_form].field_name, "[#{result_options[:attributes_name]}", "]"] + fragment.insert(2, "][#{result_options[:nested_index]}") if result_options[:nested_index] + fragment + end + + def field_id_fragment + fragment = [result_options[:parent_form].field_id, "_#{result_options[:attributes_name]}"] + fragment.push("_#{result_options[:nested_index]}") if result_options[:nested_index] + fragment + end + + def result_options + { + :parent_form => @options[:nested][:parent], + :nested_index => @options[:nested][:index], + :attributes_name => "#{@options[:nested][:association]}_attributes" + } + end + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/form_builder/standard_form_builder.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/form_builder/standard_form_builder.rb new file mode 100644 index 00000000..3078a36f --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/form_builder/standard_form_builder.rb @@ -0,0 +1,40 @@ +require File.expand_path(File.dirname(__FILE__) + '/abstract_form_builder') unless defined?(AbstractFormBuilder) + +module Padrino + module Helpers + module FormBuilder + class StandardFormBuilder < AbstractFormBuilder + ## + # StandardFormBuilder + # + # text_field_block(:username, { :class => 'long' }, { :class => 'wide-label' }) + # text_area_block(:summary, { :class => 'long' }, { :class => 'wide-label' }) + # password_field_block(:password, { :class => 'long' }, { :class => 'wide-label' }) + # file_field_block(:photo, { :class => 'long' }, { :class => 'wide-label' }) + # check_box_block(:remember_me, { :class => 'long' }, { :class => 'wide-label' }) + # select_block(:color, :options => ['green', 'black']) + # + (self.field_types - [ :hidden_field, :radio_button ]).each do |field_type| + class_eval <<-EOF + def #{field_type}_block(field, options={}, label_options={}) + label_options.reverse_merge!(:caption => options.delete(:caption)) if options[:caption] + field_html = label(field, label_options) + field_html << #{field_type}(field, options) + @template.content_tag(:p, field_html) + end + EOF + end + + def submit_block(caption, options={}) + submit_html = self.submit(caption, options) + @template.content_tag(:p, submit_html) + end + + def image_submit_block(source, options={}) + submit_html = self.image_submit(source, options) + @template.content_tag(:p, submit_html) + end + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/form_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/form_helpers.rb new file mode 100644 index 00000000..2f39ed27 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/form_helpers.rb @@ -0,0 +1,919 @@ +require 'securerandom' + +module Padrino + module Helpers + ## + # Helpers related to producing form related tags and inputs into templates. + # + module FormHelpers + ## + # Constructs a form for object using given or default form_builder. + # + # @param [Object] object + # The object for which the form is being built. + # @param [String] URL + # The url this form will submit to. + # @param [Hash] settings + # The settings associated with this form. + # Accepts a :namespace option that will be prepended to the id attributes of the form's elements. + # Also accepts HTML options. + # @option settings [String] :builder ("StandardFormBuilder") + # The FormBuilder class to use such as StandardFormBuilder. + # @param [Proc] block + # The fields and content inside this form. + # + # @yield [AbstractFormBuilder] The form builder used to compose fields. + # + # @return [String] The html object-backed form with the specified options and input fields. + # + # @example + # form_for :user, '/register' do |f| ... end + # form_for @user, '/register', :id => 'register' do |f| ... end + # + def form_for(object, url, settings={}, &block) + instance = builder_instance(object, settings) + html = capture_html(instance, &block) + settings[:multipart] = instance.multipart unless settings.include?(:multipart) + settings.delete(:namespace) + form_tag(url, settings) { html } + end + + ## + # Constructs form fields for an object using given or default form_builder. + # Used within an existing form to allow alternate objects within one form. + # + # @param [Object] object + # The object for which the fields are being built. + # @param [Hash] settings + # The settings associated with these fields. Accepts HTML options. + # @param [Proc] block + # The content inside this set of fields. + # + # @return [String] The html fields with the specified options. + # + # @example + # fields_for @user.assignment do |assignment| ... end + # fields_for :assignment do |assigment| ... end + # + def fields_for(object, settings={}, &block) + instance = builder_instance(object, settings) + fields_html = capture_html(instance, &block) + fields_html << instance.hidden_field(:id) if instance.send(:nested_object_id) + concat_safe_content fields_html + end + + ## + # Constructs a form without object based on options. + # + # @param [String] url + # The URL this form will submit to. + # @param [Hash] options + # The html options associated with this form. + # @param [Proc] block + # The fields and content inside this form. + # + # @return [String] The HTML form with the specified options and input fields. + # + # @example + # form_tag '/register', :class => "registration_form" do ... end + # + def form_tag(url, options={}, &block) + desired_method = options[:method].to_s + options.delete(:method) unless desired_method =~ /get|post/i + options.reverse_merge!(:method => 'post', + :action => url, + :protect_from_csrf => is_protected_from_csrf? ) + options[:enctype] = 'multipart/form-data' if options.delete(:multipart) + options['accept-charset'] ||= 'UTF-8' + inner_form_html = hidden_form_method_field(desired_method) + if options[:protect_from_csrf] == true && !(desired_method =~ /get/i) + inner_form_html << csrf_token_field + end + inner_form_html << mark_safe(capture_html(&block)) + not_concat = options.delete(:not_concat) + form_html = content_tag(:form, inner_form_html, options) + not_concat ? form_html : concat_content(form_html) + end + + ## + # Returns the hidden method field for 'put' and 'delete' forms. + # Only 'get' and 'post' are allowed within browsers; + # 'put' and 'delete' are just specified using hidden fields with form action still 'put'. + # + # @param [String] desired_method + # The method this hidden field represents (i.e put or delete). + # + # @return [String] The hidden field representing the +desired_method+ for the form. + # + # @example + # # Generate: + # hidden_form_method_field('delete') + # + def hidden_form_method_field(desired_method) + return ActiveSupport::SafeBuffer.new if desired_method.blank? || desired_method.to_s =~ /get|post/i + hidden_field_tag(:_method, :value => desired_method) + end + + ## + # Constructs a field_set to group fields with given options. + # + # @overload field_set_tag(legend=nil, options={}, &block) + # @param [String] legend The legend caption for the fieldset + # @param [Hash] options The html options for the fieldset. + # @param [Proc] block The content inside the fieldset. + # @overload field_set_tag(options={}, &block) + # @param [Hash] options The html options for the fieldset. + # @param [Proc] block The content inside the fieldset. + # + # @return [String] The html for the fieldset tag based on given +options+. + # + # @example + # field_set_tag(:class => "office-set") { } + # field_set_tag("Office", :class => 'office-set') { } + # + def field_set_tag(*args, &block) + options = args.extract_options! + legend_text = args[0].is_a?(String) ? args.first : nil + legend_html = legend_text.blank? ? ActiveSupport::SafeBuffer.new : content_tag(:legend, legend_text) + field_set_content = legend_html + mark_safe(capture_html(&block)) + concat_content content_tag(:fieldset, field_set_content, options) + end + + ## + # Constructs list HTML for the errors for a given symbol. + # + # @overload error_messages_for(*objects, options = {}) + # @param [Array] object Splat of objects to display errors for. + # @param [Hash] options Error message display options. + # @option options [String] :header_tag ("h2") + # Used for the header of the error div. + # @option options [String] :id ("field-errors") + # The id of the error div. + # @option options [String] :class ("field-errors") + # The class of the error div. + # @option options [Array] :object + # The object (or array of objects) for which to display errors, + # if you need to escape the instance variable convention. + # @option options [String] :object_name + # The object name to use in the header, or any text that you prefer. + # If +:object_name+ is not set, the name of the first object will be used. + # @option options [String] :header_message ("X errors prohibited this object from being saved") + # The message in the header of the error div. Pass +nil+ or an empty string + # to avoid the header message altogether. + # @option options [String] :message ("There were problems with the following fields:") + # The explanation message after the header message and before + # the error list. Pass +nil+ or an empty string to avoid the explanation message + # altogether. + # + # @return [String] The html section with all errors for the specified +objects+ + # + # @example + # error_messages_for :user + # + def error_messages_for(*objects) + options = objects.extract_options!.symbolize_keys + objects = objects.map { |object_name| + object_name.is_a?(Symbol) ? instance_variable_get("@#{object_name}") : object_name + }.compact + count = objects.inject(0) { |sum, object| sum + object.errors.count } + + unless count.zero? + html = {} + [:id, :class, :style].each do |key| + if options.include?(key) + value = options[key] + html[key] = value unless value.blank? + else + html[key] = 'field-errors' unless key == :style + end + end + + options[:object_name] ||= objects.first.class.to_s.underscore.gsub(/\//, ' ') + + I18n.with_options :locale => options[:locale], :scope => [:models, :errors, :template] do |locale| + header_message = if options.include?(:header_message) + options[:header_message] + else + object_name = options[:object_name] + object_name = I18n.t(:name, :default => object_name.humanize, :scope => [:models, object_name], :count => 1) + locale.t :header, :count => count, :model => object_name + end + message = options.include?(:message) ? options[:message] : locale.t(:body) + error_messages = objects.map { |object| + object_name = options[:object_name] + object.errors.map { |f, msg| + field = I18n.t(f, :default => f.to_s.humanize, :scope => [:models, object_name, :attributes]) + content_tag(:li, "%s %s" % [field, msg]) + } + }.join + + contents = ActiveSupport::SafeBuffer.new + contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank? + contents << content_tag(:p, message) unless message.blank? + contents << safe_content_tag(:ul, error_messages) + + content_tag(:div, contents, html) + end + else + '' + end + end + + ## + # Returns a string containing the error message attached to the + # +method+ on the +object+ if one exists. + # + # @param [Object] object + # The object to display the error for. + # @param [Symbol] field + # The field on the +object+ to display the error for. + # @param [Hash] options + # The options to control the error display. + # @option options [String] :tag ("span") + # The tag that encloses the error. + # @option options [String] :prepend ("") + # The text to prepend before the field error. + # @option options [String] :append ("") + # The text to append after the field error. + # + # @example + # # => can't be blank + # error_message_on :post, :title + # error_message_on @post, :title + # + # # =>
can't be blank
+ # error_message_on :post, :title, :tag => :id, :class => :custom, :style => "border:1px solid red" + # + # # =>
This title can't be blank (or it won't work)
+ # error_message_on :post, :title, :prepend => "This title", :append => "(or it won't work)" + # + # @return [String] The html display of an error for a particular +object+ and +field+. + # + # @api public + def error_message_on(object, field, options={}) + object = object.is_a?(Symbol) ? instance_variable_get("@#{object}") : object + error = object.errors[field] rescue nil + error = if defined?(Ohm::Model) && object.is_a?(Ohm::Model) + I18n.t("ohm.errors.messages.#{error[0]}", :default => error[0].to_s) + else + # Array(error).first is necessary because some ORMs + # give us an array others directly a value. + Array(error)[0] + end + + if error = Array(error)[0] + options.reverse_merge!(:tag => :span, :class => :error) + tag = options.delete(:tag) + error = [options.delete(:prepend), error, options.delete(:append)].compact.join(" ") + content_tag(tag, error, options) + else + '' + end + end + + ## + # Constructs a label tag from the given options. + # + # @param [String] name + # The name of the field to label. + # @param [Hash] options + # The html options for this label. + # @option options :caption + # The caption for this label. + # @param [Proc] block + # The content to be inserted into the label. + # + # @return [String] The html for this label with the given +options+. + # + # @example + # label_tag :username, :class => 'long-label' + # label_tag :username, :class => 'long-label' do ... end + # + def label_tag(name, options={}, &block) + options.reverse_merge!(:caption => "#{name.to_s.humanize}: ", :for => name) + caption_text = options.delete(:caption).html_safe + caption_text.safe_concat "* " if options.delete(:required) + + if block_given? # label with inner content + label_content = caption_text.concat capture_html(&block) + concat_content(content_tag(:label, label_content, options)) + else # regular label + content_tag(:label, caption_text, options) + end + end + + ## + # Creates a text field input with the given name and options. + # + # @macro [new] text_field + # @param [Symbol] name + # The name of the input to create. + # @param [Hash] options + # The HTML options to include in this field. + # + # @option options [String] :id + # Specifies a unique identifier for the field. + # @option options [String] :class + # Specifies the stylesheet class of the field. + # @option options [String] :name + # Specifies the name of the field. + # @option options [String] :accesskey + # Specifies a shortcut key to access the field. + # @option options [Integer] :tabindex + # Specifies the tab order of the field. + # @option options [Integer] :maxlength + # Specifies the maximum length, in characters, of the field. + # @option options [Integer] :size + # Specifies the width, in characters, of the field. + # @option options [String] :placeholder + # Specifies a short hint that describes the expected value of the field. + # @option options [Boolean] :hidden + # Specifies whether or not the field is hidden from view. + # @option options [Boolean] :spellcheck + # Specifies whether or not the field should have it's spelling and grammar checked for errors. + # @option options [Boolean] :draggable + # Specifies whether or not the field is draggable. (true, false, :auto). + # @option options [String] :pattern + # Specifies the regular expression pattern that the field's value is checked against. + # @option options [Symbol] :autocomplete + # Specifies whether or not the field should have autocomplete enabled. (:on, :off). + # @option options [Boolean] :autofocus + # Specifies whether or not the field should automatically get focus when the page loads. + # @option options [Boolean] :required + # Specifies whether or not the field is required to be completed before the form is submitted. + # @option options [Boolean] :readonly + # Specifies whether or not the field is read only. + # @option options [Boolean] :disabled + # Specifies whether or not the field is disabled. + # + # @return [String] + # Generated HTML with specified +options+. + # + # @example + # text_field_tag :first_name, :maxlength => 40, :required => true + # # => + # + # text_field_tag :last_name, :class => 'string', :size => 40 + # # => + # + # text_field_tag :username, :placeholder => 'Your Username' + # # => + # + def text_field_tag(name, options={}) + input_tag(:text, options.reverse_merge!(:name => name)) + end + + ## + # Creates a number field input with the given name and options. + # + # @macro [new] number_field + # @param [Symbol] name + # The name of the input to create. + # @param [Hash] options + # The HTML options to include in this field. + # + # @option options [String] :id + # Specifies a unique identifier for the field. + # @option options [String] :class + # Specifies the stylesheet class of the field. + # @option options [String] :name + # Specifies the name of the field. + # @option options [String] :accesskey + # Specifies a shortcut key to access the field. + # @option options [Integer] :tabindex + # Specifies the tab order of the field. + # @option options [Integer] :min + # Specifies the minimum value of the field. + # @option options [Integer] :max + # Specifies the maximum value of the field. + # @option options [Integer] :step + # Specifies the legal number intervals of the field. + # @option options [Boolean] :hidden + # Specifies whether or not the field is hidden from view. + # @option options [Boolean] :spellcheck + # Specifies whether or not the field should have it's spelling and grammar checked for errors. + # @option options [Boolean] :draggable + # Specifies whether or not the field is draggable. (true, false, :auto). + # @option options [String] :pattern + # Specifies the regular expression pattern that the field's value is checked against. + # @option options [Symbol] :autocomplete + # Specifies whether or not the field should have autocomplete enabled. (:on, :off). + # @option options [Boolean] :autofocus + # Specifies whether or not the field should automatically get focus when the page loads. + # @option options [Boolean] :required + # Specifies whether or not the field is required to be completeled before the form is submitted. + # @option options [Boolean] :readonly + # Specifies whether or not the field is read only. + # @option options [Boolean] :disabled + # Specifies whether or not the field is disabled. + # + # @return [String] + # Generated HTML with specified +options+. + # + # @example + # number_field_tag :quantity, :class => 'numeric' + # # => + # + # number_field_tag :zip_code, :pattern => /[0-9]{5}/ + # # => + # + # number_field_tag :credit_card, :autocomplete => :off + # # => + # + # number_field_tag :age, :min => 18, :max => 120, :step => 1 + # # => + # + def number_field_tag(name, options={}) + input_tag(:number, options.reverse_merge(:name => name)) + end + + ## + # Creates a telephone field input with the given name and options. + # + # @macro text_field + # + # @example + # telephone_field_tag :phone_number, :class => 'string' + # # => + # + # telephone_field_tag :cell_phone, :tabindex => 1 + # telephone_field_tag :work_phone, :tabindex => 2 + # telephone_field_tag :home_phone, :tabindex => 3 + # + # # => + # # => + # # => + # + def telephone_field_tag(name, options={}) + input_tag(:tel, options.reverse_merge(:name => name)) + end + alias_method :phone_field_tag, :telephone_field_tag + + ## + # Creates an email field input with the given name and options. + # + # @macro text_field + # + # @example + # email_field_tag :email, :placeholder => 'you@example.com' + # # => + # + # email_field_tag :email, :value => 'padrinorb@gmail.com', :readonly => true + # # => + # + def email_field_tag(name, options={}) + input_tag(:email, options.reverse_merge(:name => name)) + end + + ## + # Creates a search field input with the given name and options. + # + # @macro text_field + # + # @example + # search_field_tag :search, :placeholder => 'Search this website...' + # # => + # + # search_field_tag :search, :maxlength => 15, :class => ['search', 'string'] + # # => + # + # search_field_tag :search, :id => 'search' + # # => + # + # search_field_tag :search, :autofocus => true + # # => + # + def search_field_tag(name, options={}) + input_tag(:search, options.reverse_merge(:name => name)) + end + + ## + # Creates a URL field input with the given name and options. + # + # @macro text_field + # + # @example + # url_field_tag :favorite_website, :placeholder => 'http://padrinorb.com' + # + # + # url_field_tag :home_page, :class => 'string url' + # + # + def url_field_tag(name, options={}) + input_tag(:url, options.reverse_merge(:name => name)) + end + + ## + # Constructs a hidden field input from the given options. + # + # @example + # hidden_field_tag :session_key, :value => "__secret__" + # + def hidden_field_tag(name, options={}) + options.reverse_merge!(:name => name) + input_tag(:hidden, options) + end + + ## + # Constructs a text area input from the given options. + # + # @example + # text_area_tag :username, :class => 'long', :value => "Demo?" + # + def text_area_tag(name, options={}) + options.reverse_merge!(:name => name, :rows => "", :cols => "") + content_tag(:textarea, options.delete(:value).to_s, options) + end + + ## + # Constructs a password field input from the given options. + # + # @example + # password_field_tag :password, :class => 'long' + # + # @api public + def password_field_tag(name, options={}) + options.reverse_merge!(:name => name) + input_tag(:password, options) + end + + ## + # Constructs a check_box from the given options. + # + # @example + # check_box_tag :remember_me, :value => 'Yes' + # + def check_box_tag(name, options={}) + options.reverse_merge!(:name => name, :value => '1') + input_tag(:checkbox, options) + end + + ## + # Constructs a radio_button from the given options. + # + # @example + # radio_button_tag :remember_me, :value => 'true' + # + def radio_button_tag(name, options={}) + options.reverse_merge!(:name => name) + input_tag(:radio, options) + end + + ## + # Constructs a file field input from the given options. + # + # @example + # file_field_tag :photo, :class => 'long' + # + # @api public + def file_field_tag(name, options={}) + name = "#{name}[]" if options[:multiple] + options.reverse_merge!(:name => name) + input_tag(:file, options) + end + + ## + # Constructs a select from the given options. + # + # @example + # options = [['caption', 'value'], ['Green', 'green1'], ['Blue', 'blue1'], ['Black', "black1"]] + # options = ['option', 'red', 'yellow' ] + # select_tag(:favorite_color, :options => ['red', 'yellow'], :selected => 'green1') + # select_tag(:country, :collection => @countries, :fields => [:name, :code], :include_blank => 'None') + # + # # Optgroups can be generated using :grouped_options => (Hash or nested Array) + # grouped_options = [['Friends',['Yoda',['Obiwan',1]]],['Enemies',['Palpatine',['Darth Vader',3]]]] + # grouped_options = {'Friends' => ['Yoda',['Obiwan',1]],'Enemies' => ['Palpatine',['Darth Vader',3]]} + # select_tag(:color, :grouped_options => [['warm',['red','yellow']],['cool',['blue', 'purple']]]) + # + # # Optgroups can be generated using :grouped_options => (Hash or nested Array) + # grouped_options = [['Friends',['Yoda',['Obiwan',1]]],['Enemies',['Palpatine',['Darth Vader',3]]]] + # grouped_options = {'Friends' => ['Yoda',['Obiwan',1]],'Enemies' => ['Palpatine',['Darth Vader',3]]} + # select_tag(:color, :grouped_options => [['warm',['red','yellow']],['cool',['blue', 'purple']]]) + # + # @param [String] name + # The name of the input field. + # @param [Hash] options + # The html options for the input field. + # @option options [Array] :options + # Explicit options to display in the select. Can be strings or string tuples. + # @option options [Array] :grouped_options + # List of options for each group in the select. See examples for details. + # @option options [Array] :collection + # Collection of objects used as options in the select. + # @option options [Array] :fields + # The attributes used as "label" and "value" for each +collection+ object. + # @option options [String] :selected (nil) + # The option value initially selected. + # @option options [Boolean] :include_blank (false) + # Include a blank option in the select. + # @option options [Boolean] :multiple (false) + # Allow multiple options to be selected at once. + # + # @return [String] The HTML input field based on the +options+ specified. + # + def select_tag(name, options={}) + options.reverse_merge!(:name => name) + collection, fields = options.delete(:collection), options.delete(:fields) + options[:options] = options_from_collection(collection, fields) if collection + prompt = options.delete(:include_blank) + select_options_html = if options[:options] + options_for_select(options.delete(:options), options.delete(:selected)) + elsif options[:grouped_options] + grouped_options_for_select(options.delete(:grouped_options), options.delete(:selected), prompt) + end + select_options_html = select_options_html.unshift(blank_option(prompt)) if select_options_html.is_a?(Array) + options.merge!(:name => "#{options[:name]}[]") if options[:multiple] + safe_content_tag(:select, select_options_html, options) + end + + ## + # Constructs a button input from the given options. + # + # @param [String] caption + # The caption for the button. + # @param [Hash] options + # The html options for the input field. + # + # @return [String] The html button based on the +options+ specified. + # + # @example + # button_tag "Cancel", :class => 'clear' + # + def button_tag(caption, options = {}) + options.reverse_merge!(:value => caption) + input_tag(:button, options) + end + + ## + # Constructs a submit button from the given options. + # + # @param [String] caption (defaults to: +Submit+) + # The caption for the submit button. + # @param [Hash] options + # The html options for the input field. + # + # @return [String] The html submit button based on the +options+ specified. + # + # @example + # submit_tag "Create", :class => 'success' + # submit_tag :class => 'btn' + # + def submit_tag(*args) + options = args[-1].is_a?(Hash) ? args.pop : {} + caption = args.length >= 1 ? args.shift : "Submit" + options.reverse_merge!(:value => caption) + input_tag(:submit, options) + end + + ## + # Constructs a submit button from the given options. + # + # @param [String] source + # The source image path for the button. + # @param [Hash] options + # The html options for the input field. + # + # @return [String] The html image button based on the +options+ specified. + # + # @example + # submit_tag "Create", :class => 'success' + # + def image_submit_tag(source, options={}) + options.reverse_merge!(:src => image_path(source)) + input_tag(:image, options) + end + + ## + # Constructs a hidden field containing a CSRF token. + # + # @param [String] token + # The token to use. Will be read from the session by default. + # + # @return [String] The hidden field with CSRF token as value. + # + # @example + # csrf_token_field + # + def csrf_token_field(token = nil) + hidden_field_tag csrf_param, :value => csrf_token + end + + ## + # Constructs meta tags `csrf-param` and `csrf-token` with the name of the + # cross-site request forgery protection parameter and token, respectively. + # + # @return [String] The meta tags with the CSRF token and the param your app expects it in. + # + # @example + # csrf_meta_tags + # + def csrf_meta_tags + if is_protected_from_csrf? + meta_tag(csrf_param, :name => 'csrf-param') << + meta_tag(csrf_token, :name => 'csrf-token') + end + end + + ## + # Creates a form containing a single button that submits to the URL. + # + # @overload button_to(name, url, options={}) + # @param [String] caption The text caption. + # @param [String] url The url href. + # @param [Hash] options The html options. + # @overload button_to(name, options={}, &block) + # @param [String] url The url href. + # @param [Hash] options The html options. + # @param [Proc] block The button content. + # + # @option options [Boolean] :multipart + # If true, this form will support multipart encoding. + # @option options [String] :remote + # Instructs ujs handler to handle the submit as ajax. + # @option options [Symbol] :method + # Instructs ujs handler to use different http method (i.e :post, :delete). + # @option options [Hash] :submit_options + # Hash of any options, that you want to pass to submit_tag (i.e :id, :class) + # + # @return [String] Form and button html with specified +options+. + # + # @example + # button_to 'Delete', url(:accounts_destroy, :id => account), :method => :delete, :class => :form + # # Generates: + # #
+ # # + # # + # #
+ # + def button_to(*args, &block) + name, url = args[0], args[1] + options = args.extract_options! + options['data-remote'] = 'true' if options.delete(:remote) + submit_options = options.delete(:submit_options) || {} + if block_given? + form_tag(url, options, &block) + else + form_tag(url, options.merge!(:not_concat => true)) do + submit_tag(name, submit_options) + end + end + end + + ## + # Constructs a range tag from the given options. + # + # @example + # range_field_tag('ranger_with_min_max', :min => 1, :max => 50) + # range_field_tag('ranger_with_range', :range => 1..5) + # + # @param [String] name + # The name of the range field. + # @param [Hash] options + # The html options for the range field. + # @option options [Integer] :min + # The min range of the range field. + # @option options [Integer] :max + # The max range of the range field. + # @option options [range] :range + # The range, in lieu of :min and :max. See examples for details. + # @return [String] The html range field + # + def range_field_tag(name, options = {}) + options.reverse_merge!(:name => name) + if range = options.delete(:range) + options[:min], options[:max] = range.min, range.max + end + input_tag(:range, options) + end + + protected + + ## + # Returns an array of option items for a select field based on the given collection. + # + # @param [Array] fields + # fields is an array containing the fields to display from each item in the collection. + # + def options_from_collection(collection, fields) + collection.map { |item| [ item.send(fields.first), item.send(fields.last) ] } + end + + ## + # Returns the options tags for a select based on the given option items. + # + def options_for_select(option_items, selected_value=nil) + return [] if option_items.blank? + option_items.map do |caption, value, disabled| + value ||= caption + disabled ||= false + content_tag(:option, caption, :value => value, :selected => option_is_selected?(value, caption, selected_value), :disabled => disabled) + end + end + + ## + # Returns the optgroups with options tags for a select based on the given :grouped_options items. + # + def grouped_options_for_select(collection, selected=nil, prompt=false) + if collection.is_a?(Hash) + collection.map do |key, value| + # Hash format: + # {:first => [1,2,3], :second => [4,5,6]} + # or: + # {:first => [[1,2,3], {:disabled => true}], :second => [4,5,6]} + attributes_hash = value.last.is_a?(Hash) ? value.pop : nil + disabled ||= attributes_hash && attributes_hash.include?(:disabled) ? attributes_hash[:disabled] : false + content_tag :optgroup, options_for_select(value, selected), :label => key, :disabled => disabled + end + elsif collection.is_a?(Array) + # Array format: + # ["Option Label", [:option1, :option2, ...]] + # or: + # ["Option Label", [:option1, :option2, ...], true] + # the last item tells if it is disabled or not. This is keeps it backwards compatible. + collection.map do |optgroup| + disabled ||= optgroup.count > 2 ? optgroup.pop : false + content_tag :optgroup, options_for_select(optgroup.last, selected), :label => optgroup.first, :disabled => disabled + end + end + end + + ## + # Returns the blank option serving as a prompt if passed. + # + def blank_option(prompt) + return unless prompt + case prompt + when String then content_tag(:option, prompt, :value => '') + when Array then content_tag(:option, prompt.first, :value => prompt.last) + else content_tag(:option, '', :value => '') + end + end + + ## + # Returns whether the application is being protected from CSRF. Defaults to true. + # + def is_protected_from_csrf? + defined?(settings) ? settings.protect_from_csrf : true + end + + ## + # Returns the current CSRF token (based on the session). If it doesn't exist, + # it will create one and assign it to the session's `csrf` key. + # + def csrf_token + session[:csrf] ||= SecureRandom.hex(32) if defined?(session) + end + + ## + # Returns the param/field name in which your CSRF token should be expected by your + # controllers. Defaults to `authenticity_token`. + # + # Set this in your application with `set :csrf_param, :something_else`. + # + def csrf_param + defined?(settings) && settings.respond_to?(:csrf_param) ? + settings.csrf_param : :authenticity_token + end + + private + ## + # Returns the FormBuilder class to use based on all available setting sources + # If explicitly defined, returns that, otherwise returns defaults. + # + # @example + # configured_form_builder_class(nil) => StandardFormBuilder + # + def configured_form_builder_class(explicit_builder=nil) + default_builder = self.respond_to?(:settings) && self.settings.default_builder + configured_builder = explicit_builder || default_builder || 'StandardFormBuilder' + configured_builder = "Padrino::Helpers::FormBuilder::#{configured_builder}".constantize if configured_builder.is_a?(String) + configured_builder + end + + ## + # Returns an initialized builder instance for the given object and settings. + # + # @example + # builder_instance(@account, :nested => { ... }) => + # + def builder_instance(object, settings={}) + builder_class = configured_form_builder_class(settings.delete(:builder)) + builder_class.new(self, object, settings) + end + + ## + # Returns whether the option should be selected or not. + # + # @example + # option_is_selected?("red", "Red", ["red", "blue"]) => true + # option_is_selected?("red", "Red", ["green", "blue"]) => false + # + def option_is_selected?(value, caption, selected_values) + Array(selected_values).any? do |selected| + [value.to_s, caption.to_s].include?(selected.to_s) + end + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/format_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/format_helpers.rb new file mode 100644 index 00000000..534b9117 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/format_helpers.rb @@ -0,0 +1,372 @@ +# -*- coding: utf-8 -*- +module Padrino + module Helpers + ### + # Helpers related to formatting or manipulating text within templates. + # + module FormatHelpers + ## + # Returns escaped text to protect against malicious content. + # + # @param [String] text + # Unsanitized HTML string that needs to be escaped. + # + # @return [String] HTML with escaped characters. + # + # @example + # escape_html("Hey") => "<b>Hey<b;gt;" + # h("Me & Bob") => "Me & Bob" + # + def escape_html(text) + Rack::Utils.escape_html(text).html_safe + end + alias h escape_html + alias sanitize_html escape_html + + ## + # Returns escaped text to protect against malicious content. + # + # @param [String] text + # Unsanitized HTML string that needs to be escaped. + # @param [String] blank_text + # Text to return if escaped text is blank. + # + # @return [String] HTML with escaped characters or the value specified if blank. + # + # @example + # h!("Me & Bob") => "Me & Bob" + # h!("", "Whoops") => "Whoops" + # + def h!(text, blank_text = ' ') + return blank_text.html_safe if text.nil? || text.empty? + h(text) + end + + ## + # Strips all HTML tags from the html. + # + # @param [String] html + # The HTML for which to strip tags. + # + # @return [String] HTML with tags stripped. + # + # @example + # strip_tags("Hey") => "Hey" + # + def strip_tags(html) + html.gsub(/<\/?[^>]*>/, "") if html + end + + ## + # Returns text transformed into HTML using simple formatting rules. Two or more consecutive newlines(\n\n) are considered + # as a paragraph and wrapped in

or your own tags. One newline (\n) is considered as a linebreak and a
tag is appended. + # This method does not remove the newlines from the text. + # + # @param [String] text + # The simple text to be formatted. + # @param [Hash] options + # Formatting options for the text. Can accept html options for the wrapper tag. + # @option options [Symbol] :tag (p) + # The html tag to use for formatting newlines. + # + # @return [String] The text formatted as simple HTML. + # + # @example + # simple_format("hello\nworld") # => "

hello
world

" + # simple_format("hello\nworld", :tag => :div, :class => :foo) # => "
hello
world
" + # + def simple_format(text, options={}) + t = options.delete(:tag) || :p + start_tag = tag(t, options, true) + text = escape_html(text.to_s.dup) + text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n + text.gsub!(/\n\n+/, "\n\n#{start_tag}") # 2+ newline -> paragraph + text.gsub!(/([^\n]\n)(?=[^\n])/, '\1
') # 1 newline -> br + text.insert 0, start_tag + text << "" + text.html_safe + end + + ## + # Attempts to pluralize the singular word unless count is 1. If plural is supplied, it will use that when count is > 1, + # otherwise it will use inflector to determine the plural form. + # + # @param [Fixnum] count + # The count which determines pluralization. + # @param [String] singular + # The word to be pluralized if appropriate based on +count+. + # @param [String] plural + # Explicit pluralized word to be used; if not specified uses inflector. + # + # @return [String] The properly pluralized word. + # + # @example + # pluralize(2, 'person') => '2 people' + # + def pluralize(count, singular, plural = nil) + "#{count || 0} " + ((count == 1 || count == '1') ? singular : (plural || singular.pluralize)) + end + + ## + # Truncates a given text after a given :length if text is longer than :length (defaults to 30). + # The last characters will be replaced with the :omission (defaults to "…") for a total length not exceeding :length. + # + # @param [String] text + # The text to be truncated. + # @param [Hash] options + # Formatting options for the truncation. + # @option options [Fixnum] :length (30) + # The number of characters before truncation occurs. + # @option options [String] :omission ("...") + # The characters that are placed after the truncated text. + # + # @return [String] The text truncated after the given number of characters. + # + # @example + # truncate("Once upon a time in a world far far away", :length => 8) => "Once upon..." + # + def truncate(text, options={}) + options.reverse_merge!(:length => 30, :omission => "...") + if text + len = options[:length] - options[:omission].length + chars = text + (chars.length > options[:length] ? chars[0...len] + options[:omission] : text).to_s + end + end + + ## + # Truncates words of a given text after a given :length if number of words in text is more than :length (defaults to 30). + # The last words will be replaced with the :omission (defaults to "…") for a total number of words not exceeding :length. + # + # @param [String] text + # The text to be truncated. + # @param [Hash] options + # Formatting options for the truncation. + # @option options [Fixnum] :length (30) + # The number of words before truncation occurs. + # @option options [String] :omission ("...") + # The characters that are placed after the truncated text. + # + # @return [String] The text truncated after the given number of words. + # + # @example + # truncate_words("Once upon a time in a world far far away", :length => 8) => "Once upon a time in a world far..." + # + def truncate_words(text, options={}) + options.reverse_merge!(:length => 30, :omission => "...") + if text + words = text.split() + words[0..(options[:length]-1)].join(' ') + (words.length > options[:length] ? options[:omission] : '') + end + end + + ## + # Wraps the text into lines no longer than line_width width. + # This method breaks on the first whitespace character that does not exceed line_width (which is 80 by default). + # + # @overload word_wrap(text, options={}) + # @param [String] text + # The text to be wrapped. + # @param [Hash] options + # Formatting options for the wrapping. + # @option options [Fixnum] :line_width (80) + # The line width before a wrap should occur. + # + # @return [String] The text with line wraps for lines longer then +line_width+. + # + # @example + # word_wrap('Once upon a time', :line_width => 8) => "Once upon\na time" + # + def word_wrap(text, *args) + options = args.extract_options! + unless args.blank? + options[:line_width] = args[0] || 80 + end + options.reverse_merge!(:line_width => 80) + + text.split("\n").map do |line| + line.length > options[:line_width] ? line.gsub(/(.{1,#{options[:line_width]}})(\s+|$)/, "\\1\n").strip : line + end * "\n" + end + + ## + # Highlights one or more words everywhere in text by inserting it into a :highlighter string. + # + # The highlighter can be customized by passing :+highlighter+ as a single-quoted string + # with \1 where the phrase is to be inserted. + # + # @overload highlight(text, words, options={}) + # @param [String] text + # The text that will be searched. + # @param [String] words + # The words to be highlighted in the +text+. + # @param [Hash] options + # Formatting options for the highlight. + # @option options [String] :highlighter ('\1') + # The html pattern for wrapping the highlighted words. + # + # @return [String] The text with the words specified wrapped with highlighted spans. + # + # @example + # highlight('Lorem ipsum dolor sit amet', 'dolor') + # # => Lorem ipsum dolor sit amet + # + # highlight('Lorem ipsum dolor sit amet', 'dolor', :highlighter => '\1') + # # => Lorem ipsum dolor sit amet + # + def highlight(text, words, *args) + options = args.extract_options! + options.reverse_merge!(:highlighter => '\1') + + if text.blank? || words.blank? + text + else + match = Array(words).map { |p| Regexp.escape(p) }.join('|') + text.gsub(/(#{match})(?!(?:[^<]*?)(?:["'])[^<>]*>)/i, options[:highlighter]) + end + end + + ## + # Reports the approximate distance in time between two Time or Date objects or integers as seconds. + # Set +include_seconds+ to true if you want more detailed approximations when distance < 1 min, 29 secs + # Distances are reported based on the following table: + # + # 0 <-> 29 secs # => less than a minute + # 30 secs <-> 1 min, 29 secs # => 1 minute + # 1 min, 30 secs <-> 44 mins, 29 secs # => [2..44] minutes + # 44 mins, 30 secs <-> 89 mins, 29 secs # => about 1 hour + # 89 mins, 29 secs <-> 23 hrs, 59 mins, 29 secs # => about [2..24] hours + # 23 hrs, 59 mins, 29 secs <-> 47 hrs, 59 mins, 29 secs # => 1 day + # 47 hrs, 59 mins, 29 secs <-> 29 days, 23 hrs, 59 mins, 29 secs # => [2..29] days + # 29 days, 23 hrs, 59 mins, 30 secs <-> 59 days, 23 hrs, 59 mins, 29 secs # => about 1 month + # 59 days, 23 hrs, 59 mins, 30 secs <-> 1 yr minus 1 sec # => [2..12] months + # 1 yr <-> 1 yr, 3 months # => about 1 year + # 1 yr, 3 months <-> 1 yr, 9 months # => over 1 year + # 1 yr, 9 months <-> 2 yr minus 1 sec # => almost 2 years + # 2 yrs <-> max time or date # => (same rules as 1 yr) + # + # With +include_seconds+ = true and the difference < 1 minute 29 seconds: + # 0-4 secs # => less than 5 seconds + # 5-9 secs # => less than 10 seconds + # 10-19 secs # => less than 20 seconds + # 20-39 secs # => half a minute + # 40-59 secs # => less than a minute + # 60-89 secs # => 1 minute + # + # @param [Time] from_time + # The time to be compared against +to_time+ in order to approximate the distance. + # @param [Time] to_time + # The time to be compared against +from_time+ in order to approximate the distance. + # @param [Boolean] include_seconds + # Set true for more detailed approximations. + # @param [Hash] options + # Flags for the approximation. + # @option options [String] :locale + # The translation locale to be used for approximating the time. + # + # @return [String] The time formatted as a relative string. + # + # @example + # from_time = Time.now + # distance_of_time_in_words(from_time, from_time + 50.minutes) # => about 1 hour + # distance_of_time_in_words(from_time, 50.minutes.from_now) # => about 1 hour + # distance_of_time_in_words(from_time, from_time + 15.seconds) # => less than a minute + # distance_of_time_in_words(from_time, from_time + 15.seconds, true) # => less than 20 seconds + # distance_of_time_in_words(from_time, 3.years.from_now) # => about 3 years + # distance_of_time_in_words(from_time, from_time + 60.hours) # => about 3 days + # distance_of_time_in_words(from_time, from_time + 45.seconds, true) # => less than a minute + # distance_of_time_in_words(from_time, from_time - 45.seconds, true) # => less than a minute + # distance_of_time_in_words(from_time, 76.seconds.from_now) # => 1 minute + # distance_of_time_in_words(from_time, from_time + 1.year + 3.days) # => about 1 year + # distance_of_time_in_words(from_time, from_time + 3.years + 6.months) # => over 3 years + # distance_of_time_in_words(from_time, from_time + 4.years + 9.days + 30.minutes + 5.seconds) # => about 4 years + # to_time = Time.now + 6.years + 19.days + # distance_of_time_in_words(from_time, to_time, true) # => about 6 years + # distance_of_time_in_words(to_time, from_time, true) # => about 6 years + # distance_of_time_in_words(Time.now, Time.now) # => less than a minute + # + def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false, options = {}) + from_time = from_time.to_time if from_time.respond_to?(:to_time) + to_time = to_time.to_time if to_time.respond_to?(:to_time) + distance_in_minutes = (((to_time.to_i - from_time.to_i).abs)/60).round + distance_in_seconds = ((to_time.to_i - from_time.to_i).abs).round + + I18n.with_options :locale => options[:locale], :scope => :'datetime.distance_in_words' do |locale| + case distance_in_minutes + when 0..1 + return distance_in_minutes == 0 ? + locale.t(:less_than_x_minutes, :count => 1) : + locale.t(:x_minutes, :count => distance_in_minutes) unless include_seconds + + case distance_in_seconds + when 0..4 then locale.t :less_than_x_seconds, :count => 5 + when 5..9 then locale.t :less_than_x_seconds, :count => 10 + when 10..19 then locale.t :less_than_x_seconds, :count => 20 + when 20..39 then locale.t :half_a_minute + when 40..59 then locale.t :less_than_x_minutes, :count => 1 + else locale.t :x_minutes, :count => 1 + end + + when 2..44 then locale.t :x_minutes, :count => distance_in_minutes + when 45..89 then locale.t :about_x_hours, :count => 1 + when 90..1439 then locale.t :about_x_hours, :count => (distance_in_minutes.to_f / 60.0).round + when 1440..2529 then locale.t :x_days, :count => 1 + when 2530..43199 then locale.t :x_days, :count => (distance_in_minutes.to_f / 1440.0).round + when 43200..86399 then locale.t :about_x_months, :count => 1 + when 86400..525599 then locale.t :x_months, :count => (distance_in_minutes.to_f / 43200.0).round + else + distance_in_years = distance_in_minutes / 525600 + minute_offset_for_leap_year = (distance_in_years / 4) * 1440 + remainder = ((distance_in_minutes - minute_offset_for_leap_year) % 525600) + if remainder < 131400 + locale.t(:about_x_years, :count => distance_in_years) + elsif remainder < 394200 + locale.t(:over_x_years, :count => distance_in_years) + else + locale.t(:almost_x_years, :count => distance_in_years + 1) + end + end + end + end + + ## + # Like distance_of_time_in_words, but where to_time is fixed to Time.now. + # + # @param [Time] from_time + # The time to be compared against now in order to approximate the distance. + # @param [Boolean] include_seconds + # Set true for more detailed approximations. + # + # @return [String] The time formatted as a relative string. + # + # @example + # time_ago_in_words(3.minutes.from_now) # => 3 minutes + # time_ago_in_words(Time.now - 15.hours) # => 15 hours + # time_ago_in_words(Time.now) # => less than a minute + # + def time_ago_in_words(from_time, include_seconds = false) + distance_of_time_in_words(from_time, Time.now, include_seconds) + end + + ## + # Used in xxxx.js.erb files to escape html so that it can be passed to javascript from Padrino. + # + # @param [String] html + # The HTML content to be escaped into javascript compatible format. + # + # @return [String] The html escaped for javascript passing. + # + # @example + # js_escape_html("

Hey

") + # + def js_escape_html(html_content) + return '' unless html_content + javascript_mapping = { '\\' => '\\\\', ' '<\/', "\r\n" => '\n', "\n" => '\n', "\r" => '\n', '"' => '\\"', "'" => "\\'" } + escaped_content = html_content.gsub(/(\\|<\/|\r\n|[\n\r"'])/){ |m| javascript_mapping[m] } + escaped_content = escaped_content.html_safe if html_content.html_safe? + escaped_content + end + alias :escape_javascript :js_escape_html + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/cs.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/cs.yml new file mode 100644 index 00000000..cedcd25f --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/cs.yml @@ -0,0 +1,103 @@ +cs: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "," + # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: " " + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 3 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%n %u" + unit: "Kč" + # These three are to override number.format and are optional. + separator: "," + delimiter: " " + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision() + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB) + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "půl minutou" + less_than_x_seconds: + one: "asi před sekundou" + other: "asi před %{count} sekundami" + x_seconds: + one: "sekundou" + other: "%{count} sekundami" + less_than_x_minutes: + one: "před necelou minutou" + other: "před ani ne %{count} minutami" + x_minutes: + one: "minutou" + other: "%{count} minutami" + about_x_hours: + one: "asi hodinou" + other: "asi %{count} hodinami" + x_days: + one: "24 hodinami" + other: "%{count} dny" + about_x_months: + one: "asi měsícem" + other: "asi %{count} měsíci" + x_months: + one: "měsícem" + other: "%{count} měsíci" + about_x_years: + one: "asi rokem" + other: "asi %{count} roky" + over_x_years: + one: "více než před rokem" + other: "více než %{count} roky" + almost_x_years: + one: "skoro rokem" + other: "almost %{count} roků" + models: + errors: + template: + header: + one: "Při ukládání %{model} došlo k chybě a nebylo jej možné uložit" + other: "Při ukládání %{model} došlo ke %{count} chybám a nebylo možné jej uložit" + body: "Následující pole obsahují chybně vyplněné údaje:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/da.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/da.yml new file mode 100644 index 00000000..3cda2456 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/da.yml @@ -0,0 +1,91 @@ +da: + number: + format: + separator: "," + delimiter: "." + precision: 3 + currency: + format: + format: "%u %n" + unit: "DKK" + separator: "," + delimiter: "." + precision: 2 + precision: + format: + # separator: + delimiter: "" + # precision: + human: + format: + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + percentage: + format: + # separator: + delimiter: "" + # precision: + + datetime: + distance_in_words: + half_a_minute: "et halvt minut" + less_than_x_seconds: + one: "mindre end et sekund" + other: "mindre end %{count} sekunder" + x_seconds: + one: "et sekund" + other: "%{count} sekunder" + less_than_x_minutes: + one: "mindre end et minut" + other: "mindre end %{count} minutter" + x_minutes: + one: "et minut" + other: "%{count} minutter" + about_x_hours: + one: "cirka en time" + other: "cirka %{count} timer" + x_days: + one: "en dag" + other: "%{count} dage" + about_x_months: + one: "cirka en måned" + other: "cirka %{count} måneder" + x_months: + one: "en måned" + other: "%{count} måneder" + about_x_years: + one: "cirka et år" + other: "cirka %{count} år" + over_x_years: + one: "mere end et år" + other: "mere end %{count} år" + almost_x_years: + one: "næsten et år" + other: "næsten %{count} years" + prompts: + second: "Sekund" + minute: "Minut" + hour: "Time" + day: "Dag" + month: "Måned" + year: "År" + models: + errors: + template: + header: + one: "En fejl forhindrede %{model} i at blive gemt" + other: "%{count} fejl forhindrede denne %{model} i at blive gemt" + body: "Der var problemer med følgende felter:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/de.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/de.yml new file mode 100644 index 00000000..a27c4f2c --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/de.yml @@ -0,0 +1,81 @@ +de: + number: + format: + precision: 2 + separator: ',' + delimiter: '.' + currency: + format: + unit: '€' + format: '%n%u' + separator: "," + delimiter: "." + precision: 2 + percentage: + format: + delimiter: "" + precision: + format: + delimiter: "" + human: + format: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + datetime: + distance_in_words: + half_a_minute: 'eine halbe Minute' + less_than_x_seconds: + zero: 'weniger als 1 Sekunde' + one: 'weniger als 1 Sekunde' + other: 'weniger als %{count} Sekunden' + x_seconds: + one: '1 Sekunde' + other: '%{count} Sekunden' + less_than_x_minutes: + zero: 'weniger als 1 Minute' + one: 'weniger als 1 Minute' + other: 'weniger als %{count} Minuten' + x_minutes: + one: '1 Minute' + other: '%{count} Minuten' + about_x_hours: + one: 'etwa 1 Stunde' + other: 'etwa %{count} Stunden' + x_days: + one: '1 Tag' + other: '%{count} Tage' + about_x_months: + one: 'etwa 1 Monat' + other: 'etwa %{count} Monate' + x_months: + one: '1 Monat' + other: '%{count} Monate' + about_x_years: + one: 'etwa 1 Jahr' + other: 'etwa %{count} Jahre' + over_x_years: + one: 'mehr als 1 Jahr' + other: 'mehr als %{count} Jahre' + almost_x_years: + one: 'fast ein Jahr' + other: 'fast %{count} Jahre' + models: + errors: + template: + header: + one: "1 Fehler verhindert, dass Objekt %{model} gesichert werden kann" + other: "%{count} Fehler verhindern, dass Objekt %{model} gesichert werden kann" + body: "Es existieren Probleme mit den folgenden Feldern:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/en.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/en.yml new file mode 100644 index 00000000..934d695c --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/en.yml @@ -0,0 +1,103 @@ +en: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "." + # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: "," + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 3 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%u%n" + unit: "$" + # These three are to override number.format and are optional. + separator: "." + delimiter: "," + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision(). + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "half a minute" + less_than_x_seconds: + one: "less than 1 second" + other: "less than %{count} seconds" + x_seconds: + one: "1 second" + other: "%{count} seconds" + less_than_x_minutes: + one: "less than a minute" + other: "less than %{count} minutes" + x_minutes: + one: "1 minute" + other: "%{count} minutes" + about_x_hours: + one: "about 1 hour" + other: "about %{count} hours" + x_days: + one: "1 day" + other: "%{count} days" + about_x_months: + one: "about 1 month" + other: "about %{count} months" + x_months: + one: "1 month" + other: "%{count} months" + about_x_years: + one: "about 1 year" + other: "about %{count} years" + over_x_years: + one: "over 1 year" + other: "over %{count} years" + almost_x_years: + one: "almost 1 year" + other: "almost %{count} years" + models: + errors: + template: + header: + one: "1 error prohibited this %{model} from being saved" + other: "%{count} errors prohibited this %{model} from being saved" + body: "There were problems with the following fields:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/es.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/es.yml new file mode 100644 index 00000000..0e6b4f5a --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/es.yml @@ -0,0 +1,103 @@ +es: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "." + # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: "," + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 2 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%u%n" + unit: "$" + # These three are to override number.format and are optional. + separator: "." + delimiter: "," + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision(). + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "medio minuto" + less_than_x_seconds: + one: "menos de un segundo" + other: "menos de %{count} segundos" + x_seconds: + one: "1 segundo" + other: "%{count} segundos" + less_than_x_minutes: + one: "menos de un minuto" + other: "menos de %{count} minutos" + x_minutes: + one: "1 minuto" + other: "%{count} minutos" + about_x_hours: + one: "hace 1 hora" + other: "hace %{count} horas" + x_days: + one: "1 día" + other: "%{count} días" + about_x_months: + one: "hace 1 mes" + other: "hace %{count} meses" + x_months: + one: "1 mes" + other: "%{count} meses" + about_x_years: + one: "hace 1 año" + other: "hace %{count} años" + over_x_years: + one: "hace más de 1 año" + other: "hace más de %{count} años" + almost_x_years: + one: "casi 1 año" + other: "casi %{count} años" + models: + errors: + template: + header: + one: "1 error impidió que %{model} se guardara" + other: "%{count} erroress impidieron que %{model} se guardara" + body: "Hay problemas con los siguientes campos:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/fr.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/fr.yml new file mode 100644 index 00000000..004f7c09 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/fr.yml @@ -0,0 +1,79 @@ +fr: + number: + format: + precision: 2 + separator: ',' + delimiter: '.' + currency: + format: + unit: '€' + format: '%n%u' + separator: "." + delimiter: "" + precision: 2 + percentage: + format: + delimiter: "" + precision: + format: + delimiter: "" + human: + format: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Octet" + other: "Octets" + kb: "Ko" + mb: "Mo" + gb: "Go" + tb: "To" + + datetime: + distance_in_words: + half_a_minute: "une demi minute" + less_than_x_seconds: + one: "inférieur à une seconde" + other: "inférieur à %{count} secondes" + x_seconds: + one: "1 seconde" + other: "%{count} secondes" + less_than_x_minutes: + one: "inférieur à 1 minute" + other: "inférieur à %{count} minutes" + x_minutes: + one: "1 minute" + other: "%{count} minutes" + about_x_hours: + one: "environ 1 heure" + other: "environ %{count} heures" + x_days: + one: "1 jour" + other: "%{count} jours" + about_x_months: + one: "environ 1 mois" + other: "environ %{count} mois" + x_months: + one: "1 mois" + other: "%{count} mois" + about_x_years: + one: "environ 1 ans" + other: "environ %{count} ans" + over_x_years: + one: "plus d'un an" + other: "plus de %{count} ans" + almost_x_years: + one: "près d'un an" + other: "près de %{count} ans" + models: + errors: + template: + header: + one: "1 erreur a empêché ce %{model} d'être sauvé" + other: "%{count} erreurs ont empêché ce %{model} d'être sauvé" + body: "Il y avait des problèmes avec les champs suivants:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/hu.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/hu.yml new file mode 100644 index 00000000..db7f19ce --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/hu.yml @@ -0,0 +1,103 @@ +hu: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "," + # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: "." + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 2 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%n %u" + unit: "Ft" + # These three are to override number.format and are optional. + separator: "," + delimiter: "." + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision(). + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "byte" + other: "byte" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "fél perc" + less_than_x_seconds: + one: "kevesebb, mint egy másodperc" + other: "kevesebb, mint %{count} másodperc" + x_seconds: + one: "1 másodperc" + other: "%{count} másodperc" + less_than_x_minutes: + one: "kevesebb, mint egy perc" + other: "kevesebb, mint %{count} perc" + x_minutes: + one: "1 perc" + other: "%{count} perc" + about_x_hours: + one: "nagyjából 1 óra" + other: "nagyjából %{count} óra" + x_days: + one: "1 nap" + other: "%{count} nap" + about_x_months: + one: "nagyjából 1 hónap" + other: "nagyjából %{count} hónap" + x_months: + one: "1 hónap" + other: "%{count} hónap" + about_x_years: + one: "nagyjából 1 év" + other: "nagyjából %{count} év" + over_x_years: + one: "több, mint 1 év" + other: "több, mint %{count} év" + almost_x_years: + one: "majdnem 1 év" + other: "majdnem %{count} év" + models: + errors: + template: + header: + one: "1 hiba akadályozza a(z) %{model} mentését" + other: "%{count} hiba akadályozza a(z) %{model} mentését" + body: "A következő mezőkkel van baj:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/it.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/it.yml new file mode 100644 index 00000000..9fcb5977 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/it.yml @@ -0,0 +1,89 @@ +it: + number: + format: + separator: "," + delimiter: "." + precision: 3 + + currency: + format: + format: "%n %u" + unit: "€" + separator: "." + delimiter: "," + precision: 2 + + percentage: + format: + delimiter: "" + # precision: + + precision: + format: + # separator: + delimiter: "" + # precision: + + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + datetime: + distance_in_words: + half_a_minute: "mezzo minuto" + less_than_x_seconds: + one: "meno di un secondo" + other: "meno di %{count} secondi" + x_seconds: + one: "1 secondo" + other: "%{count} secondi" + less_than_x_minutes: + one: "meno di un minuto" + other: "meno di %{count} minuti" + x_minutes: + one: "1 minuto" + other: "%{count} minuti" + about_x_hours: + one: "circa un'ora" + other: "circa %{count} ore" + x_days: + one: "1 giorno" + other: "%{count} giorni" + about_x_months: + one: "circa un mese" + other: "circa %{count} mesi" + x_months: + one: "1 mese" + other: "%{count} mesi" + about_x_years: + one: "circa un anno" + other: "circa %{count} anni" + over_x_years: + one: "oltre un anno" + other: "oltre %{count} anni" + almost_x_years: + one: "circa 1 anno" + other: "circa %{count} anni" + + models: + errors: + template: + header: + one: "Non posso salvare questo %{model}: 1 errore" + other: "Non posso salvare questo %{model}: %{count} errori." + body: "Per favore ricontrolla i seguenti campi:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/ja.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/ja.yml new file mode 100644 index 00000000..c16074bf --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/ja.yml @@ -0,0 +1,103 @@ +ja: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "." + # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: "," + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 2 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%u%n" + unit: "¥" + # These three are to override number.format and are optional. + separator: "." + delimiter: "," + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision(). + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "30秒" + less_than_x_seconds: + one: "1 秒以内" + other: "%{count} 秒以内" + x_seconds: + one: "1 秒" + other: "%{count} 秒" + less_than_x_minutes: + one: "1 分以内" + other: "%{count} 分以内" + x_minutes: + one: "1 分" + other: "%{count} 分" + about_x_hours: + one: "およそ 1 時間" + other: "およそ %{count} 時間" + x_days: + one: "1 日" + other: "%{count} 日" + about_x_months: + one: "およそ 1 ヶ月" + other: "およそ %{count} ヶ月" + x_months: + one: "1 ヶ月" + other: "%{count} ヶ月" + about_x_years: + one: "およそ 1 年" + other: "およそ %{count} 年" + over_x_years: + one: "1 年以上" + other: "%{count} 年以上" + almost_x_years: + one: "ほぼ 1 年" + other: "ほぼ %{count} 年" + models: + errors: + template: + header: + one: "1 つのエラーにより、 %{model} をセーブできませんでした" + other: "%{count} つのエラーにより、 %{model} をセーブできませんでした" + body: "以下のフィールドにエラーが存在します:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/lv.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/lv.yml new file mode 100644 index 00000000..199af0ef --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/lv.yml @@ -0,0 +1,103 @@ +lv: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "," + # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: "." + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 2 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%u %n" + unit: "LVL" + # These three are to override number.format and are optional. + separator: "," + delimiter: "." + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision(). + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Baits" + other: "Baiti" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "pusminūte" + less_than_x_seconds: + one: "mazāk par vienu sekundi" + other: "mazāk par %{count} sekundēm" + x_seconds: + one: "1 sekunde" + other: "%{count} sekundes" + less_than_x_minutes: + one: "mazāk par vienu minūti" + other: "mazāk par %{count} minūtēm" + x_minutes: + one: "1 minūte" + other: "%{count} minūtes" + about_x_hours: + one: "apmēram 1 stunda" + other: "apmēram %{count} stundas" + x_days: + one: "1 diena" + other: "%{count} dienas" + about_x_months: + one: "apmēram 1 mēnesis" + other: "apmēram %{count} mēneši" + x_months: + one: "1 mēnesis" + other: "%{count} mēneši" + about_x_years: + one: "apmēram 1 gads" + other: "apmēram %{count} gadi" + over_x_years: + one: "vairāk kā gads" + other: "vairāk kā %{count} gadi" + almost_x_years: + one: "gandrīz 1 gads" + other: "gandrīz %{count} gadi" + models: + errors: + template: + header: + one: "Dēļ 1 kļūdas šis %{model} netika saglabāts" + other: "Dēļ %{count} kļūdām šis %{model} netika saglabāts" + body: "Problēmas ir šajos ievades laukos:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/nl.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/nl.yml new file mode 100644 index 00000000..97223103 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/nl.yml @@ -0,0 +1,82 @@ +nl: + number: + format: + precision: 2 + separator: ',' + delimiter: '.' + currency: + format: + unit: '€' + format: '%u %n' + separator: "," + delimiter: "." + precision: 2 + percentage: + format: + delimiter: "" + precision: + format: + delimiter: "" + human: + format: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "byte" + other: "bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + datetime: + distance_in_words: + half_a_minute: "een halve minuut" + less_than_x_seconds: + one: "minder dan \xC3\xA9\xC3\xA9n seconde" + other: "minder dan %{count} seconden" + x_seconds: + one: "1 seconde" + other: "%{count} seconden" + less_than_x_minutes: + one: "minder dan \xC3\xA9\xC3\xA9n minuut" + other: "minder dan %{count} minuten" + x_minutes: + one: "1 minuut" + other: "%{count} minuten" + about_x_hours: + one: "ongeveer \xC3\xA9\xC3\xA9n uur" + other: "ongeveer %{count} uur" + x_days: + one: "1 dag" + other: "%{count} dagen" + about_x_months: + one: "ongeveer \xC3\xA9\xC3\xA9n maand" + other: "ongeveer %{count} maanden" + x_months: + one: "1 maand" + other: "%{count} maanden" + about_x_years: + one: "ongeveer \xC3\xA9\xC3\xA9n jaar" + other: "ongeveer %{count} jaar" + over_x_years: + one: "meer dan \xC3\xA9\xC3\xA9n jaar" + other: "meer dan %{count} jaar" + almost_x_years: + one: "bijna \xC3\xA9\xC3\xA9n jaar" + other: "bijna %{count} jaar" + over_x_years: + one: 'meer dan 1 jaar' + other: 'meer dan %{count} jaar' + models: + errors: + template: + header: + one: "1 fout verhindert het opslaan van dit %{model} object" + other: "%{count} fouten verhinderen het opslaan van dit %{model} object" + body: "Controleer alstublieft de volgende velden:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/no.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/no.yml new file mode 100644 index 00000000..a3561dc5 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/no.yml @@ -0,0 +1,91 @@ +"no": + number: + format: + separator: "," + delimiter: "." + precision: 3 + currency: + format: + format: "%u %n" + unit: "NOK" + separator: "," + delimiter: "." + precision: 2 + precision: + format: + # separator: + delimiter: "" + # precision: + human: + format: + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + percentage: + format: + # separator: + delimiter: "" + # precision: + + datetime: + distance_in_words: + half_a_minute: "et halvt minutt" + less_than_x_seconds: + one: "mindre enn et sekund" + other: "mindre enn %{count} sekunder" + x_seconds: + one: "ett sekund" + other: "%{count} sekunder" + less_than_x_minutes: + one: "mindre enn et minutt" + other: "mindre enn %{count} minutter" + x_minutes: + one: "ett minutt" + other: "%{count} minutter" + about_x_hours: + one: "cirka en time" + other: "cirka %{count} timer" + x_days: + one: "en dag" + other: "%{count} dager" + about_x_months: + one: "cirka en måned" + other: "cirka %{count} måneder" + x_months: + one: "en måned" + other: "%{count} måneder" + about_x_years: + one: "cirka et år" + other: "cirka %{count} år" + over_x_years: + one: "mer enn ett år" + other: "mer enn %{count} år" + almost_x_years: + one: "nesten et år" + other: "nesten %{count} år" + prompts: + second: "Sekund" + minute: "Minutt" + hour: "Time" + day: "Dag" + month: "Måned" + year: "År" + models: + errors: + template: + header: + one: "En feil forhindrer %{model} å bli lagret" + other: "%{count} feil forhindrer denne %{model} i å bli lagret" + body: "Det er problemer med følgende felter:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/pl.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/pl.yml new file mode 100644 index 00000000..ba41f491 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/pl.yml @@ -0,0 +1,95 @@ +pl: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + separator: "," + delimiter: " " + precision: 2 + + # Used in number_to_currency(). + currency: + format: + format: "%n %u" + unit: "PLN" + separator: "," + delimiter: " " + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + delimiter: "" + + # Used in number_to_precision(). + precision: + format: + delimiter: "" + + # Used in number_to_human_size(). + human: + format: + delimiter: "" + precision: 1 + storage_units: + format: "%n %u" + units: + byte: + one: "bajt" + other: "bajty" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "pół minuty" + less_than_x_seconds: + one: "mniej niż sekundę" + few: "mniej niż %{count} sekundy" + other: "mniej niż %{count} sekund" + x_seconds: + one: "sekundę" + few: "%{count} sekundy" + other: "%{count} sekund" + less_than_x_minutes: + one: "mniej niż minutę" + few: "mniej niż %{count} minuty" + other: "mniej niż %{count} minut" + x_minutes: + one: "minutę" + few: "%{count} minuty" + other: "%{count} minut" + about_x_hours: + one: "około godziny" + other: "około %{count} godzin" + x_days: + one: "1 dzień" + other: "%{count} dni" + about_x_months: + one: "około miesiąca" + other: "około %{count} miesięcy" + x_months: + one: "1 miesiąc" + few: "%{count} miesiące" + other: "%{count} miesięcy" + about_x_years: + one: "około roku" + other: "około %{count} lat" + almost_x_years: + one: "prawie rok" + few: "prawie %{count} lata" + other: "prawie %{count} lat" + over_x_years: + one: "ponad rok" + few: "ponad %{count} lata" + other: "ponad %{count} lat" + models: + errors: + template: + header: + one: "%{model} nie został zachowany z powodu jednego błędu" + other: "%{model} nie został zachowany z powodu %{count} błędów" + body: "Błędy dotyczą następujących pól:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/pt_br.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/pt_br.yml new file mode 100644 index 00000000..10bc6dc4 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/pt_br.yml @@ -0,0 +1,103 @@ +pt_br: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "," + # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: "." + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 3 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%u%n" + unit: "R$" + # These three are to override number.format and are optional. + separator: "," + delimiter: "." + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision(). + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "meio minuto" + less_than_x_seconds: + one: "menos de 1 segundo" + other: "menos de %{count} segundos" + x_seconds: + one: "1 segundo" + other: "%{count} segundos" + less_than_x_minutes: + one: "menos de 1 minuto" + other: "menos de %{count} minutos" + x_minutes: + one: "1 minuto" + other: "%{count} minutos" + about_x_hours: + one: "cerca de 1 hora" + other: "cerca de %{count} horas" + x_days: + one: "1 dia" + other: "%{count} dias" + about_x_months: + one: "cerca de 1 mês" + other: "cerca de %{count} meses" + x_months: + one: "1 mês" + other: "%{count} meses" + about_x_years: + one: "cerca de 1 ano" + other: "cerca de %{count} anos" + over_x_years: + one: "mais de 1 ano" + other: "mais de %{count} anos" + almost_x_years: + one: "quase 1 ano" + other: "quase %{count} anos" + models: + errors: + template: + header: + one: "Não posso salvar %{model}: 1 erro" + other: "Não posso salvar %{model}: %{count} erros." + body: "Por favor, verifique novamente os seguintes campos:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/ro.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/ro.yml new file mode 100644 index 00000000..0b6968da --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/ro.yml @@ -0,0 +1,103 @@ +ro: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "," + # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: "." + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 2 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%n %u" + unit: "lei" + # These three are to override number.format and are optional. + separator: "," + delimiter: "." + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision(). + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "jumătate de minut" + less_than_x_seconds: + one: "mai puțin de o secundă" + other: "mai puțin de %{count} secunde" + x_seconds: + one: "o secundă" + other: "%{count} secunde" + less_than_x_minutes: + one: "mai puțin de un minut" + other: "mai puțin de %{count} minute" + x_minutes: + one: "un minut" + other: "%{count} minute" + about_x_hours: + one: "aproximativ o oră" + other: "aproximativ %{count} ore" + x_days: + one: "o zi" + other: "%{count} zile" + about_x_months: + one: "aproximativ o lună" + other: "aproximativ %{count} luni" + x_months: + one: "o lună" + other: "%{count} luni" + about_x_years: + one: "aproximativ un an" + other: "aproximativ %{count} ani" + over_x_years: + one: "peste un an" + other: "peste %{count} ani" + almost_x_years: + one: "aproape un an" + other: "aproape %{count} ani" + models: + errors: + template: + header: + one: "Nu s-a putut salva %{model}, a avut loc o eroare." + other: "Nu s-a putut salva %{model}, au avut loc %{count} erori." + body: "Există probleme cu următoarele câmpuri:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/ru.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/ru.yml new file mode 100644 index 00000000..749d9271 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/ru.yml @@ -0,0 +1,103 @@ +ru: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "," + # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: "" + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 3 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%n %u" + unit: "руб" + # These three are to override number.format and are optional. + separator: "," + delimiter: " " + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision(). + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Байт" + other: "Байт" + kb: "Кб" + mb: "Мб" + gb: "Гб" + tb: "Тб" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "пол минуты" + less_than_x_seconds: + one: "менее секунды" + other: "менее %{count} секунд" + x_seconds: + one: "1 секунда" + other: "%{count} секунд" + less_than_x_minutes: + one: "менее минуты" + other: "менее %{count} минут" + x_minutes: + one: "1 минута" + other: "%{count} минут" + about_x_hours: + one: "около часа" + other: "около %{count} часов" + x_days: + one: "1 день" + other: "%{count} дней" + about_x_months: + one: "около месяца" + other: "около %{count} месяцев" + x_months: + one: "1 месяц" + other: "%{count} месяцев" + about_x_years: + one: "около года" + other: "около %{count} лет" + over_x_years: + one: "более года" + other: "более %{count} лет" + almost_x_years: + one: "почти год" + other: "почти %{count} года" + models: + errors: + template: + header: + one: "Данные «%{model}» не могут быть сохранены из-за 1 ошибки" + other: "Данные «%{model}» не могут быть сохранены из-за %{count} ошибок" + body: "Допущены ошибки в следующих полях:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/sv.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/sv.yml new file mode 100644 index 00000000..d0ea51f5 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/sv.yml @@ -0,0 +1,103 @@ +sv: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "," + # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: " " + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 2 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%n %u" + unit: "kr" + # These three are to override number.format and are optional. + separator: "," + delimiter: " " + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision(). + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "en halv minut" + less_than_x_seconds: + one: "mindre än 1 sekund" + other: "mindre än %{count} sekunder" + x_seconds: + one: "1 sekund" + other: "%{count} sekunder" + less_than_x_minutes: + one: "mindre än en minut" + other: "mindre än %{count} minuter" + x_minutes: + one: "1 minut" + other: "%{count} minuter" + about_x_hours: + one: "cirka 1 timme" + other: "cirka %{count} timmar" + x_days: + one: "1 dag" + other: "%{count} dagar" + about_x_months: + one: "cirka 1 månad" + other: "cirka %{count} månader" + x_months: + one: "1 månad" + other: "%{count} månader" + about_x_years: + one: "cirka 1 år" + other: "cirka %{count} år" + over_x_years: + one: "över 1 år" + other: "över %{count} år" + almost_x_years: + one: "nästan 1 år" + other: "nästan %{count} år" + models: + errors: + template: + header: + one: "1 fel hindrade denna %{model} från att sparas" + other: "%{count} fel hindrade denna %{model} från att sparas" + body: "Följande fält innehåller fel:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/tr.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/tr.yml new file mode 100644 index 00000000..10729e9b --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/tr.yml @@ -0,0 +1,103 @@ +tr: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "." + # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: "," + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 3 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%n%u" + unit: "TL" + # These three are to override number.format and are optional. + separator: "." + delimiter: "," + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision(). + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "30 saniye" + less_than_x_seconds: + one: "1 saniyeden az" + other: "%{count} saniyeden az" + x_seconds: + one: "1 saniye" + other: "%{count} saniye" + less_than_x_minutes: + one: "bir dakikadan az" + other: "%{count} dakikadan az" + x_minutes: + one: "1 dakika" + other: "%{count} dakika" + about_x_hours: + one: "yaklaşık 1 saat" + other: "yaklaşık %{count} saat" + x_days: + one: "1 gün" + other: "%{count} gün" + about_x_months: + one: "yaklaşık 1 ay" + other: "yaklaşık %{count} ay" + x_months: + one: "1 ay" + other: "%{count} ay" + about_x_years: + one: "yaklaşık 1 yıl" + other: "yaklaşık %{count} yıl" + over_x_years: + one: "1 yıldan fazla" + other: "%{count} yıldan fazla" + almost_x_years: + one: "neredeyse 1 yıl" + other: "neredeyse %{count} yıl" + models: + errors: + template: + header: + one: "1 hata oluştu; %{model} kaydedilemedi" + other: "%{count} hata oluştu; %{model} kaydedilemedi" + body: "Hata oluşan alanlar:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/uk.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/uk.yml new file mode 100644 index 00000000..3eb4b7b6 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/uk.yml @@ -0,0 +1,103 @@ +uk: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "," + # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: "" + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 3 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%n %u" + unit: "грн" + # These three are to override number.format and are optional. + separator: "," + delimiter: " " + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision(). + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Байт" + other: "Байт" + kb: "Кб" + mb: "Мб" + gb: "Гб" + tb: "Тб" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "півхвилини" + less_than_x_seconds: + one: "менше секунди" + other: "менше %{count} секунд" + x_seconds: + one: "1 секунда" + other: "%{count} секунд" + less_than_x_minutes: + one: "менше хвилини" + other: "менше %{count} хвилин" + x_minutes: + one: "1 хвилина" + other: "%{count} хвилин" + about_x_hours: + one: "близько години" + other: "близько %{count} годин" + x_days: + one: "1 день" + other: "%{count} днів" + about_x_months: + one: "близько місяця" + other: "близько %{count} місяців" + x_months: + one: "1 місяць" + other: "%{count} месяців" + about_x_years: + one: "близько року" + other: "близько %{count} років" + over_x_years: + one: "більше року" + other: "більше %{count} років" + almost_x_years: + one: "майже рік" + other: "майжу %{count} роки" + models: + errors: + template: + header: + one: "Дані «%{model}» не можуть бути збережені через 1 помилки" + other: "Дані «%{model}» не можуть бути збережені через %{count} помилок" + body: "Допущені помилки в наступних полях:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/zh_cn.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/zh_cn.yml new file mode 100644 index 00000000..02bd4919 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/zh_cn.yml @@ -0,0 +1,103 @@ +zh_cn: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "." + # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: "," + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 3 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%u%n" + unit: "RMB" + # These three are to override number.format and are optional. + separator: "." + delimiter: "," + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision(). + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "字节" + other: "字节" + kb: "K" + mb: "兆" + gb: "G" + tb: "T" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "半分钟" + less_than_x_seconds: + one: "不到一秒" + other: "不到 %{count} 秒" + x_seconds: + one: "一秒" + other: "%{count} 秒" + less_than_x_minutes: + one: "不到一分钟" + other: "不到 %{count} 分钟" + x_minutes: + one: "一分钟" + other: "%{count} 分钟" + about_x_hours: + one: "大约一小时" + other: "大约 %{count} 小时" + x_days: + one: "一天" + other: "%{count} 天" + about_x_months: + one: "大约一个月" + other: "大约 %{count} 个月" + x_months: + one: "一个月" + other: "%{count} 个月" + about_x_years: + one: "大约一年" + other: "大约 %{count} 年" + over_x_years: + one: "一年多" + other: "%{count} 年多" + almost_x_years: + one: "已经一年" + other: "已经 %{count} 年" + models: + errors: + template: + header: + one: "%{model} 保存时产生错误" + other: "%{model} 保存时产生了 %{count} 个错误" + body: "下列字段产生错误:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/zh_tw.yml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/zh_tw.yml new file mode 100644 index 00000000..982760bd --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/locale/zh_tw.yml @@ -0,0 +1,103 @@ +zh_tw: + number: + # Used in number_with_delimiter(). + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'. + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5). + separator: "." + # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three). + delimiter: "," + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00). + precision: 3 + + # Used in number_to_currency(). + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00). + format: "%u %n" + unit: "NT$" + # These three are to override number.format and are optional. + separator: "." + delimiter: "," + precision: 2 + + # Used in number_to_percentage(). + percentage: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_precision(). + precision: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + # precision: + + # Used in number_to_human_size(). + human: + format: + # These three are to override number.format and are optional. + # separator: + delimiter: "" + precision: 1 + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB). + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words(). + datetime: + distance_in_words: + half_a_minute: "半分鐘" + less_than_x_seconds: + one: "不到一秒" + other: "不到 %{count} 秒" + x_seconds: + one: "一秒" + other: "%{count} 秒" + less_than_x_minutes: + one: "不到一分鐘" + other: "不到 %{count} 分鐘" + x_minutes: + one: "一分鐘" + other: "%{count} 分鐘" + about_x_hours: + one: "大約一小時" + other: "大約 %{count} 小時" + x_days: + one: "一天" + other: "%{count} 天" + about_x_months: + one: "大約一個月" + other: "大約 %{count} 個月" + x_months: + one: "一個月" + other: "%{count} 個月" + about_x_years: + one: "大約一年" + other: "大約 %{count} 年" + over_x_years: + one: "一年多" + other: "%{count} 年多" + almost_x_years: + one: "接近一年" + other: "接近 %{count} 年" + models: + errors: + template: + header: + one: "有 1 個錯誤發生使得「%{model}」無法被儲存。" + other: "有 %{count} 個錯誤發生使得「%{model}」無法被儲存。" + body: "以下欄位發生問題:" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/number_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/number_helpers.rb new file mode 100644 index 00000000..6112daf0 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/number_helpers.rb @@ -0,0 +1,283 @@ +module Padrino + module Helpers + ## + # Provides methods for converting numbers into formatted strings. + # Methods are provided for phone numbers, currency, percentage, + # precision, positional notation, and file size. + # + # Adapted from Rails Number Helpers. + # + module NumberHelpers + ## + # Formats a +number+ into a currency string (e.g., $13.65). You can customize the format + # in the +options+ hash. + # + # @param [Float] number + # Currency value to format. + # @param [Hash] options + # Options for currency conversion. + # @option options [Fixnum] :precision (2) + # Sets the level of precision. + # @option options [String] :unit ("$") + # Sets the denomination of the currency. + # @option options [String] :separator (".") + # Sets the separator between the units. + # @option options [String] :delimiter (",") + # Sets the thousands delimiter. + # @option options [String] :format ("%u%n") + # Sets the format of the output string. The field types are: + # %u The currency unit + # %n The number + # + # @return [String] The formatted representation of the currency. + # + # @example + # number_to_currency(1234567890.50) # => $1,234,567,890.50 + # number_to_currency(1234567890.506) # => $1,234,567,890.51 + # number_to_currency(1234567890.506, :precision => 3) # => $1,234,567,890.506 + # number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "") + # # => £1234567890,50 + # number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "", :format => "%n %u") + # # => 1234567890,50 £ + # + def number_to_currency(number, options = {}) + options.symbolize_keys! + + defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {} + currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :raise => true) rescue {} + defaults = defaults.merge(currency) + + precision = options[:precision] || defaults[:precision] + unit = options[:unit] || defaults[:unit] + separator = options[:separator] || defaults[:separator] + delimiter = options[:delimiter] || defaults[:delimiter] + format = options[:format] || defaults[:format] + separator = '' if precision == 0 + + begin + format.gsub(/%n/, number_with_precision(number, + :precision => precision, + :delimiter => delimiter, + :separator => separator) + ).gsub(/%u/, unit) + rescue + number + end + end + + ## + # Formats a +number+ as a percentage string (e.g., 65%). You can customize the + # format in the +options+ hash. + # + # @param [Fixnum, Float] number + # Percentage value to format. + # @param [Hash] options + # Options for percentage conversion. + # @option options [Fixnum] :precision (3) + # Sets the level of precision. + # @option options [String] :separator (".") + # Sets the separator between the units. + # @option options [String] :delimiter ("") + # Sets the thousands delimiter. + # + # @return [String] The formatted representation of the percentage + # + # @example + # number_to_percentage(100) # => 100.000% + # number_to_percentage(100, :precision => 0) # => 100% + # number_to_percentage(1000, :delimiter => '.', :separator => ',') # => 1.000,000% + # number_to_percentage(302.24398923423, :precision => 5) # => 302.24399% + # + def number_to_percentage(number, options = {}) + options.symbolize_keys! + + defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {} + percentage = I18n.translate(:'number.percentage.format', :locale => options[:locale], :raise => true) rescue {} + defaults = defaults.merge(percentage) + + precision = options[:precision] || defaults[:precision] + separator = options[:separator] || defaults[:separator] + delimiter = options[:delimiter] || defaults[:delimiter] + + begin + number_with_precision(number, + :precision => precision, + :separator => separator, + :delimiter => delimiter) + "%" + rescue + number + end + end + + ## + # Formats a +number+ with grouped thousands using +delimiter+ (e.g., 12,324). You can + # customize the format in the +options+ hash. + # + # @overload number_with_delimiter(number, options={}) + # @param [Fixnum, Float] number + # Number value to format. + # @param [Hash] options + # Options for formatter. + # @option options [String] :delimiter (", ") + # Sets the thousands delimiter. + # @option options [String] :separator (".") + # Sets the separator between the units. + # + # @return [String] The formatted representation of the number. + # + # @example + # number_with_delimiter(12345678) # => 12,345,678 + # number_with_delimiter(12345678.05) # => 12,345,678.05 + # number_with_delimiter(12345678, :delimiter => ".") # => 12.345.678 + # number_with_delimiter(12345678, :separator => ",") # => 12,345,678 + # number_with_delimiter(98765432.98, :delimiter => " ", :separator => ",") + # # => 98 765 432,98 + # + def number_with_delimiter(number, *args) + options = args.extract_options! + options.symbolize_keys! + + defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {} + + delimiter ||= (options[:delimiter] || defaults[:delimiter]) + separator ||= (options[:separator] || defaults[:separator]) + + begin + parts = number.to_s.split('.') + parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}") + parts.join(separator) + rescue + number + end + end + + ## + # Formats a +number+ with the specified level of :precision (e.g., 112.32 has a precision of 2). + # You can customize the format in the +options+ hash. + # + # @overload number_with_precision(number, options={}) + # @param [Fixnum, Float] number + # Number value to format. + # @param [Hash] options + # Options for formatter. + # @option options [Fixnum] :precision (3) + # Sets the level of precision. + # @option options [String] :separator (".") + # Sets the separator between the units. + # @option options [String] :delimiter ("") + # Sets the thousands delimiter. + # + # @return [String] The formatted representation of the number. + # + # @example + # number_with_precision(111.2345) # => 111.235 + # number_with_precision(111.2345, :precision => 2) # => 111.23 + # number_with_precision(13, :precision => 5) # => 13.00000 + # number_with_precision(389.32314, :precision => 0) # => 389 + # number_with_precision(1111.2345, :precision => 2, :separator => ',', :delimiter => '.') + # # => 1.111,23 + # + def number_with_precision(number, *args) + options = args.extract_options! + options.symbolize_keys! + + defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {} + precision_defaults = I18n.translate(:'number.precision.format', :locale => options[:locale], + :raise => true) rescue {} + defaults = defaults.merge(precision_defaults) + + precision ||= (options[:precision] || defaults[:precision]) + separator ||= (options[:separator] || defaults[:separator]) + delimiter ||= (options[:delimiter] || defaults[:delimiter]) + + begin + rounded_number = (Float(number) * (10 ** precision)).round.to_f / 10 ** precision + number_with_delimiter("%01.#{precision}f" % rounded_number, + :separator => separator, + :delimiter => delimiter) + rescue + number + end + end + + # The units available for storage formatting. + STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb].freeze + + ## + # Formats the bytes in +size+ into a more understandable representation + # (e.g., giving it 1500 yields 1.5 KB). This method is useful for + # reporting file sizes to users. This method returns nil if + # +size+ cannot be converted into a number. You can customize the + # format in the +options+ hash. + # + # + # @overload number_to_human_size(number, options={}) + # @param [Fixnum] number + # Number value to format. + # @param [Hash] options + # Options for formatter. + # @option options [Fixnum] :precision (1) + # Sets the level of precision. + # @option options [String] :separator (".") + # Sets the separator between the units. + # @option options [String] :delimiter ("") + # Sets the thousands delimiter. + # + # @return [String] The formatted representation of bytes + # + # @example + # number_to_human_size(123) # => 123 Bytes + # number_to_human_size(1234) # => 1.2 KB + # number_to_human_size(12345) # => 12.1 KB + # number_to_human_size(1234567) # => 1.2 MB + # number_to_human_size(1234567890) # => 1.1 GB + # number_to_human_size(1234567890123) # => 1.1 TB + # number_to_human_size(1234567, :precision => 2) # => 1.18 MB + # number_to_human_size(483989, :precision => 0) # => 473 KB + # number_to_human_size(1234567, :precision => 2, :separator => ',') # => 1,18 MB + # + def number_to_human_size(number, *args) + return nil if number.nil? + + options = args.extract_options! + options.symbolize_keys! + + defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {} + human = I18n.translate(:'number.human.format', :locale => options[:locale], :raise => true) rescue {} + defaults = defaults.merge(human) + + precision ||= (options[:precision] || defaults[:precision]) + separator ||= (options[:separator] || defaults[:separator]) + delimiter ||= (options[:delimiter] || defaults[:delimiter]) + + storage_units_format = I18n.translate(:'number.human.storage_units.format', :locale => options[:locale], :raise => true) + + if number.to_i < 1024 + unit = I18n.translate(:'number.human.storage_units.units.byte', :locale => options[:locale], :count => number.to_i, :raise => true) + storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit) + else + max_exp = STORAGE_UNITS.size - 1 + number = Float(number) + exponent = (Math.log(number) / Math.log(1024)).to_i # Convert to base 1024 + exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit + number /= 1024 ** exponent + + unit_key = STORAGE_UNITS[exponent] + unit = I18n.translate(:"number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true) + + begin + escaped_separator = Regexp.escape(separator) + formatted_number = number_with_precision(number, + :precision => precision, + :separator => separator, + :delimiter => delimiter + ).sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '') + storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit) + rescue + number + end + end + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers.rb new file mode 100644 index 00000000..69e8e945 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers.rb @@ -0,0 +1,207 @@ +module Padrino + module Helpers + ## + # Helpers related to buffer output for various template engines. + # + module OutputHelpers + def self.included(base) + base.send(:include, SinatraCurrentEngine) unless base.method_defined?(:current_engine) + end + + ## + # Module used to detect the current engine in vanilla Sinatra apps. + # + module SinatraCurrentEngine + attr_reader :current_engine + + def render(engine, *) + @current_engine, engine_was = engine, @current_engine + output = super + @current_engine = engine_was + output + end + end + + ## + # Captures the html from a block of template code for any available handler. + # + # Be aware that trusting the html is up to the caller. + # + # @param [Object] *args + # Objects yield to the captured block. + # @param [Proc] &block + # Template code to capture as HTML. + # + # @return [String] Captured HTML resulting from the block. + # + # @example + # capture_html(&block) => "...html..." + # capture_html(object_for_block, &block) => "...html..." + # + # @example + # ActiveSupport::SafeBuffer.new + capture_html { "" } + # # => "<foo>" + # ActiveSupport::SafeBuffer.new.safe_concat(capture_html { "" }) + # # => "" + # + def capture_html(*args, &block) + handler = find_proper_handler + captured_block, captured_html = nil, "" + if handler && handler.is_type? && handler.block_is_type?(block) + captured_html, captured_block = handler.capture_from_template(*args, &block) + end + # invoking the block directly if there was no template + captured_html = block_given? && ( captured_block || block.call(*args) ) if captured_html.blank? + captured_html + end + alias :capture :capture_html + + ## + # Outputs the given text to the templates buffer directly. + # + # The output might be subject to escaping, if it is not marked as safe. + # + # @param [String, SafeBuffer] text + # Text to concatenate to the buffer. + # + # @example + # concat_content("This will be output to the template buffer") + # + def concat_content(text="") + handler = find_proper_handler + if handler && handler.is_type? + handler.concat_to_template(text) + else # theres no template to concat, return the text directly + text + end + end + alias :concat :concat_content + + ## + # Outputs the given text to the templates buffer directly, + # assuming that it is safe. + # + # @param [String] text + # Text to concatenate to the buffer. + # + # @example + # concat_safe_content("This will be output to the template buffer") + # + def concat_safe_content(text="") + concat_content text.html_safe + end + + ## + # Returns true if the block is from a supported template type; false otherwise. + # Used to determine if html should be returned or concatenated to the view. + # + # @param [Block] block + # Determine if this block is a view template. + # + # @example + # block_is_template?(block) => true + # + # @return [Boolean] True if the block is a template; false otherwise. + # + def block_is_template?(block) + handler = find_proper_handler + block && handler && handler.block_is_type?(block) + end + + ## + # Capture a block or text of content to be rendered at a later time. + # Your blocks can also receive values, which are passed to them by yield_content. + # + # @overload content_for(key, content) + # @param [Symbol] key Name of your key for the content yield. + # @param [String] content Text to be stored for this key. + # @overload content_for(key, &block) + # @param [Symbol] key Name of your key for the content yield. + # @param [Proc] block Block to be stored as content for this key. + # + # @example + # content_for(:name) { ...content... } + # content_for(:name) { |name| ...content... } + # content_for(:name, "I'm Jeff") + # + def content_for(key, content = nil, &block) + content_blocks[key.to_sym] << (block_given? ? block : Proc.new { content }) + end + + ## + # Is there a content block for a given key? + # + # @param [Symbol] key + # Name of content to yield. + # + # @return [TrueClass,FalseClass] Result html for the given +key+ + # + # @example + # content_for? :header => true + # + def content_for?(key) + content_blocks[key.to_sym].present? + end + + ## + # Render the captured content blocks for a given key. + # You can also pass values to the content blocks by passing them + # as arguments after the key. + # + # @param [Symbol] key + # Name of content to yield. + # @param *args + # Values to pass to the content block. + # + # @return [String] Result HTML for the given +key+. + # + # @example + # yield_content :include + # yield_content :head, "param1", "param2" + # yield_content(:title) || "My page title" + # + def yield_content(key, *args) + blocks = content_blocks[key.to_sym] + return nil if blocks.empty? + mark_safe(blocks.map { |content| capture_html(*args, &content) }.join) + end + + protected + ## + # Retrieves content_blocks stored by content_for or within yield_content. + # + # @example + # content_blocks[:name] => ['...', '...'] + # + def content_blocks + @content_blocks ||= Hash.new { |h,k| h[k] = [] } + end + + ## + # Retrieves the template handler for the given output context. + # Can handle any output related to capturing or concatenating in a given template. + # + # @example + # find_proper_handler => + # + def find_proper_handler + OutputHelpers.handlers.map { |h| h.new(self) }.find { |h| h.engines.include?(current_engine) && h.is_type? } + end + + ## + # Marks a String or a collection of Strings as safe. `nil` is accepted + # but ignored. + # + # @param [String, Array] the values to be marked safe. + # + # @return [ActiveSupport::SafeBuffer, Array] + def mark_safe(value) + if value.respond_to? :map! + value.map!{|v| v.html_safe if v } + else + value.html_safe if value + end + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers/abstract_handler.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers/abstract_handler.rb new file mode 100644 index 00000000..0ba38600 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers/abstract_handler.rb @@ -0,0 +1,96 @@ +module Padrino + module Helpers + module OutputHelpers + ## + # Returns the list of all available template handlers. + # + # @example + # OutputHelpers.handlers => [, ] + # + def self.handlers + @_template_handlers ||= [] + end + + ## + # Registers a new handler as available to the output helpers. + # + # @example + # OutputHelpers.register(OutputHelpers::HamlHandler) + # + def self.register(handler) + handlers << handler + end + + # @abstract Extend this to create a template handler. + class AbstractHandler + attr_reader :template + + def initialize(template) + @template = template + end + + ## + # Returns extension of the template. + # + # @example + # @handler.template_extension => "erb" + # + def template_extension + caller.find { |c| c =~ /\/views\// }[/\.([\w]*?)\:/, 1] rescue nil + # "/some/path/app/views/posts/foo.html.erb:3:in `evaluate_source'" + # => "erb" + end + + ## + # Returns an array of engines used for the template. + # + # @example + # @handler.engines => [:erb, :erubis] + # + def engines + # Implemented in subclass. + end + + ## + # Returns true if the current template type is same as this handlers; false otherwise. + # + # @example + # @handler.is_type? => true + # + def is_type? + # Implemented in subclass. + end + + ## + # Returns true if the block given is of the handler's template type; false otherwise. + # + # @example + # @handler.block_is_type?(block) => true + # + def block_is_type?(block) + # Implemented in subclass. + end + + ## + # Captures the html from a block of template code for this handler. + # + # @example + # @handler.capture_from_template(&block) => "...html..." + # + def capture_from_template(*args, &block) + # Implemented in subclass. + end + + ## + # Outputs the given text to the templates buffer directly. + # + # @example + # @handler.concat_to_template("This will be output to the template buffer") + # + def concat_to_template(text="") + # Implemented in subclass. + end + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers/erb_handler.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers/erb_handler.rb new file mode 100644 index 00000000..3d073177 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers/erb_handler.rb @@ -0,0 +1,78 @@ +module Padrino + module Helpers + module OutputHelpers + ## + # Handler for reading and writing from an erb template. + # + class ErbHandler < AbstractHandler + attr_reader :output_buffer + + def initialize(template) + super + @output_buffer = template.instance_variable_get(:@_out_buf) + end + + ## + # Returns true if the current template type is same as this handlers; false otherwise. + # + # @example + # @handler.is_type? => true + # + def is_type? + !self.output_buffer.nil? + end + + ## + # Captures the html from a block of template code for this handler. + # + # @example + # @handler.capture_from_template(&block) => "...html..." + # + def capture_from_template(*args, &block) + self.output_buffer, _buf_was = ActiveSupport::SafeBuffer.new, self.output_buffer + captured_block = block.call(*args) + ret = eval("@_out_buf", block.binding) + self.output_buffer = _buf_was + [ ret, captured_block ] + end + + ## + # Outputs the given text to the templates buffer directly. + # + # @example + # @handler.concat_to_template("This will be output to the template buffer") + # + def concat_to_template(text="") + self.output_buffer << text if is_type? && text + nil + end + + ## + # Returns true if the block given is of the handler's template type; false otherwise. + # + # @example + # @handler.block_is_type?(block) => true + # + def block_is_type?(block) + is_type? || (block && eval('defined?(__in_erb_template)', block.binding)) + end + + ## + # Returns an array of engines used for the template. + # + # @example + # @handler.engines => [:erb, :erubis] + # + def engines + @_engines ||= [:erb, :erubis] + end + + protected + def output_buffer=(val) + template.instance_variable_set(:@_out_buf, val) + end + end + OutputHelpers.register(ErbHandler) + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers/haml_handler.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers/haml_handler.rb new file mode 100644 index 00000000..dd57fd97 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers/haml_handler.rb @@ -0,0 +1,63 @@ +module Padrino + module Helpers + module OutputHelpers + ## + # Handler for reading and writing from a haml template. + # + class HamlHandler < AbstractHandler + ## + # Returns true if the current template type is same as this handlers; false otherwise. + # + # @example + # @handler.is_type? => true + # + def is_type? + template.respond_to?(:is_haml?) && template.is_haml? + end + + ## + # Returns true if the block given is of the handler's template type; false otherwise. + # + # @example + # @handler.block_is_type?(block) => true + # + def block_is_type?(block) + template.block_is_haml?(block) + end + + ## + # Captures the html from a block of template code for this handler. + # + # @example + # @handler.capture_from_template(&block) => "...html..." + # + def capture_from_template(*args, &block) + eval("_hamlout ||= @haml_buffer", block.binding) + template.capture_haml(*args, &block) + end + + ## + # Outputs the given text to the templates buffer directly. + # + # @example + # @handler.concat_to_template("This will be output to the template buffer") + # + def concat_to_template(text="") + template.haml_concat(text) + nil + end + + ## + # Returns an array of engines used for the template. + # + # @example + # @handler.engines => [:haml] + # + def engines + @_engines ||= [:haml] + end + end + OutputHelpers.register(HamlHandler) + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers/slim_handler.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers/slim_handler.rb new file mode 100644 index 00000000..3b8ab5be --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/output_helpers/slim_handler.rb @@ -0,0 +1,78 @@ +module Padrino + module Helpers + module OutputHelpers + ## + # Handler for reading and writing from a slim template. + # + class SlimHandler < AbstractHandler + attr_reader :output_buffer + + def initialize(template) + super + @output_buffer = template.instance_variable_get(:@_out_buf) + end + + ## + # Returns true if the current template type is same as this handlers; false otherwise. + # + # @example + # @handler.is_type? => true + # + def is_type? + !self.output_buffer.nil? + end + + ## + # Captures the html from a block of template code for this handler. + # + # @example + # @handler.capture_from_template(&block) => "...html..." + # + def capture_from_template(*args, &block) + self.output_buffer, _buf_was = ActiveSupport::SafeBuffer.new, self.output_buffer + captured_block = block.call(*args) + ret = eval("@_out_buf", block.binding) + self.output_buffer = _buf_was + [ ret, captured_block ] + end + + ## + # Outputs the given text to the templates buffer directly. + # + # @example + # @handler.concat_to_template("This will be output to the template buffer") + # + def concat_to_template(text="") + self.output_buffer << text if is_type? && text + nil + end + + ## + # Returns true if the block given is of the handler's template type; false otherwise. + # + # @example + # @handler.block_is_type?(block) => true + # + def block_is_type?(block) + is_type? || (block && eval('defined? __in_erb_template', block.binding)) + end + + ## + # Returns an array of engines used for the template. + # + # @example + # @handler.engines => [:erb, :erubis] + # + def engines + @_engines ||= [:slim] + end + + protected + def output_buffer=(val) + template.instance_variable_set(:@_out_buf, val) + end + end + OutputHelpers.register(SlimHandler) + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/render_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/render_helpers.rb new file mode 100644 index 00000000..79ec87c4 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/render_helpers.rb @@ -0,0 +1,59 @@ +module Padrino + module Helpers + ## + # Helpers related to rendering within templates (i.e partials). + # + module RenderHelpers + ## + # Render a partials with collections support. + # + # @param [String] template + # Relative path to partial template. + # @param [Hash] options + # Options hash for rendering options. + # @option options [Object] :object + # Object rendered in partial. + # @option options [Array] :collection + # Partial is rendered for each object in this collection. + # @option options [Hash] :locals ({}) + # Local variables accessible in the partial. + # @option options [Symbol] :engine + # Explicit rendering engine to use for this partial. + # + # @return [String] The html generated from this partial. + # + # @example + # partial 'photo/item', :object => @photo + # partial 'photo/item', :collection => @photos + # partial 'photo/item', :locals => { :foo => :bar } + # partial 'photo/item', :engine => :erb + # + # @note If using this from Sinatra, pass explicit +:engine+ option + # + def partial(template, options={}) + options.reverse_merge!(:locals => {}, :layout => false) + path = template.to_s.split(File::SEPARATOR) + object_name = path[-1].to_sym + path[-1] = "_#{path[-1]}" + explicit_engine = options.delete(:engine) + template_path = File.join(path).to_sym + raise 'Partial collection specified but is nil' if options.has_key?(:collection) && options[:collection].nil? + if collection = options.delete(:collection) + options.delete(:object) + counter = 0 + collection.map { |member| + counter += 1 + options[:locals].merge!(object_name => member, "#{object_name}_counter".to_sym => counter) + render(explicit_engine, template_path, options.dup) + }.join("\n").html_safe + else + if member = options.delete(:object) + options[:locals].merge!(object_name => member) + end + render(explicit_engine, template_path, options.dup).html_safe + end + end + alias :render_partial :partial + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/tag_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/tag_helpers.rb new file mode 100644 index 00000000..a39e1a5f --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/tag_helpers.rb @@ -0,0 +1,292 @@ +module Padrino + module Helpers + ## + # Helpers related to producing html tags within templates. + # + module TagHelpers + ## + # Tag values escaped to html entities. + # + ESCAPE_VALUES = { + "&" => "&", + "<" => "<", + ">" => ">", + '"' => """ + } + + ## + # Cached Regexp for escaping values to avoid rebuilding one + # on every escape operation. + # + ESCAPE_REGEXP = Regexp.union(*ESCAPE_VALUES.keys) + + BOOLEAN_ATTRIBUTES = [ + :autoplay, + :autofocus, + :formnovalidate, + :checked, + :disabled, + :hidden, + :loop, + :multiple, + :muted, + :readonly, + :required, + :selected, + :declare, + :defer, + :ismap, + :itemscope, + :noresize, + :novalidate + ] + + ## + # Custom data attributes, + # feel free to update with yours: + # + # Padrino::Helpers::TagHelpers::DATA_ATTRIBUTES.push(:dialog) + # text_field :foo, :dialog => true + # # Generates: + # + DATA_ATTRIBUTES = [ + :method, + :remote, + :confirm + ] + + ## + # A html_safe newline string to avoid allocating a new on each + # concatenation. + # + NEWLINE = "\n".html_safe.freeze + + ## + # Creates an HTML tag with given name, content, and options. + # + # @overload content_tag(name, content, options = nil) + # @param [Symbol] name + # The name of the HTML tag to create. + # @param [String] content + # The content inside of the tag. + # @param [Hash] options + # The HTML options to include in this tag. + # + # @overload content_tag(name, options = nil, &block) + # @param [Symbol] name + # The name of the HTML tag to create. + # @param [Hash] options + # The HTML options to include in this tag. + # @param [Proc] block + # The block returning HTML content. + # + # @macro [new] global_html_attributes + # @option options [String] :id + # Specifies a unique identifier for the element. + # @option options [String] :class + # Specifies the stylesheet class of the element. + # @option options [String] :title + # Specifies the title for the element. + # @option options [String] :accesskey + # Specifies a shortcut key to access the element. + # @option options [Symbol] :dropzone + # Specifies what happens when dragged items are dropped on the element. (:copy, :link, :move) + # @option options [Boolean] :hidden + # Specifies whether or not the element is hidden from view. + # @option options [Boolean] :draggable + # Specifies whether or not the element is draggable. (true, false, :auto) + # @option options [Boolean] :contenteditable + # Specifies whether or not the element is editable. + # + # @return [String] + # Generated HTML with specified +options+. + # + # @example + # content_tag(:p, 'Hello World', :class => 'light') + # + # # =>

+ # # => Hello World + # # =>

+ # + # content_tag(:p, :class => 'dark') do + # link_to 'Padrino', 'http://www.padrinorb.com' + # end + # + # # =>

+ # # => Padrino + # # =>

+ # + def content_tag(name, content = nil, options = nil, &block) + if block_given? + options = content if content.is_a?(Hash) + content = capture_html(&block) + end + + options = parse_data_options(name, options) + attributes = tag_attributes(options) + output = ActiveSupport::SafeBuffer.new + output.safe_concat "<#{name}#{attributes}>" + if content.respond_to?(:each) && !content.is_a?(String) + content.each { |c| output.concat c; output.safe_concat NEWLINE } + else + output.concat content + end + output.safe_concat "" + + block_is_template?(block) ? concat_content(output) : output + end + + ## + # Like #content_tag, but assumes its input to be safe and doesn't + # escape. It also returns safe HTML. + # + # @see #content_tag + # + def safe_content_tag(name, content = nil, options = nil, &block) + mark_safe(content_tag(name, mark_safe(content), options, &block)) + end + + ## + # Creates an HTML input field with the given type and options. + # + # @param [Symbol] type + # The type of input to create. + # @param [Hash] options + # The HTML options to include in this input. + # + # @option options [String] :id + # Specifies a unique identifier for the input. + # @option options [String] :class + # Specifies the stylesheet class of the input. + # @option options [String] :name + # Specifies the name of the input. + # @option options [String] :accesskey + # Specifies a shortcut key to access the input. + # @option options [Integer] :tabindex + # Specifies the tab order of the input. + # @option options [Boolean] :hidden + # Specifies whether or not the input is hidden from view. + # @option options [Boolean] :spellcheck + # Specifies whether or not the input should have it's spelling and grammar checked for errors. + # @option options [Boolean] :draggable + # Specifies whether or not the input is draggable. (true, false, :auto) + # @option options [String] :pattern + # Specifies the regular expression pattern that the input's value is checked against. + # @option options [Symbol] :autocomplete + # Specifies whether or not the input should have autocomplete enabled. (:on, :off) + # @option options [Boolean] :autofocus + # Specifies whether or not the input should automatically get focus when the page loads. + # @option options [Boolean] :required + # Specifies whether or not the input is required to be completed before the form is submitted. + # @option options [Boolean] :readonly + # Specifies whether or not the input is read only. + # @option options [Boolean] :disabled + # Specifies whether or not the input is disabled. + # + # @return [String] + # Generated HTML with specified +options+. + # + # @example + # input_tag :text, :name => 'handle' + # # => + # + # input_tag :password, :name => 'password', :size => 20 + # # => + # + # input_tag :text, :name => 'username', :required => true, :autofocus => true + # # => + # + # input_tag :number, :name => 'credit_card', :autocomplete => :off + # # => + # + def input_tag(type, options = {}) + tag(:input, options.reverse_merge!(:type => type)) + end + + ## + # Creates an HTML tag with the given name and options. + # + # @param [Symbol] name + # The name of the HTML tag to create. + # @param [Hash] options + # The HTML options to include in this tag. + # + # @macro global_html_attributes + # + # @return [String] + # Generated HTML with specified +options+. + # + # @example + # tag :hr, :class => 'dotted' + # # =>
+ # + # tag :input, :name => 'username', :type => :text + # # => + # + # tag :img, :src => 'images/pony.jpg', :alt => 'My Little Pony' + # # => My Little Pony + # + # tag :img, :src => 'sinatra.jpg, :data => { :nsfw => false, :geo => [34.087, -118.407] } + # # => + # + def tag(name, options = nil, open = false) + options = parse_data_options(name, options) + attributes = tag_attributes(options) + "<#{name}#{attributes}#{open ? '>' : ' />'}".html_safe + end + + private + ## + # Returns a compiled list of HTML attributes. + # + def tag_attributes(options) + return '' if options.nil? + attributes = options.map do |k, v| + next if v.nil? || v == false + if v.is_a?(Hash) + nested_values(k, v) + elsif BOOLEAN_ATTRIBUTES.include?(k) + %(#{k}="#{k}") + else + %(#{k}="#{escape_value(v)}") + end + end.compact + attributes.empty? ? '' : " #{attributes * ' '}" + end + + ## + # Escape tag values to their HTML/XML entities. + # + def escape_value(string) + string.to_s.gsub(ESCAPE_REGEXP) { |c| ESCAPE_VALUES[c] } + end + + ## + # Iterate through nested values. + # + def nested_values(attribute, hash) + hash.map do |k, v| + if v.is_a?(Hash) + nested_values("#{attribute}-#{k.to_s.dasherize}", v) + else + %(#{attribute}-#{k.to_s.dasherize}="#{escape_value(v)}") + end + end * ' ' + end + + ## + # Parses custom data attributes. + # + def parse_data_options(tag, options) + return if options.nil? + parsed_options = options.dup + options.each do |k, v| + next if !DATA_ATTRIBUTES.include?(k) || (tag.to_s == 'form' && k == :method) + parsed_options["data-#{k}"] = parsed_options.delete(k) + parsed_options[:rel] = 'nofollow' if k == :method + end + parsed_options + end + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/translation_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/translation_helpers.rb new file mode 100644 index 00000000..22518f7c --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/lib/padrino-helpers/translation_helpers.rb @@ -0,0 +1,36 @@ +module Padrino + module Helpers + ## + # Helpers related to locale i18n translation within templates. + # + module TranslationHelpers + ## + # Delegates to I18n.translate with no additional functionality. + # + # @param [Symbol] *args + # The keys to retrieve. + # + # @return [String] + # The translation for the specified keys. + # + def translate(*args) + I18n.translate(*args) + end + alias :t :translate + + ## + # Delegates to I18n.localize with no additional functionality. + # + # @param [Symbol] *args + # The keys to retrieve. + # + # @return [String] + # The translation for the specified keys. + # + def localize(*args) + I18n.localize(*args) + end + alias :l :localize + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/padrino-helpers.gemspec b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/padrino-helpers.gemspec new file mode 100644 index 00000000..01d1d61c --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/padrino-helpers.gemspec @@ -0,0 +1,27 @@ +#!/usr/bin/env gem build +# encoding: utf-8 + +require File.expand_path("../../padrino-core/lib/padrino-core/version.rb", __FILE__) + +Gem::Specification.new do |s| + s.name = "padrino-helpers" + s.rubyforge_project = "padrino-helpers" + s.authors = ["Padrino Team", "Nathan Esquenazi", "Davide D'Agostino", "Arthur Chiu"] + s.email = "padrinorb@gmail.com" + s.summary = "Helpers for padrino" + s.homepage = "http://www.padrinorb.com" + s.description = "Tag helpers, asset helpers, form helpers, form builders and many more helpers for padrino" + s.required_rubygems_version = ">= 1.3.6" + s.version = Padrino.version + s.date = Time.now.strftime("%Y-%m-%d") + + s.extra_rdoc_files = Dir["*.rdoc"] + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + s.require_paths = ["lib"] + s.rdoc_options = ["--charset=UTF-8"] + + s.add_dependency("padrino-core", Padrino.version) + s.add_dependency("i18n", "~> 0.6") +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/app.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/app.rb new file mode 100644 index 00000000..88c18aed --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/app.rb @@ -0,0 +1,84 @@ +require 'sinatra/base' +require 'haml' +require 'erubis' +require 'slim' +require 'padrino-core/application/rendering/extensions/erubis' +require 'padrino-core/application/rendering/extensions/haml' +require 'padrino-core/application/rendering/extensions/slim' + +class MarkupDemo < Sinatra::Base + register Padrino::Helpers + + configure do + set :logging, false + set :padrino_logging, false + set :environment, :test + set :root, File.dirname(__FILE__) + set :erb, :engine_class => Padrino::Erubis::SafeBufferTemplate + set :haml, :escape_html => true + set :slim, :generator => Temple::Generators::RailsOutputBuffer, :buffer => "out_buf" + set :sessions, true + set :protect_from_csrf, true + end + + get '/:engine/:file' do + show(params[:engine], params[:file].to_sym) + end + + helpers do + # show :erb, :index + # show :haml, :index + def show(kind, template) + send kind.to_sym, template.to_sym + end + + def captured_content(&block) + content_html = capture_html(&block) + "

#{content_html}

".html_safe + end + + def concat_in_p(content_html) + concat_safe_content "

#{content_html}

" + end + + def concat_if_block_is_template(name, &block) + concat_safe_content "

The #{name} block passed in is a template

" if block_is_template?(block) + end + + def concat_ruby_not_template_block + concat_if_block_is_template('ruby') do + content_tag(:span, "This not a template block") + end + end + end +end + +class MarkupUser + def errors; { :fake => "must be valid", :second => "must be present", :third => "must be a number", :email => "must be an email"}; end + def session_id; 45; end + def gender; 'male'; end + def remember_me; '1'; end + def permission; Permission.new; end + def telephone; Telephone.new; end + def addresses; [Address.new('Greenfield', true), Address.new('Willowrun', false)]; end +end + +class Telephone + def number; "62634576545"; end +end + +class Address + attr_accessor :name + def initialize(name, existing); @name, @existing = name, existing; end + def new_record?; !@existing; end + def id; @existing ? 25 : nil; end +end + +class Permission + def can_edit; true; end + def can_delete; false; end +end + +module Outer + class UserAccount; end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/button_to.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/button_to.erb new file mode 100644 index 00000000..69f8b1d7 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/button_to.erb @@ -0,0 +1,8 @@ +<% button_to 'Foo button', '/foo', :class => 'foo-form' do %> + <% field_set_tag do %> + <%= hidden_field_tag :session_id, :value => "__secret__" %> + <%= label_tag :username %> + <% end %> +<% end %> +<%= content_tag(:p, 'button_to test', :id => 'test-point') %> +<%= button_to 'Bar button', '/bar' %> diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/button_to.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/button_to.haml new file mode 100644 index 00000000..fa189844 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/button_to.haml @@ -0,0 +1,5 @@ +- button_to 'Foo button', '/foo', :class => 'foo-form' do + - field_set_tag do + = label_tag :username += content_tag(:p, 'button_to test', :id => 'test-point') += button_to 'Bar button', '/bar' diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/button_to.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/button_to.slim new file mode 100644 index 00000000..90933f89 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/button_to.slim @@ -0,0 +1,6 @@ += button_to 'Foo button', '/foo', :class => 'foo-form' do + = field_set_tag do + = hidden_field_tag :session_id, :value => "__secret__" + = label_tag :username += content_tag(:p, 'button_to test', :id => 'test-point') += button_to 'Bar button', '/bar' diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/capture_concat.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/capture_concat.erb new file mode 100644 index 00000000..220cbd4e --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/capture_concat.erb @@ -0,0 +1,14 @@ +<% @content = captured_content do %> + Captured Line 1 + Captured Line 2 +<% end %> +<%= @content %> + +<% concat_in_p('Concat Line 3') %> + +<% concat_if_block_is_template('erb') do %> + This is erb + This is erb +<% end %> + +<% concat_ruby_not_template_block %> diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/capture_concat.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/capture_concat.haml new file mode 100644 index 00000000..527c0115 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/capture_concat.haml @@ -0,0 +1,12 @@ +- @content = captured_content do + %span Captured Line 1 + %span Captured Line 2 += @content + +- concat_in_p('Concat Line 3') + +- concat_if_block_is_template('haml') do + %span This is haml + %span This is haml + +- concat_ruby_not_template_block diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/capture_concat.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/capture_concat.slim new file mode 100644 index 00000000..04186e7b --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/capture_concat.slim @@ -0,0 +1,12 @@ +- @content = captured_content do + span Captured Line 1 + span Captured Line 2 += @content + +- concat_in_p('Concat Line 3') + +- concat_if_block_is_template('slim') do + span This is slim + span This is slim + +- concat_ruby_not_template_block \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_for.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_for.erb new file mode 100644 index 00000000..bede704d --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_for.erb @@ -0,0 +1,14 @@ +<% content_for :demo do %> +

This is content yielded from a content_for

+<% end %> + +
<%= yield_content :demo %>
+ +<% content_for :demo2 do |fname, lname| %> +

This is content yielded with name <%= fname + " " + lname %>

+<% end %> + +
<%= yield_content :demo2, "Johnny", "Smith" %>
+ +
<%= content_for?(:demo).to_s %> +
<%= content_for?(:fake).to_s %> \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_for.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_for.haml new file mode 100644 index 00000000..80055aa8 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_for.haml @@ -0,0 +1,12 @@ +- content_for :demo do + %h1 This is content yielded from a content_for + +.demo= yield_content :demo + +- content_for :demo2 do |fname, lname| + %h1 This is content yielded with name #{fname + " " + lname} + +.demo2= yield_content :demo2, "Johnny", "Smith" + +.demo_has_content= content_for?(:demo) +.fake_has_content= content_for?(:fake) diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_for.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_for.slim new file mode 100644 index 00000000..be66c854 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_for.slim @@ -0,0 +1,12 @@ +- content_for :demo do + h1 This is content yielded from a content_for + +.demo= yield_content :demo + +- content_for :demo2 do |fname, lname| + h1 This is content yielded with name #{fname + " " + lname} + +.demo2= yield_content :demo2, "Johnny", "Smith" + +.demo_has_content= content_for?(:demo) +.fake_has_content= content_for?(:fake) \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_tag.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_tag.erb new file mode 100644 index 00000000..2771f33a --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_tag.erb @@ -0,0 +1,11 @@ +<%= content_tag :p, "Test 1", :class => 'test', :id => "test1" %> + +<%= content_tag :p, "Test 2" %> + +<% content_tag(:p, :class => 'test', :id => 'test3') do %> + Test 3 +<% end %> + +<% content_tag(:p) do %> + Test 4 +<% end %> diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_tag.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_tag.haml new file mode 100644 index 00000000..780a2332 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_tag.haml @@ -0,0 +1,9 @@ += content_tag :p, "Test 1", :class => 'test', :id => "test1" + += content_tag :p, "Test 2" + +- content_tag(:p, :class => 'test', :id => 'test3') do + %span Test 3 + +- content_tag(:p) do + %span Test 4 diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_tag.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_tag.slim new file mode 100644 index 00000000..5ba06188 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/content_tag.slim @@ -0,0 +1,9 @@ +=content_tag :p, "Test 1", :class => 'test', :id => "test1" + +=content_tag :p, "Test 2" + +=content_tag(:p, :class => 'test', :id => 'test3') do + span Test 3 + +=content_tag(:p) do + span Test 4 \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/current_engine.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/current_engine.erb new file mode 100644 index 00000000..94f9d7f0 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/current_engine.erb @@ -0,0 +1,5 @@ +

<%= current_engine %>

+

<%= haml :'partials/_haml' %>

+

<%= erb :'partials/_erb' %>

+

<%= slim :'partials/_slim' %>

+

<%= current_engine %>

diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/current_engine.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/current_engine.haml new file mode 100644 index 00000000..e7498a43 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/current_engine.haml @@ -0,0 +1,5 @@ +%p.start= current_engine +%p.haml= haml :'partials/_haml' +%p.erb= erb :'partials/_erb' +%p.slim= slim :'partials/_slim' +%p.end= current_engine diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/current_engine.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/current_engine.slim new file mode 100644 index 00000000..6c7d0926 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/current_engine.slim @@ -0,0 +1,5 @@ +p.start= current_engine +p.haml= haml :'partials/_haml' +p.erb= erb :'partials/_erb' +p.slim= slim :'partials/_slim' +p.end= current_engine diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/fields_for.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/fields_for.erb new file mode 100644 index 00000000..cb43d2e0 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/fields_for.erb @@ -0,0 +1,20 @@ +<% @user = MarkupUser.new %> +<% form_for @user , '/demo1', :id => 'demo-fields-for' do |f| %> + <%= f.text_field :gender %> + <% fields_for @user.permission do |permission| %> + <%= permission.check_box :can_edit %> + <%= permission.check_box :can_delete %> + <% end %> + <% f.fields_for :telephone do |child_form| %> + <%= child_form.label :number %> + <%= child_form.text_field :number %> + <% end %> + <% f.fields_for :addresses do |child_form| %> + <%= child_form.label :name %> + <%= child_form.text_field :name %> + <% unless child_form.object.new_record? %> + <%= child_form.check_box '_destroy' %> + <%= child_form.label '_destroy', :caption => 'Remove' %> + <% end %> + <% end %> +<% end %> diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/fields_for.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/fields_for.haml new file mode 100644 index 00000000..6a67d79b --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/fields_for.haml @@ -0,0 +1,15 @@ +- @user = MarkupUser.new +- form_for @user , '/demo1', :id => 'demo-fields-for' do |f| + = f.text_field :gender + - fields_for @user.permission do |permission| + = permission.check_box :can_edit + = permission.check_box :can_delete + - f.fields_for :telephone do |child_form| + = child_form.label :number + = child_form.text_field :number + - f.fields_for :addresses do |child_form| + = child_form.label :name + = child_form.text_field :name + - unless child_form.object.new_record? + = child_form.check_box '_destroy' + = child_form.label '_destroy', :caption => 'Remove' diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/fields_for.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/fields_for.slim new file mode 100644 index 00000000..9046b11c --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/fields_for.slim @@ -0,0 +1,15 @@ +- @user = MarkupUser.new += form_for @user , '/demo1', :id => 'demo-fields-for' do |f| + = f.text_field :gender + = fields_for @user.permission do |permission| + = permission.check_box :can_edit + = permission.check_box :can_delete + = f.fields_for :telephone do |child_form| + = child_form.label :number + = child_form.text_field :number + = f.fields_for :addresses do |child_form| + = child_form.label :name + = child_form.text_field :name + - unless child_form.object.new_record? + = child_form.check_box '_destroy' + = child_form.label '_destroy', :caption => 'Remove' diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_for.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_for.erb new file mode 100644 index 00000000..bb8a5c81 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_for.erb @@ -0,0 +1,72 @@ +<% form_for MarkupUser.new, '/demo', :id => 'demo' do |f| %> + <%= f.error_messages(:header_message => "custom MarkupUser cannot be saved!") %> + <%= f.hidden_field :session_id %> +

+ <%= f.label :username, :caption => "Login: ", :class => 'user-label' %> + <%= f.text_field :username, :class => 'user-text', :value => "John" %> +

+

+ <%= f.label :password %> + <%= f.password_field :password, :class => 'user-password', :value => "secret" %> +

+

+ <%= f.label :age %> + <%= f.number_field :age, :class => 'numeric '%> +

+

+ <%= f.label :telephone %> + <%= f.telephone_field :telephone, :class => 'numeric' %> +

+

+ <%= f.label :email, :caption => 'Email Address: ' %> + <%= f.email_field :email, :class => 'string' %> +

+

+ <%= f.label :webpage, :caption => 'Your Web Page: ' %> + <%= f.url_field :webpage, :class => 'string' %> +

+

+ <%= f.label :search %> + <%= f.search_field :search, :class => 'string' %> +

+

+ <%= f.label :photo %> + <%= f.file_field :photo, :class => 'user-photo' %> +

+

+ <%= f.label :about, :caption => "About Me: " %> + <%= f.text_area :about, :class => 'user-about' %> +

+

+ <%= f.label :gender, :caption => "Your gender: " %> + <%= f.radio_button :gender, :value => 'male' %> + <%= f.radio_button :gender, :value => 'female' %> +

+

+ <%= f.label :country, :caption => "Your country" %> + <%= f.select :country, :options => ['USA', 'Canada', 'Mexico'], :selected => 'USA', :class => 'selector' %> +

+

+ <%= f.label :remember_me %> + <%= f.check_box :remember_me, :value => '1' %> +

+

<%= f.submit "Create", :class => 'success', :id => 'demo-button' %>

+

<%= f.image_submit "buttons/post.png", :class => 'success', :id => 'image-button' %>

+<% end %> + +<% form_for MarkupUser.new, '/another_demo', :id => 'demo2', :method => 'get' do |f| %> + <%= f.error_messages :header_message => "custom MarkupUser cannot be saved!" %> + <%= f.hidden_field :session_id %> + <%= f.text_field_block :username, { :class => 'input' }, { :caption => 'Nickname: ', :class => 'label' } %> + <%= f.password_field_block :code, { :class => 'input' } %> + <%= f.text_area_block :about, { :class => 'textarea' } %> + <%= f.file_field_block :photo, { :class => 'upload' } %> + <%= f.check_box_block :remember_me, { :class => 'checker' } %> + <%= f.select_block :state, :options => ['California', 'Texas'], :class => 'selector' %> + <%= f.submit_block "Create", { :class => 'button' } %> + <%= f.image_submit_block "buttons/ok.png", { :class => 'image' } %> +<% end %> + +<% form_for :markup_user, '/third_demo', :id => 'demo3', :method => 'get' do |f| %> + <%= f.text_field_block :username %> +<% end %> diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_for.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_for.haml new file mode 100644 index 00000000..dfc71a00 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_for.haml @@ -0,0 +1,59 @@ +- form_for MarkupUser.new, '/demo', :id => 'demo' do |f| + = f.error_messages(:header_message => "custom MarkupUser cannot be saved!") + = f.hidden_field :session_id + %p + = f.label :username, :caption => "Login: ", :class => 'user-label' + = f.text_field :username, :class => 'user-text', :value => "John" + %p + = f.label :password + = f.password_field :password, :class => 'user-password', :value => "secret" + %p + = f.label :age + = f.number_field :age, :class => 'numeric' + %p + = f.label :telephone + = f.telephone_field :telephone, :class => 'numeric' + %p + = f.label :email, :caption => 'Email Address: ' + = f.email_field :email, :class => 'string' + %p + = f.label :webpage, :caption => 'Your Web Page: ' + = f.url_field :webpage, :class => 'string' + %p + = f.label :search + = f.search_field :search, :class => 'string' + %p + = f.label :photo + = f.file_field :photo, :class => 'user-photo' + %p + = f.label :about, :caption => "About Me: " + = f.text_area :about, :class => 'user-about' + %p + = f.label :gender, :caption => "Your gender: " + = f.radio_button :gender, :value => 'male' + = f.radio_button :gender, :value => 'female' + %p + = f.label :country, :caption => "Your country" + = f.select :country, :options => ['USA', 'Canada', 'Mexico'], :selected => 'USA', :class => 'selector' + %p + = f.label :remember_me + = f.check_box :remember_me, :value => "1" + %p + = f.submit "Create", :class => 'success', :id => 'demo-button' + %p + = f.image_submit "buttons/post.png", :class => 'success', :id => 'image-button' + +- form_for MarkupUser.new, '/another_demo', :id => 'demo2', :method => 'get' do |f| + = f.error_messages :header_message => "custom MarkupUser cannot be saved!" + = f.hidden_field :session_id + = f.text_field_block :username, { :class => 'input' }, { :caption => 'Nickname: ', :class => 'label' } + = f.password_field_block :code, { :class => 'input' } + = f.text_area_block :about, { :class => 'textarea' } + = f.file_field_block :photo, { :class => 'upload' } + = f.check_box_block :remember_me, { :class => 'checker' } + = f.select_block :state, :options => ['California', 'Texas'], :class => 'selector' + = f.submit_block "Create", { :class => 'button' } + = f.image_submit_block "buttons/ok.png", { :class => 'image' } + +- form_for :markup_user, '/third_demo', :id => 'demo3', :method => 'get' do |f| + = f.text_field_block :username diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_for.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_for.slim new file mode 100644 index 00000000..cf0ad875 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_for.slim @@ -0,0 +1,59 @@ += form_for MarkupUser.new, '/demo', :id => 'demo' do |f| + = f.error_messages(:header_message => "custom MarkupUser cannot be saved!") + = f.hidden_field :session_id + p + = f.label :username, :caption => "Login: ", :class => 'user-label' + = f.text_field :username, :class => 'user-text', :value => "John" + p + = f.label :password + = f.password_field :password, :class => 'user-password', :value => "secret" + p + = f.label :age + = f.number_field :age, :class => 'numeric' + p + = f.label :telephone + = f.telephone_field :telephone, :class => 'numeric' + p + = f.label :email, :caption => 'Email Address: ' + = f.email_field :email, :class => 'string' + p + = f.label :webpage, :caption => 'Your Web Page: ' + = f.url_field :webpage, :class => 'string' + p + = f.label :search + = f.search_field :search, :class => 'string' + p + = f.label :photo + = f.file_field :photo, :class => 'user-photo' + p + = f.label :about, :caption => "About Me: " + = f.text_area :about, :class => 'user-about' + p + = f.label :gender, :caption => "Your gender: " + = f.radio_button :gender, :value => 'male' + = f.radio_button :gender, :value => 'female' + p + = f.label :country, :caption => "Your country" + = f.select :country, :options => ['USA', 'Canada', 'Mexico'], :selected => 'USA', :class => 'selector' + p + = f.label :remember_me + = f.check_box :remember_me, :value => "1" + p + = f.submit "Create", :class => 'success', :id => 'demo-button' + p + = f.image_submit "buttons/post.png", :class => 'success', :id => 'image-button' + += form_for MarkupUser.new, '/another_demo', :id => 'demo2', :method => 'get' do |f| + = f.error_messages :header_message => "custom MarkupUser cannot be saved!" + = f.hidden_field :session_id + = f.text_field_block :username, { :class => 'input' }, { :caption => 'Nickname: ', :class => 'label' } + = f.password_field_block :code, { :class => 'input' } + = f.text_area_block :about, { :class => 'textarea' } + = f.file_field_block :photo, { :class => 'upload' } + = f.check_box_block :remember_me, { :class => 'checker' } + = f.select_block :state, :options => ['California', 'Texas'], :class => 'selector' + = f.submit_block "Create", { :class => 'button' } + = f.image_submit_block "buttons/ok.png", { :class => 'image' } + += form_for :markup_user, '/third_demo', :id => 'demo3', :method => 'get' do |f| + = f.text_field_block :username diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_tag.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_tag.erb new file mode 100644 index 00000000..9475f707 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_tag.erb @@ -0,0 +1,95 @@ +<% form_tag '/simple', :class => 'simple-form' do %> + <%= hidden_field_tag :session_id, :value => "__secret__" %> + <% field_set_tag do %> + <%= label_tag :username %> + <%= text_field_tag :username %> + <%= label_tag :password %> + <%= password_field_tag :password %> + <%= label_tag :email %> + <%= email_field_tag :email %> + <%= label_tag :age %> + <%= number_field_tag :age %> + <%= label_tag :telephone %> + <%= telephone_field_tag :telephone %> + <%= label_tag :webpage %> + <%= url_field_tag :webpage %> + <%= label_tag :search %> + <%= search_field_tag :search %> + <%= check_box_tag :remember_me %> + <%= label_tag :gender %> + <%= label_tag :color %> + <%= select_tag :color, :options => ['green', 'orange', 'purple'] %> + <%= select_tag :type, :grouped_options => { 'foo' => ['foo', 'bar'], 'bar' => ['foo', 'bar'] } %> + <%= select_tag :character, :grouped_options => [['Friends',['Yoda',['Obiwan',1]]],['Enemies',['Palpatine',['Darth Vader',3]]]] %> + <%= radio_button_tag :gender, :value => 'male' %> + <%= radio_button_tag :gender, :value => 'female' %> + <%= submit_tag %> + <% end %> +<% end %> + +<% form_tag '/advanced', :id => 'advanced', :class => 'advanced-form', :method => 'get' do %> + <%= error_messages_for MarkupUser.new, :header_message => "There are problems with saving user!" %> + <%= hidden_field_tag :session_id, :value => "__secret__" %> + <% field_set_tag "Advanced", :class => 'advanced-field-set' do %> +

+ <%= label_tag :username, :class => 'first', :caption => "Nickname" %> + <%= text_field_tag :username, :value => params[:username], :id => 'the_username' %> +

+

+ <%= label_tag :password, :class => 'first' %> + <%= password_field_tag :password, :value => params[:password] %> +

+

+ <%= label_tag :email, :caption => 'Email Address' %> + <%= email_field_tag :email, :class => 'string' %> +

+

+ <%= label_tag :age, :class => 'age' %> + <%= number_field_tag :age, :class => 'numeric' %> +

+

+ <%= label_tag :telephone, :class => 'telephone' %> + <%= telephone_field_tag :telephone, :class => 'numeric' %> +

+

+ <%= label_tag :webpage, :caption => 'Your Home Page' %> + <%= url_field_tag :webpage, :class => 'string' %> +

+

+ <%= label_tag :search %> + <%= search_field_tag :search, :class => 'string' %> +

+

+ <%= label_tag :about, :class => 'about', :caption => "About Me" %> + <%= text_area_tag :about, :class => 'large' %> +

+

+ <%= label_tag :photo, :class => 'photo' %> + <%= file_field_tag :photo, :class => 'upload' %> +

+

+ <%= label_tag :gender, :class => 'gender' %> + <%= radio_button_tag :gender, :value => 'male', :checked => true %> + <%= radio_button_tag :remember_me, :value => 'female' %> +

+

+ <%= label_tag :fav_color %> + <%= select_tag :fav_color, :options => [ ['green', '1'], ['orange', '2'], ['purple', '3'] ], :selected => '2' %> +

+

+ <%= check_box_tag :remember_me, :value => '1', :checked => true %> +

+

+ <%= range_field_tag('ranger_with_min_max', :min => 1, :max => 50) %> + <%= range_field_tag('ranger_with_range', :range => 1..5) %> +

+ <% end %> + <% field_set_tag(:class => 'buttons') do %> + <%= submit_tag "Login" %> + <%= button_tag "Cancel" %> + <%= image_submit_tag "buttons/submit.png" %> + <% end %> +<% end %> + +<% form_tag '/dontprotect', :class => 'no-protection', :protect_from_csrf => false do %> +<% end %> diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_tag.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_tag.haml new file mode 100644 index 00000000..4cf41167 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_tag.haml @@ -0,0 +1,78 @@ +- form_tag '/simple', :class => 'simple-form' do + = error_messages_for nil + - field_set_tag do + = hidden_field_tag :session_id, :value => "__secret__" + = label_tag :username + = text_field_tag :username + = label_tag :password + = password_field_tag :password + = label_tag :email + = email_field_tag :email + = label_tag :age + = number_field_tag :age + = label_tag :telephone + = telephone_field_tag :telephone + = label_tag :webpage + = url_field_tag :webpage + = label_tag :search + = search_field_tag :search + = label_tag :color + = select_tag :color, :options => ['green', 'orange', 'purple'] + = select_tag :type, :grouped_options => { 'foo' => ['foo', 'bar'], 'bar' => ['foo', 'bar'] } + = select_tag :character, :grouped_options => [['Friends',['Yoda',['Obiwan',1]]],['Enemies',['Palpatine',['Darth Vader',3]]]] + = label_tag :gender + = radio_button_tag :gender, :value => 'male' + = radio_button_tag :gender, :value => 'female' + = check_box_tag :remember_me + = submit_tag + +- form_tag '/advanced', :id => 'advanced', :class => 'advanced-form', :method => 'get' do + = error_messages_for MarkupUser.new, :header_message => "There are problems with saving user!" + = hidden_field_tag :session_id, :value => "__secret__" + - field_set_tag "Advanced", :class => 'advanced-field-set' do + %p + = label_tag :username, :class => 'first', :caption => "Nickname" + = text_field_tag :username, :value => params[:username], :id => 'the_username' + %p + = label_tag :password, :class => 'first' + = password_field_tag :password, :value => params[:password] + %p + = label_tag :email, :caption => 'Email Address' + = email_field_tag :email, :class => 'string' + %p + = label_tag :age, :class => 'age' + = number_field_tag :age, :class => 'numeric' + %p + = label_tag :telephone, :class => 'telephone' + = telephone_field_tag :telephone, :class => 'numeric' + %p + = label_tag :webpage, :caption => 'Your Home Page' + = url_field_tag :webpage, :class => 'string' + %p + = label_tag :search + = search_field_tag :search, :class => 'string' + %p + = label_tag :about, :class => 'about', :caption => "About Me" + = text_area_tag :about, :class => 'large' + %p + = label_tag :gender, :class => 'gender' + = radio_button_tag :gender, :value => 'male', :checked => true + = radio_button_tag :gender, :value => 'female' + %p + = label_tag :photo, :class => 'photo' + = file_field_tag :photo, :class => 'upload' + %p + = label_tag :fav_color + = select_tag :fav_color, :options => [ ['green', '1'], ['orange', '2'], ['purple', '3'] ], :selected => '2' + %p + = check_box_tag :remember_me, :value => "1", :checked => true + %p + = range_field_tag('ranger_with_min_max', :min => 1, :max => 50) + = range_field_tag('ranger_with_range', :range => 1..5) + - field_set_tag(:class => 'buttons') do + = submit_tag "Login" + = button_tag "Cancel" + = image_submit_tag "buttons/submit.png" + +- form_tag '/dontprotect', :class => 'no-protection', :protect_from_csrf => false do + = submit_tag "Login" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_tag.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_tag.slim new file mode 100644 index 00000000..ee651cb5 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/form_tag.slim @@ -0,0 +1,79 @@ += form_tag '/simple', :class => 'simple-form' do + = error_messages_for nil + = field_set_tag do + = hidden_field_tag :session_id, :value => "__secret__" + = label_tag :username + = text_field_tag :username + = label_tag :password + = password_field_tag :password + = label_tag :email + = email_field_tag :email + = label_tag :age + = number_field_tag :age + = label_tag :telephone + = telephone_field_tag :telephone + = label_tag :webpage + = url_field_tag :webpage + = label_tag :search + = search_field_tag :search + = label_tag :color + = select_tag :color, :options => ['green', 'orange', 'purple'] + = select_tag :type, :grouped_options => { 'foo' => ['foo', 'bar'], 'bar' => ['foo', 'bar'] } + = select_tag :character, :grouped_options => [['Friends',['Yoda',['Obiwan',1]]],['Enemies',['Palpatine',['Darth Vader',3]]]] + = label_tag :gender + = radio_button_tag :gender, :value => 'male' + = radio_button_tag :gender, :value => 'female' + = check_box_tag :remember_me + = submit_tag + += form_tag '/advanced', :id => 'advanced', :class => 'advanced-form', :method => 'get' do + = error_messages_for MarkupUser.new, :header_message => "There are problems with saving user!" + = hidden_field_tag :session_id, :value => "__secret__" + = field_set_tag "Advanced", :class => 'advanced-field-set' do + p + = label_tag :username, :class => 'first', :caption => "Nickname" + = text_field_tag :username, :value => params[:username], :id => 'the_username' + p + = label_tag :password, :class => 'first' + = password_field_tag :password, :value => params[:password] + p + = label_tag :email, :caption => 'Email Address' + = email_field_tag :email, :class => 'string' + p + = label_tag :age, :class => 'age' + = number_field_tag :age, :class => 'numeric' + p + = label_tag :telephone, :class => 'telephone' + = telephone_field_tag :telephone, :class => 'numeric' + p + = label_tag :webpage, :caption => 'Your Home Page' + = url_field_tag :webpage, :class => 'string' + p + = label_tag :search + = search_field_tag :search, :class => 'string' + p + = label_tag :about, :class => 'about', :caption => "About Me" + = text_area_tag :about, :class => 'large' + p + = label_tag :gender, :class => 'gender' + = radio_button_tag :gender, :value => 'male', :checked => true + = radio_button_tag :gender, :value => 'female' + p + = label_tag :photo, :class => 'photo' + = file_field_tag :photo, :class => 'upload' + p + = label_tag :fav_color + = select_tag :fav_color, :options => [ ['green', '1'], ['orange', '2'], ['purple', '3'] ], :selected => '2' + p + = check_box_tag :remember_me, :value => "1", :checked => true + p + = range_field_tag('ranger_with_min_max', :min => 1, :max => 50) + = range_field_tag('ranger_with_range', :range => 1..5) + + = field_set_tag(:class => 'buttons') do + = submit_tag "Login" + = button_tag "Cancel" + = image_submit_tag "buttons/submit.png" + += form_tag '/dontprotect', :class => 'no-protection', :protect_from_csrf => false do + = submit_tag "Login" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/link_to.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/link_to.erb new file mode 100644 index 00000000..56631c4f --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/link_to.erb @@ -0,0 +1,5 @@ +<%= link_to "Test 1 No Block", '/test1', :class => 'test', :id => 'test1' %> + +<% link_to("/test2", :class => 'test', :id => 'test2') do %> + Test 2 With Block +<% end %> diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/link_to.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/link_to.haml new file mode 100644 index 00000000..b53277d4 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/link_to.haml @@ -0,0 +1,4 @@ += link_to "Test 1 No Block", '/test1', :class => 'test', :id => 'test1' + +- link_to("/test2", :class => 'test', :id => 'test2') do + %span Test 2 With Block diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/link_to.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/link_to.slim new file mode 100644 index 00000000..01392638 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/link_to.slim @@ -0,0 +1,4 @@ += link_to "Test 1 No Block", '/test1', :class => 'test', :id => 'test1' + += link_to("/test2", :class => 'test', :id => 'test2') do + span Test 2 With Block diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/mail_to.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/mail_to.erb new file mode 100644 index 00000000..a0b54128 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/mail_to.erb @@ -0,0 +1,3 @@ +

<%= mail_to 'test@demo.com' %>

+ +

<%= mail_to 'test@demo.com', "Click my Email" %>

diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/mail_to.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/mail_to.haml new file mode 100644 index 00000000..4cd7b791 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/mail_to.haml @@ -0,0 +1,3 @@ +%p.simple= mail_to 'test@demo.com' + +%p.captioned= mail_to 'test@demo.com', "Click my Email" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/mail_to.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/mail_to.slim new file mode 100644 index 00000000..9a8e10f1 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/mail_to.slim @@ -0,0 +1,3 @@ +p.simple= mail_to 'test@demo.com' + +p.captioned= mail_to 'test@demo.com', "Click my Email" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/meta_tag.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/meta_tag.erb new file mode 100644 index 00000000..a9d086d3 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/meta_tag.erb @@ -0,0 +1,3 @@ +<%= meta_tag "weblog,news", :name => "keywords" %> + +<%= meta_tag "text/html; charset=UTF-8", :"http-equiv" => "Content-Type" %> diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/meta_tag.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/meta_tag.haml new file mode 100644 index 00000000..9ed5ae35 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/meta_tag.haml @@ -0,0 +1,3 @@ += meta_tag "weblog,news", :name => "keywords" + += meta_tag "text/html; charset=UTF-8", :"http-equiv" => "Content-Type" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/meta_tag.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/meta_tag.slim new file mode 100644 index 00000000..9ed5ae35 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/meta_tag.slim @@ -0,0 +1,3 @@ += meta_tag "weblog,news", :name => "keywords" + += meta_tag "text/html; charset=UTF-8", :"http-equiv" => "Content-Type" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/partials/_erb.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/partials/_erb.erb new file mode 100644 index 00000000..365e638f --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/partials/_erb.erb @@ -0,0 +1 @@ +<%= current_engine %> diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/partials/_haml.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/partials/_haml.haml new file mode 100644 index 00000000..790066c9 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/partials/_haml.haml @@ -0,0 +1 @@ +=current_engine diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/partials/_slim.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/partials/_slim.slim new file mode 100644 index 00000000..839716be --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/partials/_slim.slim @@ -0,0 +1 @@ += current_engine diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/simple_partial.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/simple_partial.erb new file mode 100644 index 00000000..1bfd39ae --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/simple_partial.erb @@ -0,0 +1 @@ +

<%= partial 'partials/erb', :engine => "erb" %>

diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/simple_partial.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/simple_partial.haml new file mode 100644 index 00000000..bc120c58 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/simple_partial.haml @@ -0,0 +1 @@ +%p.haml= partial 'partials/haml', :engine => "haml" diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/simple_partial.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/simple_partial.slim new file mode 100644 index 00000000..ca16c418 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/markup_app/views/simple_partial.slim @@ -0,0 +1 @@ +p.slim= partial 'partials/slim', :engine => "slim" \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/app.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/app.rb new file mode 100644 index 00000000..bf4bc057 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/app.rb @@ -0,0 +1,58 @@ +PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT +PADRINO_ENV = 'test' unless defined? PADRINO_ENV + +require 'padrino-core' +require 'slim' + +class RenderUser + attr_accessor :name + def initialize(name); @name = name; end +end + +class RenderDemo < Padrino::Application + register Padrino::Rendering + register Padrino::Helpers + + configure do + set :logging, false + set :padrino_logging, false + set :environment, :test + set :erb, :engine_class => Padrino::Erubis::SafeBufferTemplate + set :haml, :escape_html => true + set :slim, :generator => Temple::Generators::RailsOutputBuffer + end + + # get current engines from partials + get '/current_engine' do + render :current_engine + end + + # get current engines from explicit engine partials + get '/explicit_engine' do + render :explicit_engine + end + + get '/double_capture_:ext' do + render "double_capture_#{params[:ext]}" + end + + # partial with object + get '/partial/object' do + partial 'template/user', :object => RenderUser.new('John'), :locals => { :extra => "bar" } + end + + # partial with collection + get '/partial/collection' do + partial 'template/user', :collection => [RenderUser.new('John'), RenderUser.new('Billy')], :locals => { :extra => "bar" } + end + + # partial with locals + get '/partial/locals' do + partial 'template/user', :locals => { :user => RenderUser.new('John'), :extra => "bar" } + end + + # partial starting with forward slash + get '/partial/foward_slash' do + partial '/template/user', :object => RenderUser.new('John'), :locals => { :extra => "bar" } + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/current_engine.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/current_engine.haml new file mode 100644 index 00000000..e49423d1 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/current_engine.haml @@ -0,0 +1,5 @@ +%p.start= current_engine +%p.haml= partial 'current_engines/haml' +%p.erb= partial 'current_engines/erb' +%p.slim= partial 'current_engines/slim' +%p.end= current_engine diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/current_engines/_erb.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/current_engines/_erb.erb new file mode 100644 index 00000000..d10c2b3b --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/current_engines/_erb.erb @@ -0,0 +1 @@ +<%= current_engine %> diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/current_engines/_haml.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/current_engines/_haml.haml new file mode 100644 index 00000000..4db543bc --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/current_engines/_haml.haml @@ -0,0 +1 @@ +%span=current_engine diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/current_engines/_slim.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/current_engines/_slim.slim new file mode 100644 index 00000000..480cb50b --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/current_engines/_slim.slim @@ -0,0 +1 @@ +span=current_engine diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/double_capture_erb.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/double_capture_erb.erb new file mode 100644 index 00000000..c7f7e123 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/double_capture_erb.erb @@ -0,0 +1,3 @@ +<% form_for( :object, '/' ) do |f| %> + <%= $number_of_captures += 1 %> +<% end %> \ No newline at end of file diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/double_capture_haml.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/double_capture_haml.haml new file mode 100644 index 00000000..26102762 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/double_capture_haml.haml @@ -0,0 +1,2 @@ +- form_for :object, '/' do |f| + = $number_of_captures += 1 diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/double_capture_slim.slim b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/double_capture_slim.slim new file mode 100644 index 00000000..26102762 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/double_capture_slim.slim @@ -0,0 +1,2 @@ +- form_for :object, '/' do |f| + = $number_of_captures += 1 diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/erb/test.erb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/erb/test.erb new file mode 100644 index 00000000..6549fd1e --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/erb/test.erb @@ -0,0 +1 @@ +

This is a <%= @template %> template!

diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/explicit_engine.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/explicit_engine.haml new file mode 100644 index 00000000..337ff147 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/explicit_engine.haml @@ -0,0 +1,5 @@ +%p.start= current_engine +%p.haml= partial "current_engines/haml", :engine => :haml +%p.erb= partial 'current_engines/erb', :engine => :erb +%p.slim= partial 'current_engines/slim', :engine => :slim +%p.end= current_engine diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/haml/test.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/haml/test.haml new file mode 100644 index 00000000..352e28f6 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/haml/test.haml @@ -0,0 +1 @@ +%h1 This is a #{@template} template! diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/template/_user.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/template/_user.haml new file mode 100644 index 00000000..cba4cc4b --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/template/_user.haml @@ -0,0 +1,7 @@ +%h1 User name is #{user.name} + +- if defined?(extra) + %p Extra is #{extra} + +- if defined?(user_counter) + %p My counter is #{user_counter} diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/template/haml_template.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/template/haml_template.haml new file mode 100644 index 00000000..519fc9d2 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/template/haml_template.haml @@ -0,0 +1 @@ +%h1 This is a #{@template} template sent from render_template! diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/template/some_template.haml b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/template/some_template.haml new file mode 100644 index 00000000..c98a33e5 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/fixtures/render_app/views/template/some_template.haml @@ -0,0 +1,2 @@ + +%h1 This is a haml template which was detected! diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/helper.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/helper.rb new file mode 100644 index 00000000..9038f4ea --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/helper.rb @@ -0,0 +1,67 @@ +require File.expand_path('../../../load_paths', __FILE__) +require File.join(File.dirname(__FILE__), '..', '..', 'padrino-core', 'test', 'mini_shoulda') +require 'rack/test' +require 'webrat' +require 'padrino-helpers' +require 'active_support/time' + +class MiniTest::Spec + include Padrino::Helpers::OutputHelpers + include Padrino::Helpers::TagHelpers + include Padrino::Helpers::AssetTagHelpers + include Rack::Test::Methods + include Webrat::Methods + include Webrat::Matchers + + Webrat.configure do |config| + config.mode = :rack + end + + def stop_time_for_test + time = Time.now + Time.stubs(:now).returns(time) + return time + end + + # assert_has_tag(:h1, :content => "yellow") { "

yellow

" } + # In this case, block is the html to evaluate + def assert_has_tag(name, attributes = {}, &block) + html = block && block.call + assert html.html_safe?, 'html_safe? failed' + matcher = HaveSelector.new(name, attributes) + raise "Please specify a block!" if html.blank? + assert matcher.matches?(html), matcher.failure_message + end + + # assert_has_no_tag, tag(:h1, :content => "yellow") { "

green

" } + # In this case, block is the html to evaluate + def assert_has_no_tag(name, attributes = {}, &block) + html = block && block.call + attributes.merge!(:count => 0) + matcher = HaveSelector.new(name, attributes) + raise "Please specify a block!" if html.blank? + assert matcher.matches?(html), matcher.failure_message + end + + # Asserts that a file matches the pattern + def assert_match_in_file(pattern, file) + assert File.exist?(file), "File '#{file}' does not exist!" + assert_match pattern, File.read(file) + end + + # mock_model("Business", :new_record? => true) => + def mock_model(klazz, options={}) + options.reverse_merge!(:class => klazz, :new_record? => false, :id => 20, :errors => {}) + record = stub(options) + record.stubs(:to_ary => [record]) + record + end +end + +module Webrat + module Logging + def logger # @private + @logger = nil + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_asset_tag_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_asset_tag_helpers.rb new file mode 100644 index 00000000..afa5d678 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_asset_tag_helpers.rb @@ -0,0 +1,359 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require File.expand_path(File.dirname(__FILE__) + '/fixtures/markup_app/app') + +describe "AssetTagHelpers" do + include Padrino::Helpers::AssetTagHelpers + + def app + MarkupDemo + end + + def flash + @_flash ||= { :notice => "Demo notice" } + end + + context 'for #flash_tag method' do + should "display flash with no given attributes" do + assert_has_tag('div.notice', :content => "Demo notice") { flash_tag(:notice) } + end + should "display flash with given attributes" do + actual_html = flash_tag(:notice, :class => 'notice', :id => 'notice-area') + assert_has_tag('div.notice#notice-area', :content => "Demo notice") { actual_html } + end + should "display multiple flash tags with given attributes" do + flash[:error] = 'wrong' + flash[:success] = 'okey' + actual_html = flash_tag(:success, :warning, :error, :id => 'area') + assert_has_tag('div.success#area', :content => flash[:success]) { actual_html } + assert_has_tag('div.error#area', :content => flash[:error]) { actual_html } + assert_has_no_tag('div.notice') { actual_html } + end + end + + context 'for #link_to method' do + should "display link element with no given attributes" do + assert_has_tag('a', :content => "Sign up", :href => '/register') { link_to('Sign up', '/register') } + end + + should "display link element with given attributes" do + actual_html = link_to('Sign up', '/register', :class => 'first', :id => 'linky') + assert_has_tag('a#linky.first', :content => "Sign up", :href => '/register') { actual_html } + end + + should "display link element with anchor attribute" do + actual_html = link_to("Anchor", "/anchor", :anchor => :foo) + assert_has_tag('a', :content => "Anchor", :href => '/anchor#foo') { actual_html } + end + + should "display link element with void url and options" do + actual_link = link_to('Sign up', :class => "test") + assert_has_tag('a', :content => "Sign up", :href => '#', :class => 'test') { actual_link } + end + + should "display link element with remote option" do + actual_link = link_to('Sign up', '/register', :remote => true) + assert_has_tag('a', :content => "Sign up", :href => '/register', 'data-remote' => 'true') { actual_link } + end + + should "display link element with method option" do + actual_link = link_to('Sign up', '/register', :method => :delete) + assert_has_tag('a', :content => "Sign up", :href => '/register', 'data-method' => 'delete', :rel => 'nofollow') { actual_link } + end + + should "display link element with confirm option" do + actual_link = link_to('Sign up', '/register', :confirm => "Are you sure?") + assert_has_tag('a', :content => "Sign up", :href => '/register', 'data-confirm' => 'Are you sure?') { actual_link } + end + + should "display link element with ruby block" do + actual_link = link_to('/register', :class => 'first', :id => 'binky') { "Sign up" } + assert_has_tag('a#binky.first', :content => "Sign up", :href => '/register') { actual_link } + end + + should "escape the link text" do + actual_link = link_to('/register', :class => 'first', :id => 'binky') { "<&>" } + assert_has_tag('a#binky.first', :href => '/register') { actual_link } + assert_match "<&>", actual_link + end + + should "not escape image_tag" do + actual_link = link_to(image_tag("/my/fancy/image.png"), :class => 'first', :id => 'binky') + assert_has_tag('img', :src => "/my/fancy/image.png") { actual_link } + end + + should "display link block element in haml" do + visit '/haml/link_to' + assert_have_selector :a, :content => "Test 1 No Block", :href => '/test1', :class => 'test', :id => 'test1' + assert_have_selector :a, :content => "Test 2 With Block", :href => '/test2', :class => 'test', :id => 'test2' + end + + should "display link block element in erb" do + visit '/erb/link_to' + assert_have_selector :a, :content => "Test 1 No Block", :href => '/test1', :class => 'test', :id => 'test1' + assert_have_selector :a, :content => "Test 2 With Block", :href => '/test2', :class => 'test', :id => 'test2' + end + + should "display link block element in slim" do + visit '/slim/link_to' + assert_have_selector :a, :content => "Test 1 No Block", :href => '/test1', :class => 'test', :id => 'test1' + assert_have_selector :a, :content => "Test 2 With Block", :href => '/test2', :class => 'test', :id => 'test2' + end + end + + context 'for #mail_to method' do + should "display link element for mail to no caption" do + actual_html = mail_to('test@demo.com') + assert_has_tag(:a, :href => "mailto:test@demo.com", :content => 'test@demo.com') { actual_html } + end + + should "display link element for mail to with caption" do + actual_html = mail_to('test@demo.com', "My Email", :class => 'demo') + assert_has_tag(:a, :href => "mailto:test@demo.com", :content => 'My Email', :class => 'demo') { actual_html } + end + + should "display link element for mail to with caption and mail options" do + actual_html = mail_to('test@demo.com', "My Email", :subject => 'demo test', :class => 'demo', :cc => 'foo@test.com') + assert_has_tag(:a, :class => 'demo') { actual_html } + assert_match %r{mailto\:test\@demo.com\?}, actual_html + assert_match %r{cc=foo\@test\.com}, actual_html + assert_match %r{subject\=demo\%20test}, actual_html + end + + should "escape & with encoded string and & in HTML" do + actual_html = mail_to('test@demo.com', "My&Email", :subject => "this&that") + assert_match 'this%26that', actual_html + assert_match 'My&Email', actual_html + end + + should "display mail link element in haml" do + visit '/haml/mail_to' + assert_have_selector 'p.simple a', :href => 'mailto:test@demo.com', :content => 'test@demo.com' + assert_have_selector 'p.captioned a', :href => 'mailto:test@demo.com', :content => 'Click my Email' + end + + should "display mail link element in erb" do + visit '/erb/mail_to' + assert_have_selector 'p.simple a', :href => 'mailto:test@demo.com', :content => 'test@demo.com' + assert_have_selector 'p.captioned a', :href => 'mailto:test@demo.com', :content => 'Click my Email' + end + + should "display mail link element in slim" do + visit '/slim/mail_to' + assert_have_selector 'p.simple a', :href => 'mailto:test@demo.com', :content => 'test@demo.com' + assert_have_selector 'p.captioned a', :href => 'mailto:test@demo.com', :content => 'Click my Email' + end + end + + context 'for #meta_tag method' do + should "display meta tag with given content and name" do + actual_html = meta_tag("weblog,news", :name => "keywords") + assert_has_tag("meta", :name => "keywords", "content" => "weblog,news") { actual_html } + end + + should "display meta tag with given content and http-equiv" do + actual_html = meta_tag("text/html; charset=UTF-8", :"http-equiv" => "Content-Type") + assert_has_tag("meta", :"http-equiv" => "Content-Type", "content" => "text/html; charset=UTF-8") { actual_html } + end + + should "display meta tag element in haml" do + visit '/haml/meta_tag' + assert_have_selector 'meta', "content" => "weblog,news", :name => "keywords" + assert_have_selector 'meta', "content" => "text/html; charset=UTF-8", :"http-equiv" => "Content-Type" + end + + should "display meta tag element in erb" do + visit '/erb/meta_tag' + assert_have_selector 'meta', "content" => "weblog,news", :name => "keywords" + assert_have_selector 'meta', "content" => "text/html; charset=UTF-8", :"http-equiv" => "Content-Type" + end + + should "display meta tag element in slim" do + visit '/slim/meta_tag' + assert_have_selector 'meta', "content" => "weblog,news", :name => "keywords" + assert_have_selector 'meta', "content" => "text/html; charset=UTF-8", :"http-equiv" => "Content-Type" + end + end + + context 'for #image_tag method' do + should "display image tag absolute link with no options" do + time = stop_time_for_test + assert_has_tag('img', :src => "/absolute/pic.gif") { image_tag('/absolute/pic.gif') } + end + + should "display image tag relative link with specified uri root" do + time = stop_time_for_test + self.class.stubs(:uri_root).returns("/blog") + assert_has_tag('img', :src => "/blog/images/relative/pic.gif?#{time.to_i}") { image_tag('relative/pic.gif') } + end + + should "display image tag relative link with options" do + time = stop_time_for_test + assert_has_tag('img.photo', :src => "/images/relative/pic.gif?#{time.to_i}") { + image_tag('relative/pic.gif', :class => 'photo') } + end + + should "display image tag uri link with options" do + time = stop_time_for_test + assert_has_tag('img.photo', :src => "http://demo.org/pic.gif") { image_tag('http://demo.org/pic.gif', :class => 'photo') } + end + + should "display image tag relative link with incorrect spacing" do + time = stop_time_for_test + assert_has_tag('img.photo', :src => "/images/%20relative/%20pic.gif%20%20?#{time.to_i}") { + image_tag(' relative/ pic.gif ', :class => 'photo') + } + end + + should "not use a timestamp if stamp setting is false" do + assert_has_tag('img', :src => "/absolute/pic.gif") { image_tag('/absolute/pic.gif') } + end + + should "have xhtml convention tag" do + assert_equal image_tag('/absolute/pic.gif'), '' + end + end + + context 'for #stylesheet_link_tag method' do + should "display stylesheet link item" do + time = stop_time_for_test + actual_html = stylesheet_link_tag('style') + expected_options = { :media => "screen", :rel => "stylesheet", :type => "text/css" } + assert_has_tag('link', expected_options.merge(:href => "/stylesheets/style.css?#{time.to_i}")) { actual_html } + assert actual_html.html_safe? + end + + should "display stylesheet link item for long relative path" do + time = stop_time_for_test + expected_options = { :media => "screen", :rel => "stylesheet", :type => "text/css" } + actual_html = stylesheet_link_tag('example/demo/style') + assert_has_tag('link', expected_options.merge(:href => "/stylesheets/example/demo/style.css?#{time.to_i}")) { actual_html } + end + + should "display stylesheet link item with absolute path" do + time = stop_time_for_test + expected_options = { :media => "screen", :rel => "stylesheet", :type => "text/css" } + actual_html = stylesheet_link_tag('/css/style') + assert_has_tag('link', expected_options.merge(:href => "/css/style.css")) { actual_html } + end + + should "display stylesheet link item with uri root" do + self.class.stubs(:uri_root).returns("/blog") + time = stop_time_for_test + expected_options = { :media => "screen", :rel => "stylesheet", :type => "text/css" } + actual_html = stylesheet_link_tag('style') + assert_has_tag('link', expected_options.merge(:href => "/blog/stylesheets/style.css?#{time.to_i}")) { actual_html } + end + + should "display stylesheet link items" do + time = stop_time_for_test + actual_html = stylesheet_link_tag('style', 'layout.css', 'http://google.com/style.css') + assert_has_tag('link', :media => "screen", :rel => "stylesheet", :type => "text/css", :count => 3) { actual_html } + assert_has_tag('link', :href => "/stylesheets/style.css?#{time.to_i}") { actual_html } + assert_has_tag('link', :href => "/stylesheets/layout.css?#{time.to_i}") { actual_html } + assert_has_tag('link', :href => "http://google.com/style.css") { actual_html } + assert_equal actual_html, stylesheet_link_tag(['style', 'layout.css', 'http://google.com/style.css']) + end + + should "not use a timestamp if stamp setting is false" do + self.class.expects(:asset_stamp).returns(false) + expected_options = { :media => "screen", :rel => "stylesheet", :type => "text/css" } + assert_has_tag('link', expected_options.merge(:href => "/stylesheets/style.css")) { stylesheet_link_tag('style') } + end + end + + context 'for #javascript_include_tag method' do + should "display javascript item" do + time = stop_time_for_test + actual_html = javascript_include_tag('application') + assert_has_tag('script', :src => "/javascripts/application.js?#{time.to_i}", :type => "text/javascript") { actual_html } + assert actual_html.html_safe? + end + + should "display javascript item for long relative path" do + time = stop_time_for_test + actual_html = javascript_include_tag('example/demo/application') + assert_has_tag('script', :src => "/javascripts/example/demo/application.js?#{time.to_i}", :type => "text/javascript") { actual_html } + end + + should "display javascript item for path containing js" do + time = stop_time_for_test + actual_html = javascript_include_tag 'test/jquery.json' + assert_has_tag('script', :src => "/javascripts/test/jquery.json?#{time.to_i}", :type => "text/javascript") { actual_html } + end + + should "display javascript item for path containing period" do + time = stop_time_for_test + actual_html = javascript_include_tag 'test/jquery.min' + assert_has_tag('script', :src => "/javascripts/test/jquery.min.js?#{time.to_i}", :type => "text/javascript") { actual_html } + end + + should "display javascript item with absolute path" do + time = stop_time_for_test + actual_html = javascript_include_tag('/js/application') + assert_has_tag('script', :src => "/js/application.js", :type => "text/javascript") { actual_html } + end + + should "display javascript item with uri root" do + self.class.stubs(:uri_root).returns("/blog") + time = stop_time_for_test + actual_html = javascript_include_tag('application') + assert_has_tag('script', :src => "/blog/javascripts/application.js?#{time.to_i}", :type => "text/javascript") { actual_html } + end + + should "not append extension to absolute paths" do + time = stop_time_for_test + actual_html = javascript_include_tag('https://maps.googleapis.com/maps/api/js?key=value&sensor=false') + assert_has_tag('script', :src => "https://maps.googleapis.com/maps/api/js?key=value&sensor=false") { actual_html } + end + + should "display javascript items" do + time = stop_time_for_test + actual_html = javascript_include_tag('application', 'base.js', 'http://google.com/lib.js') + assert_has_tag('script', :type => "text/javascript", :count => 3) { actual_html } + assert_has_tag('script', :src => "/javascripts/application.js?#{time.to_i}") { actual_html } + assert_has_tag('script', :src => "/javascripts/base.js?#{time.to_i}") { actual_html } + assert_has_tag('script', :src => "http://google.com/lib.js") { actual_html } + assert_equal actual_html, javascript_include_tag(['application', 'base.js', 'http://google.com/lib.js']) + end + + should "not use a timestamp if stamp setting is false" do + self.class.expects(:asset_stamp).returns(false) + actual_html = javascript_include_tag('application') + assert_has_tag('script', :src => "/javascripts/application.js", :type => "text/javascript") { actual_html } + end + end + + context "for #favicon_tag method" do + should "display favicon" do + time = stop_time_for_test + actual_html = favicon_tag('icons/favicon.png') + assert_has_tag('link', :rel => 'icon', :type => 'image/png', :href => "/images/icons/favicon.png?#{time.to_i}") { actual_html } + end + + should "match type with file ext" do + time = stop_time_for_test + actual_html = favicon_tag('favicon.ico') + assert_has_tag('link', :rel => 'icon', :type => 'image/ico', :href => "/images/favicon.ico?#{time.to_i}") { actual_html } + end + + should "allow option overrides" do + time = stop_time_for_test + actual_html = favicon_tag('favicon.png', :type => 'image/ico') + assert_has_tag('link', :rel => 'icon', :type => 'image/ico', :href => "/images/favicon.png?#{time.to_i}") { actual_html } + end + end + + context 'for #feed_tag method' do + should "generate correctly link tag for rss" do + assert_has_tag('link', :type => 'application/rss+xml', :rel => 'alternate', :href => "/blog/post.rss", :title => 'rss') { feed_tag :rss, "/blog/post.rss" } + end + + should "generate correctly link tag for atom" do + assert_has_tag('link', :type => 'application/atom+xml', :rel => 'alternate', :href => "/blog/post.atom", :title => 'atom') { feed_tag :atom, "/blog/post.atom" } + end + + should "override options" do + assert_has_tag('link', :type => 'my-type', :rel => 'my-rel', :href => "/blog/post.rss", :title => 'my-title') { feed_tag :rss, "/blog/post.rss", :type => "my-type", :rel => "my-rel", :title => "my-title" } + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_breadcrumb_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_breadcrumb_helpers.rb new file mode 100644 index 00000000..ff4e0b80 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_breadcrumb_helpers.rb @@ -0,0 +1,134 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +describe "BreadcrumbHelpers" do + include Padrino::Helpers::Breadcrumbs + + def breadcrumb + @breadcrumb ||= Padrino::Helpers::Breadcrumb.new + end + + before(:each) { breadcrumb.reset! } + + context "for Breadcrumbs#breadcrumbs method" do + should "support breadcrumbs which is Padrino::Helpers::Breadcrumbs instance." do + breadcrumb.add "foo", "/foo", "foo link" + assert_has_tag(:a, :content => "Foo link", :href => "/foo") { breadcrumbs(breadcrumb) } + end + + should "support bootstrap" do + breadcrumb.add "foo", "/foo", "foo link" + assert_has_tag(:span, :content => "/", :class => "divider") { breadcrumbs(breadcrumb, true) } + end + + should "support active" do + breadcrumb.add "foo", "/foo", "foo link" + assert_has_tag(:li, :class => "custom-active") { breadcrumbs(breadcrumb, nil, "custom-active") } + end + + should "support options" do + assert_has_tag(:ul, :class => "breadcrumbs-class breadcrumb", :id => "breadcrumbs-id") do + breadcrumbs(breadcrumb, nil, nil, :id => "breadcrumbs-id", :class => "breadcrumbs-class") + end + end + end + + context "for #add method" do + should "support name of string and symbol type" do + breadcrumb.add "foo", "/foo", "Foo Link" + breadcrumb.add :bar, "/bar", "Bar Link" + + actual_html = breadcrumbs(breadcrumb) + assert_has_tag(:a, :content => "Foo link", :href => "/foo") { actual_html } + assert_has_tag(:a, :content => "Bar link", :href => "/bar") { actual_html } + end + + should "support url" do + breadcrumb.add :foo, "/foo", "Foo Link" + assert_has_tag(:a, :href => "/foo") { breadcrumbs(breadcrumb) } + end + + should "support caption" do + breadcrumb.add :foo, "/foo", "Foo Link" + assert_has_tag(:a, :content => "Foo link") { breadcrumbs(breadcrumb) } + end + + should "support options" do + breadcrumb.add :foo, "/foo", "Foo Link", :id => "foo-id", :class => "foo-class" + breadcrumb.add :bar, "/bar", "Bar Link", :id => "bar-id", :class => "bar-class" + + actual_html = breadcrumbs(breadcrumb) + assert_has_tag(:li, :class => "foo-class", :id => "foo-id") { actual_html } + assert_has_tag(:li, :class => "bar-class active", :id => "bar-id") { actual_html } + end + end + + context "for #del method" do + should "support name of string type" do + breadcrumb.add "foo", "/foo", "Foo Link" + breadcrumb.add :bar, "/bar", "Bar Link" + + breadcrumb.del "foo" + breadcrumb.del "bar" + + actual_html = breadcrumbs(breadcrumb) + assert_has_no_tag(:a, :content => "Foo link", :href => "/foo") { actual_html } + assert_has_no_tag(:a, :content => "Bar link", :href => "/bar") { actual_html } + end + + should "support name of symbol type" do + breadcrumb.add "foo", "/foo", "Foo Link" + breadcrumb.add :bar, "/bar", "Bar Link" + + breadcrumb.del :foo + breadcrumb.del :bar + + actual_html = breadcrumbs(breadcrumb) + assert_has_no_tag(:a, :content => "Foo link", :href => "/foo") { actual_html } + assert_has_no_tag(:a, :content => "Bar link", :href => "/bar") { actual_html } + end + end + + context "for #set_home method" do + should "modified home item elements." do + breadcrumb.set_home("/custom", "Custom Home Page") + assert_has_tag(:a, :content => "Custom home page", :href => "/custom") { breadcrumbs(breadcrumb) } + end + + should "support options" do + breadcrumb.set_home("/custom", "Custom Home Page", :id => "home-id") + + actual_html = breadcrumbs(breadcrumb) + assert_has_tag(:li, :id => "home-id") { actual_html } + assert_has_tag(:a, :content => "Custom home page", :href => "/custom") { actual_html } + end + end + + context "for #reset method" do + should "be #items which contains only home item." do + breadcrumb.set_home("/custom", "Custom Home Page") + breadcrumb.add "foo", "/foo", "Foo Link" + breadcrumb.add :bar, "/bar", "Bar Link" + + breadcrumb.reset + + actual_html = breadcrumbs(breadcrumb) + assert_has_tag(:a, :content => "Custom home page", :href => "/custom") { actual_html } + assert_has_no_tag(:a, :content => "Foo link", :href => "/foo") { actual_html } + assert_has_no_tag(:a, :content => "Bar link", :href => "/bar") { actual_html } + end + end + + context "for #reset! method" do + should "be #items which contains only default home item." do + breadcrumb.add "foo", "/foo", "foo link" + breadcrumb.add :bar, "/bar", "Bar Link" + + breadcrumb.reset! + + actual_html = breadcrumbs(breadcrumb) + assert_has_tag(:a, :content => "Home Page", :href => "/") { actual_html } + assert_has_no_tag(:a, :content => "Foo link", :href => "/foo") { actual_html } + assert_has_no_tag(:a, :content => "Bar link", :href => "/bar") { actual_html } + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_form_builder.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_form_builder.rb new file mode 100644 index 00000000..8a64b7f3 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_form_builder.rb @@ -0,0 +1,1178 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require File.expand_path(File.dirname(__FILE__) + '/fixtures/markup_app/app') + +describe "FormBuilder" do + include Padrino::Helpers::FormHelpers + + def app + MarkupDemo + end + + # Dummy form builder for testing + module Padrino::Helpers::FormBuilder + class FakeFormBuilder < AbstractFormBuilder + def foo_field; @template.content_tag(:span, "bar"); end + end + end + + def setup + role_types = [mock_model('Role', :name => "Admin", :id => 1), + mock_model('Role', :name => 'Moderate', :id => 2), mock_model('Role', :name => 'Limited', :id => 3)] + @user = mock_model("User", :first_name => "Joe", :email => '', :session_id => 54) + @user.stubs(:errors => {:a => "must be present", :b => "must be valid", :email => "Must be valid", :first_name => []}) + @user.stubs(:role_types => role_types, :role => "1", :roles => [1,3]) + @user_none = mock_model("User") + end + + def standard_builder(object=@user) + Padrino::Helpers::FormBuilder::StandardFormBuilder.new(self, object) + end + + context 'for #form_for method' do + should "display correct form html" do + actual_html = form_for(@user, '/register', :id => 'register', :"accept-charset" => "UTF-8", :method => 'post') { "Demo" } + assert_has_tag('form', :"accept-charset" => "UTF-8", :action => '/register', :id => 'register', :method => 'post', :content => "Demo") { actual_html } + assert_has_tag('form input[type=hidden]', :name => '_method', :count => 0) { actual_html } # no method action field + end + + should "display correct form html with fake object" do + actual_html = form_for(:markup_user, '/register', :id => 'register', :"accept-charset" => "UTF-8", :method => 'post') { |f| f.text_field :username } + assert_has_tag('form', :"accept-charset" => "UTF-8", :action => '/register', :id => 'register', :method => 'post') { actual_html } + assert_has_tag('form input', :type => 'text', :name => 'markup_user[username]') { actual_html } + assert_has_tag('form input[type=hidden]', :name => '_method', :count => 0) { actual_html } # no method action field + end + + should "display correct form html for namespaced object" do + actual_html = form_for(Outer::UserAccount.new, '/register', :"accept-charset" => "UTF-8", :method => 'post') { |f| f.text_field :username } + assert_has_tag('form', :"accept-charset" => "UTF-8", :action => '/register', :method => 'post') { actual_html } + assert_has_tag('form input', :type => 'text', :name => 'outer_user_account[username]') { actual_html } + end + + should "display form specifying default builder setting" do + self.expects(:settings).returns(stub(:default_builder => 'FakeFormBuilder', :protect_from_csrf => false)).at_least_once + actual_html = form_for(@user, '/register', :id => 'register', :"accept-charset" => "UTF-8", :method => 'post') { |f| f.foo_field } + assert_has_tag('form', :"accept-charset" => "UTF-8", :action => '/register', :method => 'post') { actual_html } + assert_has_tag('span', :content => "bar") { actual_html } + end + + should "display correct form html with remote option" do + actual_html = form_for(@user, '/update', :"accept-charset" => "UTF-8", :remote => true) { "Demo" } + assert_has_tag('form', :"accept-charset" => "UTF-8", :action => '/update', :method => 'post', "data-remote" => 'true') { actual_html } + end + + should "display correct form html with namespace option" do + actual_html = form_for(@user, '/update', :namespace => 'foo') do |f| + f.text_field(:first_name) << f.fields_for(:role_types) { |role| role.text_field(:name) } + end + + assert_has_no_tag(:form, :namespace => 'foo') { actual_html } + assert_has_tag(:input, :type => 'text', :name => 'user[first_name]', :id => 'foo_user_first_name') { actual_html } + assert_has_tag(:input, :type => 'text', :name => 'user[role_types_attributes][0][name]', :id => 'foo_user_role_types_attributes_0_name') { actual_html } + end + + should "display correct form html with remote option and method put" do + actual_html = form_for(@user, '/update', :"accept-charset" => "UTF-8", :remote => true, :method => 'put') { "Demo" } + assert_has_tag('form', :"accept-charset" => "UTF-8", :method => 'post', "data-remote" => 'true') { actual_html } + assert_has_tag('form input', :type => 'hidden', :name => "_method", :value => 'put') { actual_html } + end + + should "display correct form html with method :put" do + actual_html = form_for(@user, '/update', :"accept-charset" => "UTF-8", :method => 'put') { "Demo" } + assert_has_tag('form', :"accept-charset" => "UTF-8", :action => '/update', :method => 'post') { actual_html } + assert_has_tag('form input', :type => 'hidden', :name => "_method", :value => 'put') { actual_html } + end + + should "display correct form html with method :delete" do + actual_html = form_for(@user, '/destroy', :"accept-charset" => "UTF-8", :method => 'delete') { "Demo" } + assert_has_tag('form', :"accept-charset" => "UTF-8", :action => '/destroy', :method => 'post') { actual_html } + assert_has_tag('form input', :type => 'hidden', :name => "_method", :value => 'delete') { actual_html } + end + + should "display correct form html with multipart" do + actual_html = form_for(@user, '/register', :"accept-charset" => "UTF-8", :multipart => true) { "Demo" } + assert_has_tag('form', :"accept-charset" => "UTF-8", :action => '/register', :enctype => "multipart/form-data") { actual_html } + end + + should "support changing form builder type" do + form_html = proc { form_for(@user, '/register', :"accept-charset" => "UTF-8", :builder => "AbstractFormBuilder") { |f| f.text_field_block(:name) } } + assert_raises(NoMethodError) { form_html.call } + end + + should "support using default standard builder" do + actual_html = form_for(@user, '/register') { |f| f.text_field_block(:name) } + assert_has_tag('form p input[type=text]') { actual_html } + end + + should "display fail for form with nil object" do + assert_raises(RuntimeError) { form_for(@not_real, '/register', :id => 'register', :method => 'post') { "Demo" } } + end + + should "display correct form in haml" do + visit '/haml/form_for' + assert_have_selector :form, :action => '/demo', :id => 'demo' + assert_have_selector :form, :action => '/another_demo', :id => 'demo2', :method => 'get' + assert_have_selector :form, :action => '/third_demo', :id => 'demo3', :method => 'get' + assert_have_selector :input, :name => 'authenticity_token' + end + + should "display correct form in erb" do + visit '/erb/form_for' + assert_have_selector :form, :action => '/demo', :id => 'demo' + assert_have_selector :form, :action => '/another_demo', :id => 'demo2', :method => 'get' + assert_have_selector :form, :action => '/third_demo', :id => 'demo3', :method => 'get' + assert_have_selector :input, :name => 'authenticity_token' + end + + should "display correct form in slim" do + visit '/slim/form_for' + assert_have_selector :form, :action => '/demo', :id => 'demo' + assert_have_selector :form, :action => '/another_demo', :id => 'demo2', :method => 'get' + assert_have_selector :form, :action => '/third_demo', :id => 'demo3', :method => 'get' + assert_have_selector :input, :name => 'authenticity_token' + end + + should "have a class of 'invalid' for fields with errors" do + actual_html = form_for(@user, '/register') {|f| f.text_field(:email) } + assert_has_tag(:input, :type => 'text', :name => 'user[email]', :id => 'user_email', :class => 'invalid') {actual_html } + end + + should "not have a class of 'invalid' for fields with no errors" do + actual_html = form_for(@user, '/register') {|f| f.text_field(:first_name) } + assert_has_no_tag(:input, :type => 'text', :name => 'user[first_name]', :id => 'user_first_name', :class => 'invalid') {actual_html } + end + end + + context 'for #fields_for method' do + should 'display correct fields html' do + actual_html = fields_for(@user) { |f| f.text_field(:first_name) } + assert_has_tag(:input, :type => 'text', :name => 'user[first_name]', :id => 'user_first_name') { actual_html } + end + + should 'display correct fields html with symbol object' do + actual_html = fields_for(:markup_user) { |f| f.text_field(:first_name) } + assert_has_tag(:input, :type => 'text', :name => 'markup_user[first_name]', :id => 'markup_user_first_name') { actual_html } + end + + should "display fail for nil object" do + assert_raises(RuntimeError) { fields_for(@not_real) { |f| "Demo" } } + end + + should 'display correct simple fields in haml' do + visit '/haml/fields_for' + assert_have_selector :form, :action => '/demo1', :id => 'demo-fields-for' + assert_have_selector '#demo-fields-for input', :type => 'text', :name => 'markup_user[gender]', :value => 'male' + assert_have_selector '#demo-fields-for input', :type => 'checkbox', :name => 'permission[can_edit]', :value => '1', :checked => 'checked' + assert_have_selector '#demo-fields-for input', :type => 'checkbox', :name => 'permission[can_delete]' + end + + should "display correct simple fields in erb" do + visit '/erb/fields_for' + assert_have_selector :form, :action => '/demo1', :id => 'demo-fields-for' + assert_have_selector '#demo-fields-for input', :type => 'text', :name => 'markup_user[gender]', :value => 'male' + assert_have_selector '#demo-fields-for input', :type => 'checkbox', :name => 'permission[can_edit]', :value => '1', :checked => 'checked' + assert_have_selector '#demo-fields-for input', :type => 'checkbox', :name => 'permission[can_delete]' + end + + should "display correct simple fields in slim" do + visit '/slim/fields_for' + assert_have_selector :form, :action => '/demo1', :id => 'demo-fields-for' + assert_have_selector '#demo-fields-for input', :type => 'text', :name => 'markup_user[gender]', :value => 'male' + assert_have_selector '#demo-fields-for input', :type => 'checkbox', :name => 'permission[can_edit]', :value => '1', :checked => 'checked' + assert_have_selector '#demo-fields-for input', :type => 'checkbox', :name => 'permission[can_delete]' + end + end + + # =========================== + # AbstractFormBuilder + # =========================== + + context 'for #error_messages method' do + should "display correct form html with no record" do + actual_html = standard_builder(@user_none).error_messages(:header_message => "Demo form cannot be saved") + assert actual_html.blank? + end + + should "display correct form html with valid record" do + actual_html = standard_builder.error_messages(:header_message => "Demo form cannot be saved", :style => "foo:bar", :class => "mine") + assert_has_tag('#field-errors h2', :content => "Demo form cannot be saved") { actual_html } + assert_has_tag('#field-errors ul li', :content => "B must be valid") { actual_html } + assert_has_tag('#field-errors ul li', :content => "A must be present") { actual_html } + assert_has_tag('#field-errors', :style => "foo:bar") { actual_html } + assert_has_tag('#field-errors', :class => "mine") { actual_html } + end + + should "display correct form in haml" do + visit '/haml/form_for' + assert_have_selector '#demo div.field-errors h2', :content => "custom MarkupUser cannot be saved!" + assert_have_selector '#demo div.field-errors ul li', :content => "Fake must be valid" + assert_have_selector '#demo div.field-errors ul li', :content => "Second must be present" + assert_have_selector '#demo div.field-errors ul li', :content => "Third must be a number" + assert_have_selector '#demo2 div.field-errors h2', :content => "custom MarkupUser cannot be saved!" + assert_have_selector '#demo2 div.field-errors ul li', :content => "Fake must be valid" + assert_have_selector '#demo2 div.field-errors ul li', :content => "Second must be present" + assert_have_selector '#demo2 div.field-errors ul li', :content => "Third must be a number" + assert_have_selector '#demo input', :name => 'markup_user[email]', :class => 'string invalid' + end + + should "display correct form in erb" do + visit '/erb/form_for' + assert_have_selector '#demo div.field-errors h2', :content => "custom MarkupUser cannot be saved!" + assert_have_selector '#demo div.field-errors ul li', :content => "Fake must be valid" + assert_have_selector '#demo div.field-errors ul li', :content => "Second must be present" + assert_have_selector '#demo div.field-errors ul li', :content => "Third must be a number" + assert_have_selector '#demo2 div.field-errors h2', :content => "custom MarkupUser cannot be saved!" + assert_have_selector '#demo2 div.field-errors ul li', :content => "Fake must be valid" + assert_have_selector '#demo2 div.field-errors ul li', :content => "Second must be present" + assert_have_selector '#demo2 div.field-errors ul li', :content => "Third must be a number" + assert_have_selector '#demo input', :name => 'markup_user[email]', :class => 'string invalid' + end + + should "display correct form in slim" do + visit '/slim/form_for' + assert_have_selector '#demo div.field-errors h2', :content => "custom MarkupUser cannot be saved!" + assert_have_selector '#demo div.field-errors ul li', :content => "Fake must be valid" + assert_have_selector '#demo div.field-errors ul li', :content => "Second must be present" + assert_have_selector '#demo div.field-errors ul li', :content => "Third must be a number" + assert_have_selector '#demo2 div.field-errors h2', :content => "custom MarkupUser cannot be saved!" + assert_have_selector '#demo2 div.field-errors ul li', :content => "Fake must be valid" + assert_have_selector '#demo2 div.field-errors ul li', :content => "Second must be present" + assert_have_selector '#demo2 div.field-errors ul li', :content => "Third must be a number" + assert_have_selector '#demo input', :name => 'markup_user[email]', :class => 'string invalid' + end + end + + context 'for #error_message_on method' do + should "display correct form html with no record" do + actual_html = standard_builder(@user_none).error_message_on(:name) + assert actual_html.blank? + end + + should "display error for specified invalid object" do + actual_html = standard_builder(@user).error_message_on(:a, :prepend => "foo", :append => "bar") + assert_has_tag('span.error', :content => "foo must be present bar") { actual_html } + end + + should "display error for specified invalid object not matching class name" do + @bob = mock_model("User", :first_name => "Frank", :errors => { :foo => "must be bob" }) + actual_html = standard_builder(@bob).error_message_on(:foo, :prepend => "foo", :append => "bar") + assert_has_tag('span.error', :content => "foo must be bob bar") { actual_html } + end + end + + context 'for #label method' do + should "display correct label html" do + actual_html = standard_builder.label(:first_name, :class => 'large', :caption => "F. Name: ") + assert_has_tag('label', :class => 'large', :for => 'user_first_name', :content => "F. Name: ") { actual_html } + end + + should "set specific content inside the label if a block was provided" do + actual_html = standard_builder.label(:admin, :class => 'large') { input_tag :checkbox } + assert_has_tag('label', :class => 'large', :for => 'user_admin', :content => "Admin: ") { actual_html } + assert_has_tag('label input[type=checkbox]') { actual_html } + end + + should "display correct label in haml" do + visit '/haml/form_for' + assert_have_selector '#demo label', :content => "Login: ", :class => 'user-label' + assert_have_selector '#demo label', :content => "About Me: " + assert_have_selector '#demo2 label', :content => "Nickname: ", :class => 'label' + end + + should "display correct label in erb" do + visit '/erb/form_for' + assert_have_selector '#demo label', :content => "Login: ", :class => 'user-label' + assert_have_selector '#demo label', :content => "About Me: " + assert_have_selector '#demo2 label', :content => "Nickname: ", :class => 'label' + end + + should "display correct label in slim" do + visit '/slim/form_for' + assert_have_selector '#demo label', :content => "Login: ", :class => 'user-label' + assert_have_selector '#demo label', :content => "About Me: " + assert_have_selector '#demo2 label', :content => "Nickname: ", :class => 'label' + end + end + + context 'for #hidden_field method' do + should "display correct hidden field html" do + actual_html = standard_builder.hidden_field(:session_id, :class => 'hidden') + assert_has_tag('input.hidden[type=hidden]', :value => "54", :id => 'user_session_id', :name => 'user[session_id]') { actual_html } + end + + should "display correct hidden field in haml" do + visit '/haml/form_for' + assert_have_selector '#demo input[type=hidden]', :id => 'markup_user_session_id', :value => "45" + assert_have_selector '#demo2 input', :type => 'hidden', :name => 'markup_user[session_id]' + end + + should "display correct hidden field in erb" do + visit '/erb/form_for' + assert_have_selector '#demo input[type=hidden]', :id => 'markup_user_session_id', :value => "45" + assert_have_selector '#demo2 input', :type => 'hidden', :name => 'markup_user[session_id]' + end + + should "display correct hidden field in slim" do + visit '/slim/form_for' + assert_have_selector '#demo input[type=hidden]', :id => 'markup_user_session_id', :value => "45" + assert_have_selector '#demo2 input', :type => 'hidden', :name => 'markup_user[session_id]' + end + end + + context 'for #text_field method' do + should "display correct text field html" do + actual_html = standard_builder.text_field(:first_name, :class => 'large') + assert_has_tag('input.large[type=text]', :value => "Joe", :id => 'user_first_name', :name => 'user[first_name]') { actual_html } + end + + should "display correct text field in haml" do + visit '/haml/form_for' + assert_have_selector '#demo input.user-text[type=text]', :id => 'markup_user_username', :value => "John" + assert_have_selector '#demo2 input', :type => 'text', :class => 'input', :name => 'markup_user[username]' + end + + should "display correct text field in erb" do + visit '/erb/form_for' + assert_have_selector '#demo input.user-text[type=text]', :id => 'markup_user_username', :value => "John" + assert_have_selector '#demo2 input', :type => 'text', :class => 'input', :name => 'markup_user[username]' + end + + should "display correct text field in slim" do + visit '/slim/form_for' + assert_have_selector '#demo input.user-text[type=text]', :id => 'markup_user_username', :value => "John" + assert_have_selector '#demo2 input', :type => 'text', :class => 'input', :name => 'markup_user[username]' + end + end + + context 'for #number_field method' do + should "display correct number field html" do + actual_html = standard_builder.number_field(:age, :class => 'numeric') + assert_has_tag('input.numeric[type=number]', :id => 'user_age', :name => 'user[age]') { actual_html } + end + + should "display correct number field in haml" do + visit '/haml/form_for' + assert_have_selector '#demo input.numeric[type=number]', :id => 'markup_user_age' + end + + should "display correct number field in erb" do + visit '/erb/form_for' + assert_have_selector '#demo input.numeric[type=number]', :id => 'markup_user_age' + end + + should "display correct number field in slim" do + visit '/slim/form_for' + assert_have_selector '#demo input.numeric[type=number]', :id => 'markup_user_age' + end + end + + context 'for #telephone_field method' do + should "display correct telephone field html" do + actual_html = standard_builder.telephone_field(:telephone, :class => 'numeric') + assert_has_tag('input.numeric[type=tel]', :id => 'user_telephone', :name => 'user[telephone]') { actual_html } + end + + should "display correct telephone field in haml" do + visit '/haml/form_for' + assert_have_selector '#demo input.numeric[type=tel]', :id => 'markup_user_telephone' + end + + should "display correct telephone field in erb" do + visit '/erb/form_for' + assert_have_selector '#demo input.numeric[type=tel]', :id => 'markup_user_telephone' + end + + should "display correct telephone field in slim" do + visit '/slim/form_for' + assert_have_selector '#demo input.numeric[type=tel]', :id => 'markup_user_telephone' + end + end + + context 'for #search_field method' do + should "display correct search field html" do + actual_html = standard_builder.search_field(:search, :class => 'string') + assert_has_tag('input.string[type=search]', :id => 'user_search', :name => 'user[search]') { actual_html } + end + + should "display correct search field in haml" do + visit '/haml/form_for' + assert_have_selector '#demo input.string[type=search]', :id => 'markup_user_search' + end + + should "display correct search field in erb" do + visit '/erb/form_for' + assert_have_selector '#demo input.string[type=search]', :id => 'markup_user_search' + end + + should "display correct search field in slim" do + visit '/slim/form_for' + assert_have_selector '#demo input.string[type=search]', :id => 'markup_user_search' + end + end + + context 'for #email_field method' do + should "display correct email field html" do + actual_html = standard_builder.email_field(:email, :class => 'string') + assert_has_tag('input.string[type=email]', :id => 'user_email', :name => 'user[email]') { actual_html } + end + + should "display correct email field in haml" do + visit '/haml/form_for' + assert_have_selector '#demo input.string[type=email]', :id => 'markup_user_email' + end + + should "display correct email field in erb" do + visit '/erb/form_for' + assert_have_selector '#demo input.string[type=email]', :id => 'markup_user_email' + end + + should "display correct email field in slim" do + visit '/slim/form_for' + assert_have_selector '#demo input.string[type=email]', :id => 'markup_user_email' + end + end + + context 'for #url_field method' do + should "display correct url field html" do + actual_html = standard_builder.url_field(:webpage, :class => 'string') + assert_has_tag('input.string[type=url]', :id => 'user_webpage', :name => 'user[webpage]') { actual_html } + end + + should "display correct url field in haml" do + visit '/haml/form_for' + assert_have_selector '#demo input.string[type=url]', :id => 'markup_user_webpage' + end + + should "display correct url field in erb" do + visit '/erb/form_for' + assert_have_selector '#demo input.string[type=url]', :id => 'markup_user_webpage' + end + + should "display correct url field in slim" do + visit '/slim/form_for' + assert_have_selector '#demo input.string[type=url]', :id => 'markup_user_webpage' + end + end + + context 'for #check_box method' do + should "display correct checkbox html" do + actual_html = standard_builder.check_box(:confirm_destroy, :class => 'large') + assert_has_tag('input.large[type=checkbox]', :id => 'user_confirm_destroy', :name => 'user[confirm_destroy]') { actual_html } + assert_has_tag('input[type=hidden]', :name => 'user[confirm_destroy]', :value => '0') { actual_html } + end + + should "display correct checkbox html when checked" do + actual_html = standard_builder.check_box(:confirm_destroy, :checked => true) + assert_has_tag('input[type=checkbox]', :checked => 'checked', :name => 'user[confirm_destroy]') { actual_html } + end + + should "display correct checkbox html as checked when object value matches" do + @user.stubs(:show_favorites => 'human') + actual_html = standard_builder.check_box(:show_favorites, :value => 'human') + assert_has_tag('input[type=checkbox]', :checked => 'checked', :name => 'user[show_favorites]') { actual_html } + end + + should "display correct checkbox html as checked when object value is true" do + @user.stubs(:show_favorites => true) + actual_html = standard_builder.check_box(:show_favorites, :value => '1') + assert_has_tag('input[type=checkbox]', :checked => 'checked', :name => 'user[show_favorites]') { actual_html } + end + + should "display correct checkbox html as unchecked when object value doesn't match" do + @user.stubs(:show_favorites => 'alien') + actual_html = standard_builder.check_box(:show_favorites, :value => 'human') + assert_has_no_tag('input[type=checkbox]', :checked => 'checked') { actual_html } + end + + should "display correct checkbox html as unchecked when object value is false" do + @user.stubs(:show_favorites => false) + actual_html = standard_builder.check_box(:show_favorites, :value => '1') + assert_has_no_tag('input[type=checkbox]', :checked => 'checked') { actual_html } + end + + should "display correct unchecked hidden field when specified" do + actual_html = standard_builder.check_box(:show_favorites, :value => 'female', :uncheck_value => 'false') + assert_has_tag('input[type=hidden]', :name => 'user[show_favorites]', :value => 'false') { actual_html } + end + + should "display correct checkbox in haml" do + visit '/haml/form_for' + assert_have_selector '#demo input[type=checkbox]', :checked => 'checked', :id => 'markup_user_remember_me', :name => 'markup_user[remember_me]' + end + + should "display correct checkbox in erb" do + visit '/erb/form_for' + assert_have_selector '#demo input[type=checkbox]', :checked => 'checked', :id => 'markup_user_remember_me', :name => 'markup_user[remember_me]' + end + + should "display correct checkbox in slim" do + visit '/slim/form_for' + assert_have_selector '#demo input[type=checkbox]', :checked => 'checked', :id => 'markup_user_remember_me', :name => 'markup_user[remember_me]' + end + end + + context 'for #check_box_group and #radio_button_group methods' do + should 'display checkbox group html' do + checkboxes = standard_builder.check_box_group(:role, :collection => @user.role_types, :fields => [:name, :id], :selected => [2,3]) + assert_has_tag('input[type=checkbox]', :value => '1') { checkboxes } + assert_has_no_tag('input[type=checkbox][checked]', :value => '1') { checkboxes } + assert_has_tag('input[type=checkbox]', :checked => 'checked', :value => '2') { checkboxes } + assert_has_tag('label[for=user_role_3] input[name="user[role][]"][value="3"][checked]') { checkboxes } + end + + should 'display checkbox group html and extract selected values from the object' do + checkboxes = standard_builder.check_box_group(:roles, :collection => @user.role_types, :fields => [:name, :id]) + assert_has_tag('input[type=checkbox][name="user[roles][]"][value="1"][checked]') { checkboxes } + assert_has_tag('input[type=checkbox][name="user[roles][]"][value="3"][checked]') { checkboxes } + assert_has_no_tag('input[type=checkbox][name="user[roles][]"][value="2"][checked]') { checkboxes } + end + + should 'display radio group html' do + radios = standard_builder.radio_button_group(:role, :options => %W(red yellow blue), :selected => 'yellow') + assert_has_tag('input[type=radio]', :value => 'red') { radios } + assert_has_no_tag('input[type=radio][checked]', :value => 'red') { radios } + assert_has_tag('input[type=radio]', :checked => 'checked', :value => 'yellow') { radios } + assert_has_tag('label[for=user_role_blue] input[name="user[role]"][value=blue]') { radios } + end + + should 'display radio group html and extract selected value from the object' do + radios = standard_builder.radio_button_group(:role, :collection => @user.role_types) + assert_has_tag('input[type=radio][value="1"][checked]') { radios } + assert_has_no_tag('input[type=radio][value="2"][checked]') { radios } + end + end + + context 'for #radio_button method' do + should "display correct radio button html" do + actual_html = standard_builder.radio_button(:gender, :value => 'male', :class => 'large') + assert_has_tag('input.large[type=radio]', :id => 'user_gender_male', :name => 'user[gender]', :value => 'male') { actual_html } + end + + should "display correct radio button html when checked" do + actual_html = standard_builder.radio_button(:gender, :checked => true) + assert_has_tag('input[type=radio]', :checked => 'checked', :name => 'user[gender]') { actual_html } + end + + should "display correct radio button html as checked when object value matches" do + @user.stubs(:gender => 'male') + actual_html = standard_builder.radio_button(:gender, :value => 'male') + assert_has_tag('input[type=radio]', :checked => 'checked', :name => 'user[gender]') { actual_html } + end + + should "display correct radio button html as unchecked when object value doesn't match" do + @user.stubs(:gender => 'male') + actual_html = standard_builder.radio_button(:gender, :value => 'female') + assert_has_no_tag('input[type=radio]', :checked => 'checked') { actual_html } + end + + should "display correct radio button in haml" do + visit '/haml/form_for' + assert_have_selector '#demo input[type=radio]', :id => 'markup_user_gender_male', :name => 'markup_user[gender]', :value => 'male' + assert_have_selector '#demo input[type=radio]', :id => 'markup_user_gender_female', :name => 'markup_user[gender]', :value => 'female' + assert_have_selector '#demo input[type=radio][checked=checked]', :id => 'markup_user_gender_male' + end + + should "display correct radio button in erb" do + visit '/erb/form_for' + assert_have_selector '#demo input[type=radio]', :id => 'markup_user_gender_male', :name => 'markup_user[gender]', :value => 'male' + assert_have_selector '#demo input[type=radio]', :id => 'markup_user_gender_female', :name => 'markup_user[gender]', :value => 'female' + assert_have_selector '#demo input[type=radio][checked=checked]', :id => 'markup_user_gender_male' + end + + should "display correct radio button in slim" do + visit '/slim/form_for' + assert_have_selector '#demo input[type=radio]', :id => 'markup_user_gender_male', :name => 'markup_user[gender]', :value => 'male' + assert_have_selector '#demo input[type=radio]', :id => 'markup_user_gender_female', :name => 'markup_user[gender]', :value => 'female' + assert_have_selector '#demo input[type=radio][checked=checked]', :id => 'markup_user_gender_male' + end + end + + context 'for #text_area method' do + should "display correct text_area html" do + actual_html = standard_builder.text_area(:about, :class => 'large') + assert_has_tag('textarea.large', :id => 'user_about', :name => 'user[about]') { actual_html } + end + + should "display correct text_area html and content" do + actual_html = standard_builder.text_area(:about, :value => "Demo", :rows => '5', :cols => '6') + assert_has_tag('textarea', :id => 'user_about', :content => 'Demo', :rows => '5', :cols => '6') { actual_html } + end + + should "display correct text_area in haml" do + visit '/haml/form_for' + assert_have_selector '#demo textarea', :name => 'markup_user[about]', :id => 'markup_user_about', :class => 'user-about' + assert_have_selector '#demo2 textarea', :name => 'markup_user[about]', :id => 'markup_user_about', :class => 'textarea' + end + + should "display correct text_area in erb" do + visit '/erb/form_for' + assert_have_selector '#demo textarea', :name => 'markup_user[about]', :id => 'markup_user_about', :class => 'user-about' + assert_have_selector '#demo2 textarea', :name => 'markup_user[about]', :id => 'markup_user_about', :class => 'textarea' + end + + should "display correct text_area in slim" do + visit '/slim/form_for' + assert_have_selector '#demo textarea', :name => 'markup_user[about]', :id => 'markup_user_about', :class => 'user-about' + assert_have_selector '#demo2 textarea', :name => 'markup_user[about]', :id => 'markup_user_about', :class => 'textarea' + end + end + + context 'for #password_field method' do + should "display correct password_field html" do + actual_html = standard_builder.password_field(:code, :class => 'large') + assert_has_tag('input.large[type=password]', :id => 'user_code', :name => 'user[code]') { actual_html } + end + + should "display correct password_field in haml" do + visit '/haml/form_for' + assert_have_selector '#demo input', :type => 'password', :class => 'user-password', :value => 'secret' + assert_have_selector '#demo2 input', :type => 'password', :class => 'input', :name => 'markup_user[code]' + end + + should "display correct password_field in erb" do + visit '/erb/form_for' + assert_have_selector '#demo input', :type => 'password', :class => 'user-password', :value => 'secret' + assert_have_selector '#demo2 input', :type => 'password', :class => 'input', :name => 'markup_user[code]' + end + + should "display correct password_field in slim" do + visit '/slim/form_for' + assert_have_selector '#demo input', :type => 'password', :class => 'user-password', :value => 'secret' + assert_have_selector '#demo2 input', :type => 'password', :class => 'input', :name => 'markup_user[code]' + end + end + + context 'for #file_field method' do + should "display correct file_field html" do + actual_html = standard_builder.file_field(:photo, :class => 'large') + assert_has_tag('input.large[type=file]', :id => 'user_photo', :name => 'user[photo]') { actual_html } + end + + should "display correct file_field in haml" do + visit '/haml/form_for' + assert_have_selector '#demo input.user-photo', :type => 'file', :name => 'markup_user[photo]', :id => 'markup_user_photo' + assert_have_selector '#demo2 input.upload', :type => 'file', :name => 'markup_user[photo]', :id => 'markup_user_photo' + end + + should "display correct file_field in erb" do + visit '/erb/form_for' + assert_have_selector '#demo input.user-photo', :type => 'file', :name => 'markup_user[photo]', :id => 'markup_user_photo' + assert_have_selector '#demo2 input.upload', :type => 'file', :name => 'markup_user[photo]', :id => 'markup_user_photo' + end + + should "display correct file_field in slim" do + visit '/slim/form_for' + assert_have_selector '#demo input.user-photo', :type => 'file', :name => 'markup_user[photo]', :id => 'markup_user_photo' + assert_have_selector '#demo2 input.upload', :type => 'file', :name => 'markup_user[photo]', :id => 'markup_user_photo' + end + + should "display correct form html with multipart, even if no 'multipart' option is specified" do + actual_html = form_for(@user, '/register', :"accept-charset" => "UTF-8") { |f| f.file_field :photo } + assert_has_tag('form', :"accept-charset" => "UTF-8", :action => '/register', :enctype => "multipart/form-data") { actual_html } + end + + should "display correct form html without multipart, if 'multipart' option is specified 'false'" do + actual_html = form_for(@user, '/register', :"accept-charset" => "UTF-8", :multipart => false) { |f| f.file_field :photo } + assert_has_no_tag('form', :"accept-charset" => "UTF-8", :action => '/register', :enctype => "multipart/form-data") { actual_html } + end + + end + + context 'for #select method' do + should "display correct select html" do + actual_html = standard_builder.select(:state, :options => ['California', 'Texas', 'Wyoming'], :class => 'selecty') + assert_has_tag('select.selecty', :id => 'user_state', :name => 'user[state]') { actual_html } + assert_has_tag('select.selecty option', :count => 3) { actual_html } + assert_has_tag('select.selecty option', :value => 'California', :content => 'California') { actual_html } + assert_has_tag('select.selecty option', :value => 'Texas', :content => 'Texas') { actual_html } + assert_has_tag('select.selecty option', :value => 'Wyoming', :content => 'Wyoming') { actual_html } + end + + should "display correct select html with selected item if it matches value" do + @user.stubs(:state => 'California') + actual_html = standard_builder.select(:state, :options => ['California', 'Texas', 'Wyoming']) + assert_has_tag('select', :id => 'user_state', :name => 'user[state]') { actual_html } + assert_has_tag('select option', :selected => 'selected', :count => 1) { actual_html } + assert_has_tag('select option', :value => 'California', :selected => 'selected') { actual_html } + end + + should "display correct select html with selected item if it matches full value" do + @user.stubs(:state => 'Cali') + actual_html = standard_builder.select(:state, :options => ['Cali', 'California', 'Texas', 'Wyoming']) + assert_has_tag('select', :id => 'user_state', :name => 'user[state]') { actual_html } + assert_has_tag('select option', :selected => 'selected', :count => 1) { actual_html } + assert_has_tag('select option', :value => 'Cali', :selected => 'selected') { actual_html } + assert_has_tag('select option', :value => 'California') { actual_html } + end + + should "display correct select html with multiple selected items" do + @user.stubs(:pickles => ['foo', 'bar']) + actual_html = standard_builder.select( + :pickles, :options => [ ['Foo', 'foo'], ['Bar', 'bar'], ['Baz', 'baz'], ['Bar Buz', 'bar buz'] ] + ) + assert_has_tag('option', :value => 'foo', :content => 'Foo', :selected => 'selected') { actual_html } + assert_has_tag('option', :value => 'bar', :content => 'Bar', :selected => 'selected') { actual_html } + assert_has_tag('option', :value => 'baz', :content => 'Baz') { actual_html } + assert_has_tag('option', :value => 'bar buz', :content => 'Bar Buz') { actual_html } + end + + should "display correct select html with include_blank" do + actual_html = standard_builder.select(:state, :options => ['California', 'Texas', 'Wyoming'], :include_blank => true) + assert_has_tag('select', :id => 'user_state', :name => 'user[state]') { actual_html } + assert_has_tag('select option', :count => 4) { actual_html } + assert_has_tag('select option:first-child', :content => '') { actual_html } + assert_has_tag('select option:first-child', :value => '') { actual_html } + actual_html = standard_builder.select(:state, :options => ['California', 'Texas', 'Wyoming'], :include_blank => 'Select') + assert_has_tag('select', :id => 'user_state', :name => 'user[state]') { actual_html } + assert_has_tag('select option', :count => 4) { actual_html } + assert_has_tag('select option:first-child', :content => 'Select') { actual_html } + assert_has_tag('select option:first-child', :value => '') { actual_html } + end + + should "display correct select html with collection passed in" do + actual_html = standard_builder.select(:role, :collection => @user.role_types, :fields => [:name, :id]) + assert_has_tag('select', :id => 'user_role', :name => 'user[role]') { actual_html } + assert_has_tag('select option', :count => 3) { actual_html } + assert_has_tag('select option', :value => '1', :content => 'Admin', :selected => 'selected') { actual_html } + assert_has_tag('select option', :value => '2', :content => 'Moderate') { actual_html } + assert_has_tag('select option', :value => '3', :content => 'Limited') { actual_html } + end + + should "display correct select in haml" do + visit '/haml/form_for' + assert_have_selector '#demo textarea', :name => 'markup_user[about]', :id => 'markup_user_about', :class => 'user-about' + assert_have_selector '#demo2 textarea', :name => 'markup_user[about]', :id => 'markup_user_about', :class => 'textarea' + end + + should "display correct select in erb" do + visit '/erb/form_for' + assert_have_selector '#demo textarea', :name => 'markup_user[about]', :id => 'markup_user_about', :class => 'user-about' + assert_have_selector '#demo2 textarea', :name => 'markup_user[about]', :id => 'markup_user_about', :class => 'textarea' + end + + should "display correct select in slim" do + visit '/slim/form_for' + assert_have_selector '#demo textarea', :name => 'markup_user[about]', :id => 'markup_user_about', :class => 'user-about' + assert_have_selector '#demo2 textarea', :name => 'markup_user[about]', :id => 'markup_user_about', :class => 'textarea' + end + end + + context 'for #submit method' do + should "display correct submit button html with no options" do + actual_html = standard_builder.submit + assert_has_tag('input[type=submit]', :value => "Submit") { actual_html } + end + + + should "display correct submit button html with no caption" do + actual_html = standard_builder.submit(:class => 'btn') + assert_has_tag('input.btn[type=submit]', :value => "Submit") { actual_html } + end + + should "display correct submit button html with nil caption" do + actual_html = standard_builder.submit(nil, :class => 'btn') + assert_has_tag('input.btn[type=submit]') { actual_html } + assert actual_html !~ %r{ value \* = }x + end + + should "display correct submit button html" do + actual_html = standard_builder.submit("Commit", :class => 'large') + assert_has_tag('input.large[type=submit]', :value => "Commit") { actual_html } + end + + should "display correct submit button in haml" do + visit '/haml/form_for' + assert_have_selector '#demo input', :type => 'submit', :id => 'demo-button', :class => 'success' + assert_have_selector '#demo2 input', :type => 'submit', :class => 'button', :value => "Create" + end + + should "display correct submit button in erb" do + visit '/erb/form_for' + assert_have_selector '#demo input', :type => 'submit', :id => 'demo-button', :class => 'success' + assert_have_selector '#demo2 input', :type => 'submit', :class => 'button', :value => "Create" + end + + should "display correct submit button in slim" do + visit '/slim/form_for' + assert_have_selector '#demo input', :type => 'submit', :id => 'demo-button', :class => 'success' + assert_have_selector '#demo2 input', :type => 'submit', :class => 'button', :value => "Create" + end + end + + context 'for #image_submit method' do + setup do + @stamp = stop_time_for_test.to_i + end + + should "display correct image submit button html with no options" do + actual_html = standard_builder.image_submit('buttons/ok.png') + assert_has_tag('input[type=image]', :src => "/images/buttons/ok.png?#{@stamp}") { actual_html } + end + + should "display correct image submit button html" do + actual_html = standard_builder.image_submit('/system/ok.png', :class => 'large') + assert_has_tag('input.large[type=image]', :src => "/system/ok.png") { actual_html } + end + + should "display correct image submit button in haml" do + visit '/haml/form_for' + assert_have_selector '#demo input', :type => 'image', :id => 'image-button', :src => "/images/buttons/post.png?#{@stamp}" + assert_have_selector '#demo2 input', :type => 'image', :class => 'image', :src => "/images/buttons/ok.png?#{@stamp}" + end + + should "display correct image submit button in erb" do + visit '/erb/form_for' + assert_have_selector '#demo input', :type => 'image', :id => 'image-button', :src => "/images/buttons/post.png?#{@stamp}" + assert_have_selector '#demo2 input', :type => 'image', :class => 'image', :src => "/images/buttons/ok.png?#{@stamp}" + end + + should "display correct image submit button in slim" do + visit '/slim/form_for' + assert_have_selector '#demo input', :type => 'image', :id => 'image-button', :src => "/images/buttons/post.png?#{@stamp}" + assert_have_selector '#demo2 input', :type => 'image', :class => 'image', :src => "/images/buttons/ok.png?#{@stamp}" + end + end + + context 'for #fields_for method' do + setup do + @telephone = mock_model("Telephone", :number => "4568769876") + @user.stubs(:telephone).returns(@telephone) + @businesses = [ mock_model("Business", :name => "Silver", :new_record? => false, :id => 20) ] + @businesses << mock_model("Business", :name => "Gold", :new_record? => true) + @addresses = [ mock_model("Address", :name => "Foo", :new_record? => false, :id => 20, :businesses => @businesses) ] + @addresses << mock_model("Address", :name => "Bar", :new_record? => true, :businesses => @businesses) + @user.stubs(:addresses).returns(@addresses) + end + + should "display nested children fields one-to-one within form" do + actual_html = standard_builder.fields_for :telephone do |child_form| + child_form.label(:number) + + child_form.text_field(:number) + + child_form.check_box('_destroy') + end + assert_has_tag('label', :for => 'user_telephone_attributes_number') { actual_html } + assert_has_tag('input', :type => 'text', :id => 'user_telephone_attributes_number', :name => 'user[telephone_attributes][number]', :value => "4568769876") { actual_html } + assert_has_tag('input', :type => 'hidden', :name => 'user[telephone_attributes][_destroy]', :value => '0') { actual_html } + assert_has_tag('input', :type => 'checkbox', :id => 'user_telephone_attributes__destroy', :name => 'user[telephone_attributes][_destroy]', :value => '1') { actual_html } + end + + should "display nested children fields one-to-many within form" do + actual_html = standard_builder.fields_for(:addresses) do |child_form| + html = child_form.label(:name) + html << child_form.check_box('_destroy') unless child_form.object.new_record? + html << child_form.text_field(:name) + end + # Address 1 (Saved) + assert_has_tag('input', :type => 'hidden', :id => 'user_addresses_attributes_0_id', :name => "user[addresses_attributes][0][id]", :value => '20') { actual_html } + assert_has_tag('label', :for => 'user_addresses_attributes_0_name', :content => 'Name') { actual_html } + assert_has_tag('input', :type => 'text', :id => 'user_addresses_attributes_0_name', :name => 'user[addresses_attributes][0][name]') { actual_html } + assert_has_tag('input', :type => 'checkbox', :id => 'user_addresses_attributes_0__destroy', :name => 'user[addresses_attributes][0][_destroy]') { actual_html } + # Address 2 (New) + assert_has_no_tag('input', :type => 'hidden', :id => 'user_addresses_attributes_1_id') { actual_html } + assert_has_tag('label', :for => 'user_addresses_attributes_1_name', :content => 'Name') { actual_html } + assert_has_tag('input', :type => 'text', :id => 'user_addresses_attributes_1_name', :name => 'user[addresses_attributes][1][name]') { actual_html } + assert_has_no_tag('input', :type => 'checkbox', :id => 'user_addresses_attributes_1__destroy') { actual_html } + end + + should "display fields for explicit instance object" do + address = mock_model("Address", :name => "Page", :new_record? => false, :id => 40) + actual_html = standard_builder.fields_for(:addresses, address) do |child_form| + html = child_form.label(:name) + html << child_form.text_field(:name) + html << child_form.check_box('_destroy') + end + assert_has_tag('input', :type => 'hidden', :id => 'user_addresses_attributes_0_id', :name => "user[addresses_attributes][0][id]", :value => '40') { actual_html } + assert_has_tag('label', :for => 'user_addresses_attributes_0_name', :content => 'Name') { actual_html } + assert_has_tag('input', :type => 'text', :id => 'user_addresses_attributes_0_name', :name => 'user[addresses_attributes][0][name]', :value => "Page") { actual_html } + assert_has_tag('input', :type => 'checkbox', :id => 'user_addresses_attributes_0__destroy', :name => 'user[addresses_attributes][0][_destroy]', :value => '1') { actual_html } + end + + should "display fields for collection object" do + addresses = @addresses + [mock_model("Address", :name => "Walter", :new_record? => false, :id => 50)] + actual_html = standard_builder.fields_for(:addresses, addresses) do |child_form| + child_form.label(:name) + + child_form.text_field(:name) + + child_form.check_box('_destroy') + end + # Address 1 + assert_has_tag('input', :type => 'hidden', :id => 'user_addresses_attributes_0_id', :name => "user[addresses_attributes][0][id]", :value => '20') { actual_html } + assert_has_tag('label', :for => 'user_addresses_attributes_0_name', :content => 'Name') { actual_html } + assert_has_tag('input', :type => 'text', :id => 'user_addresses_attributes_0_name', :name => 'user[addresses_attributes][0][name]', :value => "Foo") { actual_html } + assert_has_tag('input', :type => 'checkbox', :id => 'user_addresses_attributes_0__destroy', :name => 'user[addresses_attributes][0][_destroy]') { actual_html } + # Address 3 + assert_has_tag('input', :type => 'hidden', :id => 'user_addresses_attributes_2_id', :value => '50') { actual_html } + assert_has_tag('label', :for => 'user_addresses_attributes_2_name', :content => 'Name') { actual_html } + assert_has_tag('input', :type => 'text', :id => 'user_addresses_attributes_2_name', :name => 'user[addresses_attributes][2][name]', :value => "Walter") { actual_html } + assert_has_tag('input', :type => 'checkbox', :id => 'user_addresses_attributes_2__destroy') { actual_html } + end + + should "display fields for arbitrarily deep nested forms" do + actual_html = standard_builder.fields_for :addresses do |child_form| + child_form.fields_for(:businesses) do |second_child_form| + second_child_form.label(:name) + + second_child_form.text_field(:name) + + second_child_form.check_box('_destroy') + end + end + assert_has_tag('label', :for => 'user_addresses_attributes_1_businesses_attributes_0_name', :content => 'Name') { actual_html } + assert_has_tag('input', :type => 'text', :id => 'user_addresses_attributes_1_businesses_attributes_0_name', :name => 'user[addresses_attributes][1][businesses_attributes][0][name]') { actual_html } + end + + should "display nested children fields in erb" do + visit '/erb/fields_for' + # Telephone + assert_have_selector('label', :for => 'markup_user_telephone_attributes_number') + assert_have_selector('input', :type => 'text', :id => 'markup_user_telephone_attributes_number', :name => 'markup_user[telephone_attributes][number]', :value => "62634576545") + # Address 1 (Saved) + assert_have_selector('input', :type => 'hidden', :id => 'markup_user_addresses_attributes_0_id', :name => "markup_user[addresses_attributes][0][id]", :value => '25') + assert_have_selector('label', :for => 'markup_user_addresses_attributes_0_name', :content => 'Name') + assert_have_selector('input', :type => 'text', :id => 'markup_user_addresses_attributes_0_name', :name => 'markup_user[addresses_attributes][0][name]') + assert_have_selector('input', :type => 'checkbox', :id => 'markup_user_addresses_attributes_0__destroy', :name => 'markup_user[addresses_attributes][0][_destroy]') + # Address 2 (New) + assert_have_no_selector('input', :type => 'hidden', :id => 'markup_user_addresses_attributes_1_id') + assert_have_selector('label', :for => 'markup_user_addresses_attributes_1_name', :content => 'Name') + assert_have_selector('input', :type => 'text', :id => 'markup_user_addresses_attributes_1_name', :name => 'markup_user[addresses_attributes][1][name]') + assert_have_no_selector('input', :type => 'checkbox', :id => 'markup_user_addresses_attributes_1__destroy') + end + + should "display nested children fields in haml" do + visit '/haml/fields_for' + # Telephone + assert_have_selector('label', :for => 'markup_user_telephone_attributes_number') + assert_have_selector('input', :type => 'text', :id => 'markup_user_telephone_attributes_number', :name => 'markup_user[telephone_attributes][number]', :value => "62634576545") + # Address 1 (Saved) + assert_have_selector('input', :type => 'hidden', :id => 'markup_user_addresses_attributes_0_id', :name => "markup_user[addresses_attributes][0][id]", :value => '25') + assert_have_selector('label', :for => 'markup_user_addresses_attributes_0_name', :content => 'Name') + assert_have_selector('input', :type => 'text', :id => 'markup_user_addresses_attributes_0_name', :name => 'markup_user[addresses_attributes][0][name]') + assert_have_selector('input', :type => 'checkbox', :id => 'markup_user_addresses_attributes_0__destroy', :name => 'markup_user[addresses_attributes][0][_destroy]') + # Address 2 (New) + assert_have_no_selector('input', :type => 'hidden', :id => 'markup_user_addresses_attributes_1_id') + assert_have_selector('label', :for => 'markup_user_addresses_attributes_1_name', :content => 'Name') + assert_have_selector('input', :type => 'text', :id => 'markup_user_addresses_attributes_1_name', :name => 'markup_user[addresses_attributes][1][name]') + assert_have_no_selector('input', :type => 'checkbox', :id => 'markup_user_addresses_attributes_1__destroy') + end + + should "display nested children fields in slim" do + visit '/slim/fields_for' + # Telephone + assert_have_selector('label', :for => 'markup_user_telephone_attributes_number') + assert_have_selector('input', :type => 'text', :id => 'markup_user_telephone_attributes_number', :name => 'markup_user[telephone_attributes][number]', :value => "62634576545") + # Address 1 (Saved) + assert_have_selector('input', :type => 'hidden', :id => 'markup_user_addresses_attributes_0_id', :name => "markup_user[addresses_attributes][0][id]", :value => '25') + assert_have_selector('label', :for => 'markup_user_addresses_attributes_0_name', :content => 'Name') + assert_have_selector('input', :type => 'text', :id => 'markup_user_addresses_attributes_0_name', :name => 'markup_user[addresses_attributes][0][name]') + assert_have_selector('input', :type => 'checkbox', :id => 'markup_user_addresses_attributes_0__destroy', :name => 'markup_user[addresses_attributes][0][_destroy]') + # Address 2 (New) + assert_have_no_selector('input', :type => 'hidden', :id => 'markup_user_addresses_attributes_1_id') + assert_have_selector('label', :for => 'markup_user_addresses_attributes_1_name', :content => 'Name') + assert_have_selector('input', :type => 'text', :id => 'markup_user_addresses_attributes_1_name', :name => 'markup_user[addresses_attributes][1][name]') + assert_have_no_selector('input', :type => 'checkbox', :id => 'markup_user_addresses_attributes_1__destroy') + end + end + + # =========================== + # StandardFormBuilder + # =========================== + + context 'for #text_field_block method' do + should "display correct text field block html" do + actual_html = standard_builder.text_field_block(:first_name, :class => 'large', :caption => "FName") + assert_has_tag('p label', :for => 'user_first_name', :content => "FName") { actual_html } + assert_has_tag('p input.large[type=text]', :value => "Joe", :id => 'user_first_name', :name => 'user[first_name]') { actual_html } + end + + should "display correct text field block in haml" do + visit '/haml/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_username', :content => "Nickname: ", :class => 'label' + assert_have_selector '#demo2 p input', :type => 'text', :name => 'markup_user[username]', :id => 'markup_user_username' + end + + should "display correct text field block in erb" do + visit '/erb/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_username', :content => "Nickname: ", :class => 'label' + assert_have_selector '#demo2 p input', :type => 'text', :name => 'markup_user[username]', :id => 'markup_user_username' + end + + should "display correct text field block in slim" do + visit '/slim/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_username', :content => "Nickname: ", :class => 'label' + assert_have_selector '#demo2 p input', :type => 'text', :name => 'markup_user[username]', :id => 'markup_user_username' + end + end + + context 'for #text_area_block method' do + should "display correct text area block html" do + actual_html = standard_builder.text_area_block(:about, :class => 'large', :caption => "About Me") + assert_has_tag('p label', :for => 'user_about', :content => "About Me") { actual_html } + assert_has_tag('p textarea', :id => 'user_about', :name => 'user[about]') { actual_html } + end + + should "display correct text area block in haml" do + visit '/haml/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_about', :content => "About: " + assert_have_selector '#demo2 p textarea', :name => 'markup_user[about]', :id => 'markup_user_about' + end + + should "display correct text area block in erb" do + visit '/erb/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_about', :content => "About: " + assert_have_selector '#demo2 p textarea', :name => 'markup_user[about]', :id => 'markup_user_about' + end + + should "display correct text area block in slim" do + visit '/slim/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_about', :content => "About: " + assert_have_selector '#demo2 p textarea', :name => 'markup_user[about]', :id => 'markup_user_about' + end + end + + context 'for #password_field_block method' do + should "display correct password field block html" do + actual_html = standard_builder.password_field_block(:keycode, :class => 'large', :caption => "Code: ") + assert_has_tag('p label', :for => 'user_keycode', :content => "Code: ") { actual_html } + assert_has_tag('p input.large[type=password]', :id => 'user_keycode', :name => 'user[keycode]') { actual_html } + end + + should "display correct password field block in haml" do + visit '/haml/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_code', :content => "Code: " + assert_have_selector '#demo2 p input', :type => 'password', :name => 'markup_user[code]', :id => 'markup_user_code' + end + + should "display correct password field block in erb" do + visit '/erb/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_code', :content => "Code: " + assert_have_selector '#demo2 p input', :type => 'password', :name => 'markup_user[code]', :id => 'markup_user_code' + end + + should "display correct password field block in slim" do + visit '/slim/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_code', :content => "Code: " + assert_have_selector '#demo2 p input', :type => 'password', :name => 'markup_user[code]', :id => 'markup_user_code' + end + end + + context 'for #file_field_block method' do + should "display correct file field block html" do + actual_html = standard_builder.file_field_block(:photo, :class => 'large', :caption => "Photo: ") + assert_has_tag('p label', :for => 'user_photo', :content => "Photo: ") { actual_html } + assert_has_tag('p input.large[type=file]', :id => 'user_photo', :name => 'user[photo]') { actual_html } + end + + should "display correct file field block in haml" do + visit '/haml/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_photo', :content => "Photo: " + assert_have_selector '#demo2 p input.upload', :type => 'file', :name => 'markup_user[photo]', :id => 'markup_user_photo' + end + + should "display correct file field block in erb" do + visit '/erb/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_photo', :content => "Photo: " + assert_have_selector '#demo2 p input.upload', :type => 'file', :name => 'markup_user[photo]', :id => 'markup_user_photo' + end + + should "display correct file field block in slim" do + visit '/slim/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_photo', :content => "Photo: " + assert_have_selector '#demo2 p input.upload', :type => 'file', :name => 'markup_user[photo]', :id => 'markup_user_photo' + end + end + + context 'for #check_box_block method' do + should "display correct check box block html" do + actual_html = standard_builder.check_box_block(:remember_me, :class => 'large', :caption => "Remember session?") + assert_has_tag('p label', :for => 'user_remember_me', :content => "Remember session?") { actual_html } + assert_has_tag('p input.large[type=checkbox]', :id => 'user_remember_me', :name => 'user[remember_me]') { actual_html } + end + + should "display correct check box block in haml" do + visit '/haml/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_remember_me', :content => "Remember me: " + assert_have_selector '#demo2 p input.checker', :type => 'checkbox', :name => 'markup_user[remember_me]' + end + + should "display correct check box block in erb" do + visit '/erb/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_remember_me', :content => "Remember me: " + assert_have_selector '#demo2 p input.checker', :type => 'checkbox', :name => 'markup_user[remember_me]' + end + + should "display correct check box block in slim" do + visit '/slim/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_remember_me', :content => "Remember me: " + assert_have_selector '#demo2 p input.checker', :type => 'checkbox', :name => 'markup_user[remember_me]' + end + end + + context 'for #select_block method' do + should "display correct select_block block html" do + actual_html = standard_builder.select_block(:country, :options => ['USA', 'Canada'], :class => 'large', :caption => "Your country") + assert_has_tag('p label', :for => 'user_country', :content => "Your country") { actual_html } + assert_has_tag('p select', :id => 'user_country', :name => 'user[country]') { actual_html } + assert_has_tag('p select option', :content => 'USA') { actual_html } + assert_has_tag('p select option', :content => 'Canada') { actual_html } + end + + should "display correct select_block block in haml" do + visit '/haml/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_state', :content => "State: " + assert_have_selector '#demo2 p select', :name => 'markup_user[state]', :id => 'markup_user_state' + assert_have_selector '#demo2 p select option', :content => 'California' + assert_have_selector '#demo2 p select option', :content => 'Texas' + end + + should "display correct select_block block in erb" do + visit '/erb/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_state', :content => "State: " + assert_have_selector '#demo2 p select', :name => 'markup_user[state]', :id => 'markup_user_state' + end + + should "display correct select_block block in slim" do + visit '/slim/form_for' + assert_have_selector '#demo2 p label', :for => 'markup_user_state', :content => "State: " + assert_have_selector '#demo2 p select', :name => 'markup_user[state]', :id => 'markup_user_state' + end + end + + context 'for #submit_block method' do + should "display correct submit block html" do + actual_html = standard_builder.submit_block("Update", :class => 'large') + assert_has_tag('p input.large[type=submit]', :value => 'Update') { actual_html } + end + + should "display correct submit block in haml" do + visit '/haml/form_for' + assert_have_selector '#demo2 p input', :type => 'submit', :class => 'button' + end + + should "display correct submit block in erb" do + visit '/erb/form_for' + assert_have_selector '#demo2 p input', :type => 'submit', :class => 'button' + end + + should "display correct submit block in slim" do + visit '/slim/form_for' + assert_have_selector '#demo2 p input', :type => 'submit', :class => 'button' + end + end + + context 'for #image_submit_block method' do + setup do + @stamp = stop_time_for_test.to_i + end + + should "display correct image submit block html" do + actual_html = standard_builder.image_submit_block("buttons/ok.png", :class => 'large') + assert_has_tag('p input.large[type=image]', :src => "/images/buttons/ok.png?#{@stamp}") { actual_html } + end + + should "display correct image submit block in haml" do + visit '/haml/form_for' + assert_have_selector '#demo2 p input', :type => 'image', :class => 'image', :src => "/images/buttons/ok.png?#{@stamp}" + end + + should "display correct image submit block in slim" do + visit '/slim/form_for' + assert_have_selector '#demo2 p input', :type => 'image', :class => 'image', :src => "/images/buttons/ok.png?#{@stamp}" + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_form_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_form_helpers.rb new file mode 100644 index 00000000..c9052c61 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_form_helpers.rb @@ -0,0 +1,1030 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require File.expand_path(File.dirname(__FILE__) + '/fixtures/markup_app/app') + +describe "FormHelpers" do + include Padrino::Helpers::FormHelpers + + def app + MarkupDemo + end + + class UnprotectedApp + def protect_from_csrf; false; end + end + + context 'for #form_tag method' do + should "display correct forms in ruby" do + actual_html = form_tag('/register', :"accept-charset" => "UTF-8", :class => 'test', :method => "post") { "Demo" } + assert_has_tag(:form, :"accept-charset" => "UTF-8", :class => "test") { actual_html } + assert_has_tag('form input', :type => 'hidden', :name => '_method', :count => 0) { actual_html } + end + + should "display correct text inputs within form_tag" do + actual_html = form_tag('/register', :"accept-charset" => "UTF-8", :class => 'test') { text_field_tag(:username) } + assert_has_tag('form input', :type => 'text', :name => "username") { actual_html } + end + + should "display correct form with remote" do + actual_html = form_tag('/update', :"accept-charset" => "UTF-8", :class => 'put-form', :remote => true) { "Demo" } + assert_has_tag(:form, :class => "put-form", :"accept-charset" => "UTF-8", :"data-remote" => 'true') { actual_html } + assert_has_no_tag(:form, "data-method" => 'post') { actual_html } + end + + should "display correct form with remote and method is put" do + actual_html = form_tag('/update', :"accept-charset" => "UTF-8", :method => 'put', :remote => true) { "Demo" } + assert_has_tag(:form, "data-remote" => 'true', :"accept-charset" => "UTF-8") { actual_html } + assert_has_tag('form input', :type => 'hidden', :name => "_method", :value => 'put') { actual_html } + end + + should "display correct form with method :put" do + actual_html = form_tag('/update', :"accept-charset" => "UTF-8", :class => 'put-form', :method => "put") { "Demo" } + assert_has_tag(:form, :class => "put-form", :"accept-charset" => "UTF-8", :method => 'post') { actual_html } + assert_has_tag('form input', :type => 'hidden', :name => "_method", :value => 'put') { actual_html } + end + + should "display correct form with method :delete and charset" do + actual_html = form_tag('/remove', :"accept-charset" => "UTF-8", :class => 'delete-form', :method => "delete") { "Demo" } + assert_has_tag(:form, :class => "delete-form", :"accept-charset" => "UTF-8", :method => 'post') { actual_html } + assert_has_tag('form input', :type => 'hidden', :name => "_method", :value => 'delete') { actual_html } + end + + should "display correct form with charset" do + actual_html = form_tag('/charset', :"accept-charset" => "UTF-8", :class => 'charset-form') { "Demo" } + assert_has_tag(:form, :class => "charset-form", :"accept-charset" => "UTF-8", :method => 'post') { actual_html } + end + + should "display correct form with multipart encoding" do + actual_html = form_tag('/remove', :"accept-charset" => "UTF-8", :multipart => true) { "Demo" } + assert_has_tag(:form, :enctype => "multipart/form-data") { actual_html } + end + + should "have an authenticity_token for method :post, :put or :delete" do + %w(post put delete).each do |method| + actual_html = form_tag('/modify', :method => method) { "Demo" } + assert_has_tag(:input, :name => 'authenticity_token') { actual_html } + end + end + + should "not have an authenticity_token if method: :get" do + actual_html = form_tag('/get', :method => :get) { "Demo" } + assert_has_no_tag(:input, :name => 'authenticity_token') { actual_html } + end + + should "have an authenticity_token by default" do + actual_html = form_tag('/superadmindelete') { "Demo" } + assert_has_tag(:input, :name => 'authenticity_token') { actual_html } + end + + should "create csrf meta tags with token and param - #csrf_meta_tags" do + actual_html = csrf_meta_tags + assert_has_tag(:meta, :name => 'csrf-param') { actual_html } + assert_has_tag(:meta, :name => 'csrf-token') { actual_html } + end + + should "have an authenticity_token by default" do + actual_html = form_tag('/superadmindelete') { "Demo" } + assert_has_tag(:input, :name => 'authenticity_token') { actual_html } + end + + should "not have an authenticity_token if passing protect_from_csrf: false" do + actual_html = form_tag('/superadmindelete', :protect_from_csrf => false) { "Demo" } + assert_has_no_tag(:input, :name => 'authenticity_token') { actual_html } + end + + should "not have an authenticity_token if protect_from_csrf is false on app settings" do + self.expects(:settings).returns(UnprotectedApp.new) + actual_html = form_tag('/superadmindelete') { "Demo" } + assert_has_no_tag(:input, :name => 'authenticity_token') { actual_html } + end + + should "display correct forms in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form', :action => '/simple' + assert_have_selector 'form.advanced-form', :action => '/advanced', :id => 'advanced', :method => 'get' + assert_have_selector 'form.simple-form input', :name => 'authenticity_token' + assert_have_no_selector 'form.no-protection input', :name => 'authenticity_token' + end + + should "display correct forms in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form', :action => '/simple' + assert_have_selector 'form.advanced-form', :action => '/advanced', :id => 'advanced', :method => 'get' + assert_have_selector 'form.simple-form input', :name => 'authenticity_token' + assert_have_no_selector 'form.no-protection input', :name => 'authenticity_token' + end + + should "display correct forms in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form', :action => '/simple' + assert_have_selector 'form.advanced-form', :action => '/advanced', :id => 'advanced', :method => 'get' + assert_have_selector 'form.simple-form input', :name => 'authenticity_token' + assert_have_no_selector 'form.no-protection input', :name => 'authenticity_token' + end + end + + context 'for #field_set_tag method' do + should "display correct field_sets in ruby" do + actual_html = field_set_tag("Basic", :class => 'basic') { "Demo" } + assert_has_tag(:fieldset, :class => 'basic') { actual_html } + assert_has_tag('fieldset legend', :content => "Basic") { actual_html } + end + + should "display correct field_sets in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form fieldset', :count => 1 + assert_have_no_selector 'form.simple-form fieldset legend' + assert_have_selector 'form.advanced-form fieldset', :count => 1, :class => 'advanced-field-set' + assert_have_selector 'form.advanced-form fieldset legend', :content => "Advanced" + end + + should "display correct field_sets in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form fieldset', :count => 1 + assert_have_no_selector 'form.simple-form fieldset legend' + assert_have_selector 'form.advanced-form fieldset', :count => 1, :class => 'advanced-field-set' + assert_have_selector 'form.advanced-form fieldset legend', :content => "Advanced" + end + + should "display correct field_sets in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form fieldset', :count => 1 + assert_have_no_selector 'form.simple-form fieldset legend' + assert_have_selector 'form.advanced-form fieldset', :count => 1, :class => 'advanced-field-set' + assert_have_selector 'form.advanced-form fieldset legend', :content => "Advanced" + end + end + + context 'for #error_messages_for method' do + should "display correct error messages list in ruby" do + user = mock_model("User", :errors => { :a => "1", :b => "2" }, :blank? => false) + actual_html = error_messages_for(user) + assert_has_tag('div.field-errors') { actual_html } + assert_has_tag('div.field-errors h2', :content => "2 errors prohibited this User from being saved") { actual_html } + assert_has_tag('div.field-errors p', :content => "There were problems with the following fields:") { actual_html } + assert_has_tag('div.field-errors ul') { actual_html } + assert_has_tag('div.field-errors ul li', :count => 2) { actual_html } + end + + should "display correct error messages list in erb" do + visit '/erb/form_tag' + assert_have_no_selector 'form.simple-form .field-errors' + assert_have_selector 'form.advanced-form .field-errors' + assert_have_selector 'form.advanced-form .field-errors h2', :content => "There are problems with saving user!" + assert_have_selector 'form.advanced-form .field-errors p', :content => "There were problems with the following fields:" + assert_have_selector 'form.advanced-form .field-errors ul' + assert_have_selector 'form.advanced-form .field-errors ul li', :count => 4 + assert_have_selector 'form.advanced-form .field-errors ul li', :content => "Email must be an email" + assert_have_selector 'form.advanced-form .field-errors ul li', :content => "Fake must be valid" + assert_have_selector 'form.advanced-form .field-errors ul li', :content => "Second must be present" + assert_have_selector 'form.advanced-form .field-errors ul li', :content => "Third must be a number" + end + + should "display correct error messages list in haml" do + visit '/haml/form_tag' + assert_have_no_selector 'form.simple-form .field-errors' + assert_have_selector 'form.advanced-form .field-errors' + assert_have_selector 'form.advanced-form .field-errors h2', :content => "There are problems with saving user!" + assert_have_selector 'form.advanced-form .field-errors p', :content => "There were problems with the following fields:" + assert_have_selector 'form.advanced-form .field-errors ul' + assert_have_selector 'form.advanced-form .field-errors ul li', :count => 4 + assert_have_selector 'form.advanced-form .field-errors ul li', :content => "Email must be an email" + assert_have_selector 'form.advanced-form .field-errors ul li', :content => "Fake must be valid" + assert_have_selector 'form.advanced-form .field-errors ul li', :content => "Second must be present" + assert_have_selector 'form.advanced-form .field-errors ul li', :content => "Third must be a number" + end + + should "display correct error messages list in slim" do + visit '/slim/form_tag' + assert_have_no_selector 'form.simple-form .field-errors' + assert_have_selector 'form.advanced-form .field-errors' + assert_have_selector 'form.advanced-form .field-errors h2', :content => "There are problems with saving user!" + assert_have_selector 'form.advanced-form .field-errors p', :content => "There were problems with the following fields:" + assert_have_selector 'form.advanced-form .field-errors ul' + assert_have_selector 'form.advanced-form .field-errors ul li', :count => 4 + assert_have_selector 'form.advanced-form .field-errors ul li', :content => "Email must be an email" + assert_have_selector 'form.advanced-form .field-errors ul li', :content => "Fake must be valid" + assert_have_selector 'form.advanced-form .field-errors ul li', :content => "Second must be present" + assert_have_selector 'form.advanced-form .field-errors ul li', :content => "Third must be a number" + end + end + + context 'for #error_message_on method' do + should "display correct error message on specified model name in ruby" do + @user = mock_model("User", :errors => { :a => "1", :b => "2" }, :blank? => false) + actual_html = error_message_on(:user, :a, :prepend => "foo", :append => "bar") + assert_has_tag('span.error', :content => "foo 1 bar") { actual_html } + end + + should "display correct error message on specified object in ruby" do + @bob = mock_model("User", :errors => { :a => "1", :b => "2" }, :blank? => false) + actual_html = error_message_on(@bob, :a, :prepend => "foo", :append => "bar") + assert_has_tag('span.error', :content => "foo 1 bar") { actual_html } + end + + should "display no message when error isn't present" do + @user = mock_model("User", :errors => { :a => "1", :b => "2" }, :blank? => false) + actual_html = error_message_on(:user, :fake, :prepend => "foo", :append => "bar") + assert actual_html.blank? + end + + should "display no message when error isn't present in an Array" do + @user = mock_model("User", :errors => { :a => [], :b => "2" }, :blank? => false) + actual_html = error_message_on(:user, :a, :prepend => "foo", :append => "bar") + assert actual_html.blank? + end + end + + context 'for #label_tag method' do + should "display label tag in ruby" do + actual_html = label_tag(:username, :class => 'long-label', :caption => "Nickname") + assert_has_tag(:label, :for => 'username', :class => 'long-label', :content => "Nickname") { actual_html } + end + + should "display label tag in ruby with required" do + actual_html = label_tag(:username, :caption => "Nickname", :required => true) + assert_has_tag(:label, :for => 'username', :content => 'Nickname') { actual_html } + assert_has_tag('label[for=username] span.required', :content => "*") { actual_html } + end + + should "display label tag in ruby with a block" do + actual_html = label_tag(:admin, :class => 'long-label') { input_tag :checkbox } + assert_has_tag(:label, :for => 'admin', :class => 'long-label', :content => "Admin") { actual_html } + assert_has_tag('label input[type=checkbox]') { actual_html } + end + + should "display label tag in erb for simple form" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form label', :count => 9 + assert_have_selector 'form.simple-form label', :content => "Username", :for => 'username' + assert_have_selector 'form.simple-form label', :content => "Password", :for => 'password' + assert_have_selector 'form.simple-form label', :content => "Gender", :for => 'gender' + end + + should "display label tag in erb for advanced form" do + visit '/erb/form_tag' + assert_have_selector 'form.advanced-form label', :count => 11 + assert_have_selector 'form.advanced-form label.first', :content => "Nickname", :for => 'username' + assert_have_selector 'form.advanced-form label.first', :content => "Password", :for => 'password' + assert_have_selector 'form.advanced-form label.about', :content => "About Me", :for => 'about' + assert_have_selector 'form.advanced-form label.photo', :content => "Photo" , :for => 'photo' + assert_have_selector 'form.advanced-form label.gender', :content => "Gender" , :for => 'gender' + end + + should "display label tag in haml for simple form" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form label', :count => 9 + assert_have_selector 'form.simple-form label', :content => "Username", :for => 'username' + assert_have_selector 'form.simple-form label', :content => "Password", :for => 'password' + assert_have_selector 'form.simple-form label', :content => "Gender", :for => 'gender' + end + + should "display label tag in haml for advanced form" do + visit '/haml/form_tag' + assert_have_selector 'form.advanced-form label', :count => 11 + assert_have_selector 'form.advanced-form label.first', :content => "Nickname", :for => 'username' + assert_have_selector 'form.advanced-form label.first', :content => "Password", :for => 'password' + assert_have_selector 'form.advanced-form label.about', :content => "About Me", :for => 'about' + assert_have_selector 'form.advanced-form label.photo', :content => "Photo" , :for => 'photo' + assert_have_selector 'form.advanced-form label.gender', :content => "Gender" , :for => 'gender' + end + + should "display label tag in slim for simple form" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form label', :count => 9 + assert_have_selector 'form.simple-form label', :content => "Username", :for => 'username' + assert_have_selector 'form.simple-form label', :content => "Password", :for => 'password' + assert_have_selector 'form.simple-form label', :content => "Gender", :for => 'gender' + end + + should "display label tag in slim for advanced form" do + visit '/slim/form_tag' + assert_have_selector 'form.advanced-form label', :count => 11 + assert_have_selector 'form.advanced-form label.first', :content => "Nickname", :for => 'username' + assert_have_selector 'form.advanced-form label.first', :content => "Password", :for => 'password' + assert_have_selector 'form.advanced-form label.about', :content => "About Me", :for => 'about' + assert_have_selector 'form.advanced-form label.photo', :content => "Photo" , :for => 'photo' + assert_have_selector 'form.advanced-form label.gender', :content => "Gender" , :for => 'gender' + end + end + + context 'for #hidden_field_tag method' do + should "display hidden field in ruby" do + actual_html = hidden_field_tag(:session_key, :id => 'session_id', :value => '56768') + assert_has_tag(:input, :type => 'hidden', :id => "session_id", :name => 'session_key', :value => '56768') { actual_html } + end + + should "display hidden field in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form input[type=hidden]', :count => 1, :name => 'session_id', :value => "__secret__" + assert_have_selector 'form.advanced-form input[type=hidden]', :count => 1, :name => 'session_id', :value => "__secret__" + end + + should "display hidden field in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form input[type=hidden]', :count => 1, :name => 'session_id', :value => "__secret__" + assert_have_selector 'form.advanced-form input[type=hidden]', :count => 1, :name => 'session_id', :value => "__secret__" + end + + should "display hidden field in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form input[type=hidden]', :count => 1, :name => 'session_id', :value => "__secret__" + assert_have_selector 'form.advanced-form input[type=hidden]', :count => 1, :name => 'session_id', :value => "__secret__" + end + end + + context 'for #text_field_tag method' do + should "display text field in ruby" do + actual_html = text_field_tag(:username, :class => 'long') + assert_has_tag(:input, :type => 'text', :class => "long", :name => 'username') { actual_html } + end + + should "display text field in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form input[type=text]', :count => 1, :name => 'username' + assert_have_selector 'form.advanced-form fieldset input[type=text]', :count => 1, :name => 'username', :id => 'the_username' + end + + should "display text field in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form input[type=text]', :count => 1, :name => 'username' + assert_have_selector 'form.advanced-form fieldset input[type=text]', :count => 1, :name => 'username', :id => 'the_username' + end + + should "display text field in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form input[type=text]', :count => 1, :name => 'username' + assert_have_selector 'form.advanced-form fieldset input[type=text]', :count => 1, :name => 'username', :id => 'the_username' + end + end + + context 'for #number_field_tag method' do + should "display number field in ruby" do + actual_html = number_field_tag(:age, :class => 'numeric') + assert_has_tag(:input, :type => 'number', :class => 'numeric', :name => 'age') { actual_html } + end + + should "display number field in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form input[type=number]', :count => 1, :name => 'age' + assert_have_selector 'form.advanced-form fieldset input[type=number]', :count => 1, :name => 'age', :class => 'numeric' + end + + should "display number field in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form input[type=number]', :count => 1, :name => 'age' + assert_have_selector 'form.advanced-form fieldset input[type=number]', :count => 1, :name => 'age', :class => 'numeric' + end + + should "display number field in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form input[type=number]', :count => 1, :name => 'age' + assert_have_selector 'form.advanced-form fieldset input[type=number]', :count => 1, :name => 'age', :class => 'numeric' + end + end + + context 'for #telephone_field_tag method' do + should "display number field in ruby" do + actual_html = telephone_field_tag(:telephone, :class => 'numeric') + assert_has_tag(:input, :type => 'tel', :class => 'numeric', :name => 'telephone') { actual_html } + end + + should "display telephone field in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form input[type=tel]', :count => 1, :name => 'telephone' + assert_have_selector 'form.advanced-form fieldset input[type=tel]', :count => 1, :name => 'telephone', :class => 'numeric' + end + + should "display telephone field in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form input[type=tel]', :count => 1, :name => 'telephone' + assert_have_selector 'form.advanced-form fieldset input[type=tel]', :count => 1, :name => 'telephone', :class => 'numeric' + end + + should "display telephone field in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form input[type=tel]', :count => 1, :name => 'telephone' + assert_have_selector 'form.advanced-form fieldset input[type=tel]', :count => 1, :name => 'telephone', :class => 'numeric' + end + end + + context 'for #search_field_tag method' do + should "display search field in ruby" do + actual_html = search_field_tag(:search, :class => 'string') + assert_has_tag(:input, :type => 'search', :class => 'string', :name => 'search') { actual_html } + end + + should "display search field in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form input[type=search]', :count => 1, :name => 'search' + assert_have_selector 'form.advanced-form fieldset input[type=search]', :count => 1, :name => 'search', :class => 'string' + end + + should "display search field in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form input[type=search]', :count => 1, :name => 'search' + assert_have_selector 'form.advanced-form fieldset input[type=search]', :count => 1, :name => 'search', :class => 'string' + end + + should "display search field in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form input[type=search]', :count => 1, :name => 'search' + assert_have_selector 'form.advanced-form fieldset input[type=search]', :count => 1, :name => 'search', :class => 'string' + end + end + + context 'for #email_field_tag method' do + should "display email field in ruby" do + actual_html = email_field_tag(:email, :class => 'string') + assert_has_tag(:input, :type => 'email', :class => 'string', :name => 'email') { actual_html } + end + + should "display email field in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form input[type=email]', :count => 1, :name => 'email' + assert_have_selector 'form.advanced-form fieldset input[type=email]', :count => 1, :name => 'email', :class => 'string' + end + + should "display email field in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form input[type=email]', :count => 1, :name => 'email' + assert_have_selector 'form.advanced-form fieldset input[type=email]', :count => 1, :name => 'email', :class => 'string' + end + + should "display email field in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form input[type=email]', :count => 1, :name => 'email' + assert_have_selector 'form.advanced-form fieldset input[type=email]', :count => 1, :name => 'email', :class => 'string' + end + end + + context 'for #url_field_tag method' do + should "display url field in ruby" do + actual_html = url_field_tag(:webpage, :class => 'string') + assert_has_tag(:input, :type => 'url', :class => 'string', :name => 'webpage') { actual_html } + end + + should "display url field in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form input[type=url]', :count => 1, :name => 'webpage' + assert_have_selector 'form.advanced-form fieldset input[type=url]', :count => 1, :name => 'webpage', :class => 'string' + end + + should "display url field in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form input[type=url]', :count => 1, :name => 'webpage' + assert_have_selector 'form.advanced-form fieldset input[type=url]', :count => 1, :name => 'webpage', :class => 'string' + end + + should "display url field in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form input[type=url]', :count => 1, :name => 'webpage' + assert_have_selector 'form.advanced-form fieldset input[type=url]', :count => 1, :name => 'webpage', :class => 'string' + end + end + + context 'for #text_area_tag method' do + should "display text area in ruby" do + actual_html = text_area_tag(:about, :class => 'long') + assert_has_tag(:textarea, :class => "long", :name => 'about') { actual_html } + end + + should "display text area in ruby with specified content" do + actual_html = text_area_tag(:about, :value => "a test", :rows => 5, :cols => 6) + assert_has_tag(:textarea, :content => "a test", :name => 'about', :rows => "5", :cols => "6") { actual_html } + end + + should "display text area in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.advanced-form textarea', :count => 1, :name => 'about', :class => 'large' + end + + should "display text area in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.advanced-form textarea', :count => 1, :name => 'about', :class => 'large' + end + + should "display text area in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.advanced-form textarea', :count => 1, :name => 'about', :class => 'large' + end + end + + context 'for #password_field_tag method' do + should "display password field in ruby" do + actual_html = password_field_tag(:password, :class => 'long') + assert_has_tag(:input, :type => 'password', :class => "long", :name => 'password') { actual_html } + end + + should "display password field in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form input[type=password]', :count => 1, :name => 'password' + assert_have_selector 'form.advanced-form input[type=password]', :count => 1, :name => 'password' + end + + should "display password field in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form input[type=password]', :count => 1, :name => 'password' + assert_have_selector 'form.advanced-form input[type=password]', :count => 1, :name => 'password' + end + + should "display password field in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form input[type=password]', :count => 1, :name => 'password' + assert_have_selector 'form.advanced-form input[type=password]', :count => 1, :name => 'password' + end + end + + context 'for #file_field_tag method' do + should "display file field in ruby" do + actual_html = file_field_tag(:photo, :class => 'photo') + assert_has_tag(:input, :type => 'file', :class => "photo", :name => 'photo') { actual_html } + end + + should "have an array name with multiple option" do + actual_html = file_field_tag(:photos, :multiple => true) + assert_has_tag(:input, :name => 'photos[]') { actual_html } + end + + should "display file field in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.advanced-form input[type=file]', :count => 1, :name => 'photo', :class => 'upload' + end + + should "display file field in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.advanced-form input[type=file]', :count => 1, :name => 'photo', :class => 'upload' + end + + should "display file field in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.advanced-form input[type=file]', :count => 1, :name => 'photo', :class => 'upload' + end + end + + context "for #check_box_tag method" do + should "display check_box tag in ruby" do + actual_html = check_box_tag("clear_session") + assert_has_tag(:input, :type => 'checkbox', :value => '1', :name => 'clear_session') { actual_html } + assert_has_no_tag(:input, :type => 'hidden') { actual_html } + end + + should "display check_box tag in ruby with extended attributes" do + actual_html = check_box_tag("clear_session", :disabled => true, :checked => true) + assert_has_tag(:input, :type => 'checkbox', :disabled => 'disabled', :checked => 'checked') { actual_html } + end + + should "display check_box tag in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form input[type=checkbox]', :count => 1 + assert_have_selector 'form.advanced-form input[type=checkbox]', :value => "1", :checked => 'checked' + end + + should "display check_box tag in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form input[type=checkbox]', :count => 1 + assert_have_selector 'form.advanced-form input[type=checkbox]', :value => "1", :checked => 'checked' + end + + should "display check_box tag in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form input[type=checkbox]', :count => 1 + assert_have_selector 'form.advanced-form input[type=checkbox]', :value => "1", :checked => 'checked' + end + end + + context "for #radio_button_tag method" do + should "display radio_button tag in ruby" do + actual_html = radio_button_tag("gender", :value => 'male') + assert_has_tag(:input, :type => 'radio', :value => 'male', :name => 'gender') { actual_html } + end + + should "display radio_button tag in ruby with extended attributes" do + actual_html = radio_button_tag("gender", :disabled => true, :checked => true) + assert_has_tag(:input, :type => 'radio', :disabled => 'disabled', :checked => 'checked') { actual_html } + end + + should "display radio_button tag in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form input[type=radio]', :count => 1, :value => 'male' + assert_have_selector 'form.simple-form input[type=radio]', :count => 1, :value => 'female' + assert_have_selector 'form.advanced-form input[type=radio]', :value => "male", :checked => 'checked' + assert_have_selector 'form.advanced-form input[type=radio]', :value => "female" + end + + should "display radio_button tag in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form input[type=radio]', :count => 1, :value => 'male' + assert_have_selector 'form.simple-form input[type=radio]', :count => 1, :value => 'female' + assert_have_selector 'form.advanced-form input[type=radio]', :value => "male", :checked => 'checked' + assert_have_selector 'form.advanced-form input[type=radio]', :value => "female" + end + + should "display radio_button tag in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form input[type=radio]', :count => 1, :value => 'male' + assert_have_selector 'form.simple-form input[type=radio]', :count => 1, :value => 'female' + assert_have_selector 'form.advanced-form input[type=radio]', :value => "male", :checked => 'checked' + assert_have_selector 'form.advanced-form input[type=radio]', :value => "female" + end + end + + context "for #select_tag method" do + should "display select tag in ruby" do + actual_html = select_tag(:favorite_color, :options => ['green', 'blue', 'black'], :include_blank => true) + assert_has_tag(:select, :name => 'favorite_color') { actual_html } + assert_has_tag('select option:first-child', :content => '') { actual_html } + assert_has_tag('select option', :content => 'green', :value => 'green') { actual_html } + assert_has_tag('select option', :content => 'blue', :value => 'blue') { actual_html } + assert_has_tag('select option', :content => 'black', :value => 'black') { actual_html } + end + + should "display select tag in ruby with extended attributes" do + actual_html = select_tag(:favorite_color, :disabled => true, :options => ['only', 'option']) + assert_has_tag(:select, :disabled => 'disabled') { actual_html } + end + + should "take a range as a collection for options" do + actual_html = select_tag(:favorite_color, :options => (1..3)) + assert_has_tag(:select) { actual_html } + assert_has_tag('select option', :value => '1') { actual_html } + assert_has_tag('select option', :value => '2') { actual_html } + assert_has_tag('select option', :value => '3') { actual_html } + end + + should "include blank for grouped options" do + opts = { "Red" => ["Rose","Fire"], "Blue" => ["Sky","Sea"] } + actual_html = select_tag( 'color', :grouped_options => opts, :include_blank => true ) + assert_has_tag('select option:first-child', :value => "", :content => "") { actual_html } + end + + should "display select tag with grouped options for a nested array" do + opts = [ + ["Friends",["Yoda",["Obiwan",2]]], + ["Enemies", ["Palpatine",['Darth Vader',3]]] + ] + actual_html = select_tag( 'name', :grouped_options => opts ) + assert_has_tag(:select, :name => "name") { actual_html } + assert_has_tag(:optgroup, :label => "Friends") { actual_html } + assert_has_tag(:option, :value => "Yoda", :content => "Yoda") { actual_html } + assert_has_tag(:option, :value => "2", :content => "Obiwan") { actual_html } + assert_has_tag(:optgroup, :label => "Enemies") { actual_html } + assert_has_tag(:option, :value => "Palpatine", :content => "Palpatine") { actual_html } + assert_has_tag(:option, :value => "3", :content => "Darth Vader") { actual_html } + end + + should "display select tag with grouped options for a nested array and accept disabled groups" do + opts = [ + ["Friends",["Yoda",["Obiwan",2]]], + ["Enemies", ["Palpatine",['Darth Vader',3]], true] + ] + actual_html = select_tag( 'name', :grouped_options => opts ) + assert_has_tag(:select, :name => "name") { actual_html } + assert_has_tag(:option, :disabled => 'disabled', :count => 0) { actual_html } + assert_has_tag(:optgroup, :disabled => 'disabled', :count => 1) { actual_html } + assert_has_tag(:optgroup, :label => "Enemies", :disabled => 'disabled') { actual_html } + end + + should "display select tag with grouped options for a nested array and accept disabled groups and/or with disabled options" do + opts = [ + ["Friends",["Yoda",["Obiwan",2, true]]], + ["Enemies", [["Palpatine", "Palpatine", true],['Darth Vader',3]], true] + ] + actual_html = select_tag( 'name', :grouped_options => opts ) + assert_has_tag(:select, :name => "name") { actual_html } + assert_has_tag(:option, :disabled => 'disabled', :count => 2) { actual_html } + assert_has_tag(:optgroup, :disabled => 'disabled', :count => 1) { actual_html } + assert_has_tag(:option, :content => "Obiwan", :disabled => 'disabled') { actual_html } + assert_has_tag(:optgroup, :label => "Enemies", :disabled => 'disabled') { actual_html } + assert_has_tag(:option, :value => "Palpatine", :content => "Palpatine", :disabled => 'disabled') { actual_html } + end + + should "display select tag with grouped options for a hash" do + opts = { + "Friends" => ["Yoda",["Obiwan",2]], + "Enemies" => ["Palpatine",['Darth Vader',3]] + } + actual_html = select_tag( 'name', :grouped_options => opts ) + assert_has_tag(:select, :name => "name") { actual_html } + assert_has_tag(:optgroup, :label => "Friends") { actual_html } + assert_has_tag(:option, :value => "Yoda", :content => "Yoda") { actual_html } + assert_has_tag(:option, :value => "2", :content => "Obiwan") { actual_html } + assert_has_tag(:optgroup, :label => "Enemies") { actual_html } + assert_has_tag(:option, :value => "Palpatine", :content => "Palpatine") { actual_html } + assert_has_tag(:option, :value => "3", :content => "Darth Vader") { actual_html } + end + + should "display select tag with grouped options for a hash and accept disabled groups" do + opts = { + "Friends" => ["Yoda",["Obiwan",2]], + "Enemies" => ["Palpatine",['Darth Vader',3], {:disabled => true}] + } + actual_html = select_tag( 'name', :grouped_options => opts ) + assert_has_tag(:select, :name => "name") { actual_html } + assert_has_tag(:option, :disabled => 'disabled', :count => 0) { actual_html } + assert_has_tag(:optgroup, :disabled => 'disabled', :count => 1) { actual_html } + assert_has_tag(:optgroup, :label => "Enemies", :disabled => 'disabled') { actual_html } + end + + should "display select tag with grouped options for a hash and accept disabled groups and/or with disabled options" do + opts = { + "Friends" => ["Yoda",["Obiwan",2,true]], + "Enemies" => [["Palpatine","Palpatine",true],["Darth Vader",3], {:disabled => true}] + } + actual_html = select_tag( 'name', :grouped_options => opts ) + assert_has_tag(:select, :name => "name") { actual_html } + assert_has_tag(:option, :disabled => 'disabled', :count => 2) { actual_html } + assert_has_tag(:optgroup, :disabled => 'disabled', :count => 1) { actual_html } + assert_has_tag(:option, :content => "Obiwan", :disabled => 'disabled') { actual_html } + assert_has_tag(:optgroup, :label => "Enemies", :disabled => 'disabled') { actual_html } + assert_has_tag(:option, :value => "Palpatine", :content => "Palpatine", :disabled => 'disabled') { actual_html } + end + + + should "display select tag in ruby with multiple attribute" do + actual_html = select_tag(:favorite_color, :multiple => true, :options => ['only', 'option']) + assert_has_tag(:select, :multiple => 'multiple', :name => 'favorite_color[]') { actual_html } + end + + should "display options with values and single selected" do + options = [['Green', 'green1'], ['Blue', 'blue1'], ['Black', "black1"]] + actual_html = select_tag(:favorite_color, :options => options, :selected => 'green1') + assert_has_tag(:select, :name => 'favorite_color') { actual_html } + assert_has_tag('select option', :selected => 'selected', :count => 1) { actual_html } + assert_has_tag('select option', :content => 'Green', :value => 'green1', :selected => 'selected') { actual_html } + assert_has_tag('select option', :content => 'Blue', :value => 'blue1') { actual_html } + assert_has_tag('select option', :content => 'Black', :value => 'black1') { actual_html } + end + + should "display options with values and accept disabled options" do + options = [['Green', 'green1', true], ['Blue', 'blue1'], ['Black', "black1"]] + actual_html = select_tag(:favorite_color, :options => options) + assert_has_tag(:select, :name => 'favorite_color') { actual_html } + assert_has_tag('select option', :disabled => 'disabled', :count => 1) { actual_html } + assert_has_tag('select option', :content => 'Green', :value => 'green1', :disabled => 'disabled') { actual_html } + assert_has_tag('select option', :content => 'Blue', :value => 'blue1') { actual_html } + assert_has_tag('select option', :content => 'Black', :value => 'black1') { actual_html } + end + + should "display option with values and multiple selected" do + options = [['Green', 'green1'], ['Blue', 'blue1'], ['Black', "black1"]] + actual_html = select_tag(:favorite_color, :options => options, :selected => ['green1', 'Black']) + assert_has_tag(:select, :name => 'favorite_color') { actual_html } + assert_has_tag('select option', :selected => 'selected', :count => 2) { actual_html } + assert_has_tag('select option', :content => 'Green', :value => 'green1', :selected => 'selected') { actual_html } + assert_has_tag('select option', :content => 'Blue', :value => 'blue1') { actual_html } + assert_has_tag('select option', :content => 'Black', :value => 'black1', :selected => 'selected') { actual_html } + end + + should "display options selected only for exact match" do + options = [['One', '1'], ['1', '10'], ['Two', "-1"]] + actual_html = select_tag(:range, :options => options, :selected => '-1') + assert_has_tag(:select, :name => 'range') { actual_html } + assert_has_tag('select option', :selected => 'selected', :count => 1) { actual_html } + assert_has_tag('select option', :content => 'Two', :value => '-1', :selected => 'selected') { actual_html } + end + + should "display select tag in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form select', :count => 1, :name => 'color' + assert_have_selector('select option', :content => 'green', :value => 'green') + assert_have_selector('select option', :content => 'orange', :value => 'orange') + assert_have_selector('select option', :content => 'purple', :value => 'purple') + assert_have_selector('form.advanced-form select', :name => 'fav_color') + assert_have_selector('select option', :content => 'green', :value => '1') + assert_have_selector('select option', :content => 'orange', :value => '2', :selected => 'selected') + assert_have_selector('select option', :content => 'purple', :value => '3') + assert_have_selector('select optgroup', :label => 'foo') + assert_have_selector('select optgroup', :label => 'bar') + assert_have_selector('select optgroup option', :content => 'foo', :value => 'foo') + assert_have_selector('select optgroup option', :content => 'bar', :value => 'bar') + assert_have_selector('select optgroup', :label => 'Friends') + assert_have_selector('select optgroup', :label => 'Enemies') + assert_have_selector('select optgroup option', :content => 'Yoda', :value => 'Yoda') + assert_have_selector('select optgroup option', :content => 'Obiwan', :value => '1') + assert_have_selector('select optgroup option', :content => 'Palpatine', :value => 'Palpatine') + assert_have_selector('select optgroup option', :content => 'Darth Vader', :value => '3') + end + + should "display select tag in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form select', :count => 1, :name => 'color' + assert_have_selector('select option', :content => 'green', :value => 'green') + assert_have_selector('select option', :content => 'orange', :value => 'orange') + assert_have_selector('select option', :content => 'purple', :value => 'purple') + assert_have_selector('form.advanced-form select', :name => 'fav_color') + assert_have_selector('select option', :content => 'green', :value => '1') + assert_have_selector('select option', :content => 'orange', :value => '2', :selected => 'selected') + assert_have_selector('select option', :content => 'purple', :value => '3') + assert_have_selector('select optgroup', :label => 'foo') + assert_have_selector('select optgroup', :label => 'bar') + assert_have_selector('select optgroup option', :content => 'foo', :value => 'foo') + assert_have_selector('select optgroup option', :content => 'bar', :value => 'bar') + assert_have_selector('select optgroup', :label => 'Friends') + assert_have_selector('select optgroup', :label => 'Enemies') + assert_have_selector('select optgroup option', :content => 'Yoda', :value => 'Yoda') + assert_have_selector('select optgroup option', :content => 'Obiwan', :value => '1') + assert_have_selector('select optgroup option', :content => 'Palpatine', :value => 'Palpatine') + assert_have_selector('select optgroup option', :content => 'Darth Vader', :value => '3') + end + + should "display select tag in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form select', :count => 1, :name => 'color' + assert_have_selector('select option', :content => 'green', :value => 'green') + assert_have_selector('select option', :content => 'orange', :value => 'orange') + assert_have_selector('select option', :content => 'purple', :value => 'purple') + assert_have_selector('form.advanced-form select', :name => 'fav_color') + assert_have_selector('select option', :content => 'green', :value => '1') + assert_have_selector('select option', :content => 'orange', :value => '2', :selected => 'selected') + assert_have_selector('select option', :content => 'purple', :value => '3') + assert_have_selector('select optgroup', :label => 'foo') + assert_have_selector('select optgroup', :label => 'bar') + assert_have_selector('select optgroup option', :content => 'foo', :value => 'foo') + assert_have_selector('select optgroup option', :content => 'bar', :value => 'bar') + assert_have_selector('select optgroup', :label => 'Friends') + assert_have_selector('select optgroup', :label => 'Enemies') + assert_have_selector('select optgroup option', :content => 'Yoda', :value => 'Yoda') + assert_have_selector('select optgroup option', :content => 'Obiwan', :value => '1') + assert_have_selector('select optgroup option', :content => 'Palpatine', :value => 'Palpatine') + assert_have_selector('select optgroup option', :content => 'Darth Vader', :value => '3') + end + end + + context 'for #submit_tag method' do + should "display submit tag in ruby" do + actual_html = submit_tag("Update", :class => 'success') + assert_has_tag(:input, :type => 'submit', :class => "success", :value => 'Update') { actual_html } + end + + should "display submit tag in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form input[type=submit]', :count => 1, :value => "Submit" + assert_have_selector 'form.advanced-form input[type=submit]', :count => 1, :value => "Login" + end + + should "display submit tag in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.simple-form input[type=submit]', :count => 1, :value => "Submit" + assert_have_selector 'form.advanced-form input[type=submit]', :count => 1, :value => "Login" + end + + should "display submit tag in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.simple-form input[type=submit]', :count => 1, :value => "Submit" + assert_have_selector 'form.advanced-form input[type=submit]', :count => 1, :value => "Login" + end + + context 'for omitted args' do + should "display submit tag with default caption" do + actual_html = submit_tag() + assert_has_tag(:input, :type => 'submit', :value => 'Submit') { actual_html } + end + end + + context 'for omitted caption arg' do + should "display submit tag with default caption" do + actual_html = submit_tag(:class => 'success') + assert_has_tag(:input, :type => 'submit', :class => 'success', :value => 'Submit') { actual_html } + end + + should "display submit tag without caption value when nil" do + actual_html = submit_tag(nil, :class => 'success') + assert_has_tag(:input, :type => 'submit', :class => 'success') { actual_html } + assert_has_no_tag(:input, :type => 'submit', :class => 'success', :value => 'Submit') { actual_html } + end + end + end + + context 'for #button_tag method' do + should "display submit tag in ruby" do + actual_html = button_tag("Cancel", :class => 'clear') + assert_has_tag(:input, :type => 'button', :class => "clear", :value => 'Cancel') { actual_html } + end + + should "display submit tag in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.advanced-form input[type=button]', :count => 1, :value => "Cancel" + end + + should "display submit tag in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.advanced-form input[type=button]', :count => 1, :value => "Cancel" + end + + should "display submit tag in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.advanced-form input[type=button]', :count => 1, :value => "Cancel" + end + end + + context 'for #image_submit_tag method' do + setup do + @stamp = stop_time_for_test.to_i + end + + should "display image submit tag in ruby with relative path" do + actual_html = image_submit_tag('buttons/ok.png', :class => 'success') + assert_has_tag(:input, :type => 'image', :class => "success", :src => "/images/buttons/ok.png?#{@stamp}") { actual_html } + end + + should "display image submit tag in ruby with absolute path" do + actual_html = image_submit_tag('/system/ok.png', :class => 'success') + assert_has_tag(:input, :type => 'image', :class => "success", :src => "/system/ok.png") { actual_html } + end + + should "display image submit tag in erb" do + visit '/erb/form_tag' + assert_have_selector 'form.advanced-form input[type=image]', :count => 1, :src => "/images/buttons/submit.png?#{@stamp}" + end + + should "display image submit tag in haml" do + visit '/haml/form_tag' + assert_have_selector 'form.advanced-form input[type=image]', :count => 1, :src => "/images/buttons/submit.png?#{@stamp}" + end + + should "display image submit tag in slim" do + visit '/slim/form_tag' + assert_have_selector 'form.advanced-form input[type=image]', :count => 1, :src => "/images/buttons/submit.png?#{@stamp}" + end + end + + context 'for #button_to method' do + should "have a form and set the method properly" do + actual_html = button_to('Delete', '/users/1', :method => :delete) + assert_has_tag('form', :action => '/users/1') { actual_html } + assert_has_tag('form input', :type => 'hidden', :name => "_method", :value => 'delete') { actual_html } + assert_has_tag('form input', :type => 'hidden', :name => "authenticity_token") { actual_html } + end + + should "add a submit button by default if no content is specified" do + actual_html = button_to('My Delete Button', '/users/1', :method => :delete) + assert_has_tag('form input', :type => 'submit', :value => 'My Delete Button') { actual_html } + end + + should "set specific content inside the form if a block was sent" do + actual_html = button_to('My Delete Button', '/users/1', :method => :delete) do + content_tag :button, "My button's content", :type => :submit, :title => "My button" + end + assert_has_tag('form button', :type => 'submit', :content => "My button's content", :title => "My button") { actual_html } + end + + should "pass options on submit button when submit_options are given" do + actual_html = button_to("Fancy button", '/users/1', :submit_options => { :class => :fancy }) + assert_has_tag('form input', :type => 'submit', :value => 'Fancy button', :class => 'fancy') { actual_html } + end + + should 'display correct button_to in erb' do + visit '/erb/button_to' + assert_have_selector('form', :action => '/foo') + assert_have_selector('form label', :for => 'username', :content => 'Username: ') + assert_have_selector('form', :action => '/bar') + assert_have_selector('#test-point ~ form > input[type=submit]', :value => 'Bar button') + end + + should 'display correct button_to in haml' do + visit '/haml/button_to' + assert_have_selector('form', :action => '/foo') + assert_have_selector('form label', :for => 'username', :content => 'Username: ') + assert_have_selector('form', :action => '/bar') + assert_have_selector('#test-point ~ form > input[type=submit]', :value => 'Bar button') + end + + should 'display correct button_to in slim' do + visit '/slim/button_to' + assert_have_selector('form', :action => '/foo') + assert_have_selector('form label', :for => 'username', :content => 'Username: ') + assert_have_selector('form', :action => '/bar') + assert_have_selector('#test-point ~ form > input[type=submit]', :value => 'Bar button') + end + end + + context 'for #range_field_tag' do + should "create an input tag with min and max options" do + actual_html = range_field_tag('ranger', :min => 20, :max => 50) + assert_has_tag('input', :type => 'range', :name => 'ranger', :min => '20', :max => '50') { actual_html } + end + + should "create an input tag with range" do + actual_html = range_field_tag('ranger', :range => 1..20) + assert_has_tag('input', :min => '1', :max => '20') { actual_html } + end + + should "display correct range_field_tag in erb" do + visit '/erb/form_tag' + assert_have_selector 'input', :type => 'range', :name => 'ranger_with_min_max', :min => '1', :max => '50', :count => 1 + assert_have_selector 'input', :type => 'range', :name => 'ranger_with_range', :min => '1', :max => '5', :count => 1 + end + + should "display correct range_field_tag in haml" do + visit '/haml/form_tag' + assert_have_selector 'input', :type => 'range', :name => 'ranger_with_min_max', :min => '1', :max => '50', :count => 1 + assert_have_selector 'input', :type => 'range', :name => 'ranger_with_range', :min => '1', :max => '5', :count => 1 + end + + should "display correct range_field_tag in slim" do + visit '/slim/form_tag' + assert_have_selector 'input', :type => 'range', :name => 'ranger_with_min_max', :min => '1', :max => '50', :count => 1 + assert_have_selector 'input', :type => 'range', :name => 'ranger_with_range', :min => '1', :max => '5', :count => 1 + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_format_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_format_helpers.rb new file mode 100644 index 00000000..52108099 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_format_helpers.rb @@ -0,0 +1,241 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require File.expand_path(File.dirname(__FILE__) + '/fixtures/markup_app/app') + +describe "FormatHelpers" do + include Padrino::Helpers::FormatHelpers + + def app + MarkupDemo + end + + def setup + Time.stubs(:now).returns(Time.utc(1983, 11, 9, 5)) + end + + context 'for #simple_format method' do + should "format simple text into html format" do + actual_text = simple_format("Here is some basic text...\n...with a line break.") + assert_equal true, actual_text.html_safe? + assert_equal "

Here is some basic text...\n
...with a line break.

", actual_text + end + + should "format more text into html format" do + actual_text = simple_format("We want to put a paragraph...\n\n...right there.") + assert_equal "

We want to put a paragraph...

\n\n

...right there.

", actual_text + end + + should "support defining a class for the paragraphs" do + actual_text = simple_format("Look me! A class!", :class => 'description') + assert_equal "

Look me! A class!

", actual_text + end + + context 'wrapped in a custom tag' do + should "format simple text into html format" do + actual_text = simple_format("Here is some basic text...\n...with a line break.", :tag => :div) + assert_equal "
Here is some basic text...\n
...with a line break.
", actual_text + end + + should "format more text into html format" do + actual_text = simple_format("We want to put a paragraph...\n\n...right there.", :tag => :div) + assert_equal "
We want to put a paragraph...
\n\n
...right there.
", actual_text + end + + should "support defining a class for the paragraphs" do + actual_text = simple_format("Look me! A class!", :class => 'description', :tag => :div) + assert_equal "
Look me! A class!
", actual_text + end + end + end + + context 'for #pluralize method' do + should "return singular count for 1 item collections" do + actual_text = pluralize(1, 'person') + assert_equal '1 person', actual_text + end + should "return plural count for empty collections" do + actual_text = pluralize(0, 'person') + assert_equal '0 people', actual_text + end + should "return plural count for many collections" do + actual_text = pluralize(2, 'person') + assert_equal '2 people', actual_text + end + should "return pluralized word specified as argument" do + actual_text = pluralize(3, 'person', 'users') + assert_equal '3 users', actual_text + end + end + + context 'for #word_wrap method' do + should "return proper formatting for 8 max width" do + actual_text = word_wrap('Once upon a time', :line_width => 8) + assert_equal "Once\nupon a\ntime", actual_text + end + should "return proper formatting for 1 max width" do + actual_text = word_wrap('Once upon a time', :line_width => 1) + assert_equal "Once\nupon\na\ntime", actual_text + end + should "return proper formatting for default width" do + actual_text = word_wrap((1..50).to_a.join(" ")) + assert_equal (1..30).to_a.join(" ") + "\n" + (31..50).to_a.join(" "), actual_text + actual_text = word_wrap((1..50).to_a.join(" "), 80) + assert_equal (1..30).to_a.join(" ") + "\n" + (31..50).to_a.join(" "), actual_text + end + end + + context 'for #highlight method' do + should 'highligth with defaults' do + actual_text = highlight('Lorem ipsum dolor sit amet', 'dolor') + assert_equal 'Lorem ipsum dolor sit amet', actual_text + end + + should 'highlight with highlighter' do + actual_text = highlight('Lorem ipsum dolor sit amet', 'dolor', :highlighter => '\1') + assert_equal 'Lorem ipsum dolor sit amet', actual_text + end + end + + context 'for #truncate method' do + should "support default truncation" do + actual_text = truncate("Once upon a time in a world far far away") + assert_equal "Once upon a time in a world...", actual_text + end + should "support specifying length" do + actual_text = truncate("Once upon a time in a world far far away", :length => 14) + assert_equal "Once upon a...", actual_text + end + should "support specifying omission text" do + actual_text = truncate("And they found that many people were sleeping better.", :length => 25, :omission => "(clipped)") + assert_equal "And they found t(clipped)", actual_text + end + end + + context 'for #truncate_words method' do + should "support default truncation" do + actual_text = truncate_words("Long before books were made, people told stories. They told them to one another and to the children as they sat before the fire. Many of these stories were about interesting people, but most of them were about the ways of fairies and giants.") + assert_equal "Long before books were made, people told stories. They told them to one another and to the children as they sat before the fire. Many of these stories were about...", actual_text + end + should "support specifying length" do + actual_text = truncate_words("Once upon a time in a world far far away", :length => 8) + assert_equal "Once upon a time in a world far...", actual_text + end + should "support specifying omission text" do + actual_text = truncate_words("And they found that many people were sleeping better.", :length => 4, :omission => "(clipped)") + assert_equal "And they found that(clipped)", actual_text + end + end + + context 'for #h and #h! method' do + should "escape the simple html" do + assert_equal '<h1>hello</h1>', h('

hello

') + assert_equal '<h1>hello</h1>', escape_html('

hello

') + end + should "escape all brackets, quotes and ampersands" do + assert_equal '<h1><>"&demo&"<></h1>', h('

<>"&demo&"<>

') + end + should "return default text if text is empty" do + assert_equal 'default', h!("", "default") + assert_equal ' ', h!("") + end + should "return text escaped if not empty" do + assert_equal '<h1>hello</h1>', h!('

hello

') + end + should "mark escaped text as safe" do + assert_equal false, '

hello

'.html_safe? + assert_equal true, h('

hello

').html_safe? + assert_equal true, h!("", "default").html_safe? + end + end + + context 'for #time_ago_in_words method' do + should "less than 5 seconds" do + assert_equal 'less than 5 seconds', time_ago_in_words(Time.now, true) + end + should "less than 10 seconds" do + assert_equal 'less than 10 seconds', time_ago_in_words(Time.now-5, true) + end + should "less than 20 seconds" do + assert_equal 'less than 20 seconds', time_ago_in_words(Time.now-10, true) + end + should "less than a minute" do + assert_equal 'less than a minute', time_ago_in_words(Time.now-40, true) + end + should "2 minutes" do + assert_equal '2 minutes', time_ago_in_words(Time.now-120, true) + end + should "display today" do + assert_equal 'less than a minute', time_ago_in_words(Time.now) + end + should "display yesterday" do + assert_equal '1 day', time_ago_in_words(1.day.ago) + end + should "display tomorrow" do + assert_equal '1 day', time_ago_in_words(1.day.from_now) + end + should "return future number of days" do + assert_equal '4 days', time_ago_in_words(4.days.from_now) + end + should "return past days ago" do + assert_equal '4 days', time_ago_in_words(4.days.ago) + end + should "return formatted archived date" do + assert_equal '3 months', time_ago_in_words(100.days.ago) + end + should "return formatted archived year date" do + assert_equal 'over 1 year', time_ago_in_words(500.days.ago) + end + should 'display now as a minute ago' do + assert_equal '1 minute', time_ago_in_words(1.minute.ago) + end + should "display a few minutes ago" do + assert_equal '4 minutes', time_ago_in_words(4.minute.ago) + end + should "display an hour ago" do + assert_equal 'about 1 hour', time_ago_in_words(1.hour.ago + 5.minutes.ago.sec) + end + should "display a few hours ago" do + assert_equal 'about 3 hours', time_ago_in_words(3.hour.ago + 5.minutes.ago.sec) + end + should "display a day ago" do + assert_equal '1 day', time_ago_in_words(1.day.ago) + end + should "display a few days ago" do + assert_equal '5 days', time_ago_in_words(5.days.ago - 5.minutes.ago.sec) + end + should "display a month ago" do + assert_equal 'about 1 month', time_ago_in_words(32.days.ago + 5.minutes.ago.sec) + end + should "display a few months ago" do + assert_equal '6 months', time_ago_in_words(180.days.ago - 5.minutes.ago.sec) + end + should "display a year ago" do + assert_equal 'about 1 year', time_ago_in_words(365.days.ago - 5.minutes.ago.sec) + end + should "display a few years ago" do + assert_equal 'over 7 years', time_ago_in_words(2800.days.ago - 5.minutes.ago.sec) + end + end + + context 'for #js_escape_html method' do + should "escape double quotes" do + assert_equal "\\\"hello\\\"", js_escape_html('"hello"') + assert_equal "\\\"hello\\\"", js_escape_html(ActiveSupport::SafeBuffer.new('"hello"')) + end + should "escape single quotes" do + assert_equal "\\'hello\\'", js_escape_html("'hello'") + assert_equal "\\'hello\\'", js_escape_html(ActiveSupport::SafeBuffer.new("'hello'")) + end + should "escape html tags and breaks" do + assert_equal "\\n\\n

hello<\\/p>\\n", js_escape_html("\n\r

hello

\r\n") + assert_equal "\\n\\n

hello<\\/p>\\n", js_escape_html(ActiveSupport::SafeBuffer.new("\n\r

hello

\r\n")) + end + should "escape data-confirm attribute" do + assert_equal "", js_escape_html("") + assert_equal "", js_escape_html(ActiveSupport::SafeBuffer.new("")) + end + should "keep html_safe content html_safe" do + assert_equal false, js_escape_html('"hello"').html_safe? + assert_equal true, js_escape_html(ActiveSupport::SafeBuffer.new('"hello"')).html_safe? + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_locale.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_locale.rb new file mode 100644 index 00000000..06b8b501 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_locale.rb @@ -0,0 +1,20 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +describe "Locale Helpers" do + Dir[File.expand_path("../../lib/padrino-helpers/locale/*.yml", __FILE__)].each do |file| + base_original = YAML.load_file(file) + name = File.basename(file, '.yml') + should "should have correct locale for #{name}" do + base = base_original[name]['number']['format'] + assert !base['separator'].nil? + assert !base['delimiter'].nil? + assert !base['precision'].nil? + base = base_original[name]['number']['currency']['format'] + assert !base['format'].nil? + assert !base['unit'].nil? + assert !base['separator'].nil? + assert !base['delimiter'].nil? + assert !base['precision'].nil? + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_number_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_number_helpers.rb new file mode 100644 index 00000000..24f659c7 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_number_helpers.rb @@ -0,0 +1,143 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require File.expand_path(File.dirname(__FILE__) + '/fixtures/markup_app/app') + +describe "NumberHelpers" do + include Padrino::Helpers::NumberHelpers + + def app + MarkupDemo + end + + def kilobytes(number) + number * 1024 + end + + def megabytes(number) + kilobytes(number) * 1024 + end + + def gigabytes(number) + megabytes(number) * 1024 + end + + def terabytes(number) + gigabytes(number) * 1024 + end + + context 'for number helpers functionality' do + + should 'display number_to_currency' do + assert_equal "$1,234,567,890.50", number_to_currency(1234567890.50) + assert_equal "$1,234,567,890.51", number_to_currency(1234567890.506) + assert_equal "$1,234,567,892", number_to_currency(1234567891.50, {:precision => 0}) + assert_equal "$1,234,567,890.5", number_to_currency(1234567890.50, {:precision => 1}) + assert_equal "£1234567890,50", number_to_currency(1234567890.50, {:unit => "£", :separator => ",", :delimiter => ""}) + assert_equal "$1,234,567,890.50", number_to_currency("1234567890.50") + assert_equal "1,234,567,890.50 Kč", number_to_currency("1234567890.50", {:unit => "Kč", :format => "%n %u"}) + assert_equal "$x", number_to_currency("x") + + assert_nil number_to_currency(nil) + end + + should 'display number_to_percentage' do + assert_equal "100.000%", number_to_percentage(100) + assert_equal "100%", number_to_percentage(100, {:precision => 0}) + assert_equal "302.06%", number_to_percentage(302.0574, {:precision => 2}) + assert_equal "100.000%", number_to_percentage("100") + assert_equal "1000.000%", number_to_percentage("1000") + assert_equal "x%", number_to_percentage("x") + assert_equal "1.000,000%", number_to_percentage(1000, :delimiter => '.', :separator => ',') + + assert_nil number_to_percentage(nil) + end + + should 'display number_with_delimiter' do + assert_equal "12,345,678", number_with_delimiter(12345678) + assert_equal "0", number_with_delimiter(0) + assert_equal "123", number_with_delimiter(123) + assert_equal "123,456", number_with_delimiter(123456) + assert_equal "123,456.78", number_with_delimiter(123456.78) + assert_equal "123,456.789", number_with_delimiter(123456.789) + assert_equal "123,456.78901", number_with_delimiter(123456.78901) + assert_equal "123,456,789.78901", number_with_delimiter(123456789.78901) + assert_equal "0.78901", number_with_delimiter(0.78901) + assert_equal "123,456.78", number_with_delimiter("123456.78") + assert_equal "x", number_with_delimiter("x") + + assert_nil number_with_delimiter(nil) + end + + should 'display number_with_delimiter with options' do + assert_equal '12 345 678', number_with_delimiter(12345678, :delimiter => ' ') + assert_equal '12,345,678-05', number_with_delimiter(12345678.05, :separator => '-') + assert_equal '12.345.678,05', number_with_delimiter(12345678.05, :separator => ',', :delimiter => '.') + assert_equal '12.345.678,05', number_with_delimiter(12345678.05, :delimiter => '.', :separator => ',') + end + + should 'display number_with_precision' do + assert_equal "111.235", number_with_precision(111.2346) + assert_equal "31.83", number_with_precision(31.825, :precision => 2) + assert_equal "111.23", number_with_precision(111.2346, :precision => 2) + assert_equal "111.00", number_with_precision(111, :precision => 2) + assert_equal "111.235", number_with_precision("111.2346") + assert_equal "31.83", number_with_precision("31.825", :precision => 2) + assert_equal "3268", number_with_precision((32.6751 * 100.00), :precision => 0) + assert_equal "112", number_with_precision(111.50, :precision => 0) + assert_equal "1234567892", number_with_precision(1234567891.50, :precision => 0) + + # Return non-numeric params unchanged. + assert_equal "x", number_with_precision("x") + assert_nil number_with_precision(nil) + end + + should 'display number_with_precision with custom delimiter and separator' do + assert_equal '31,83', number_with_precision(31.825, :precision => 2, :separator => ',') + assert_equal '1.231,83', number_with_precision(1231.825, :precision => 2, :separator => ',', :delimiter => '.') + end + + should 'display number_to_human_size' do + assert_equal '0 Bytes', number_to_human_size(0) + assert_equal '1 Byte', number_to_human_size(1) + assert_equal '3 Bytes', number_to_human_size(3.14159265) + assert_equal '123 Bytes', number_to_human_size(123.0) + assert_equal '123 Bytes', number_to_human_size(123) + assert_equal '1.2 KB', number_to_human_size(1234) + assert_equal '12.1 KB', number_to_human_size(12345) + assert_equal '1.2 MB', number_to_human_size(1234567) + assert_equal '1.1 GB', number_to_human_size(1234567890) + assert_equal '1.1 TB', number_to_human_size(1234567890123) + assert_equal '1025 TB', number_to_human_size(terabytes(1025)) + assert_equal '444 KB', number_to_human_size(kilobytes(444)) + assert_equal '1023 MB', number_to_human_size(megabytes(1023)) + assert_equal '3 TB', number_to_human_size(terabytes(3)) + assert_equal '1.18 MB', number_to_human_size(1234567, :precision => 2) + assert_equal '3 Bytes', number_to_human_size(3.14159265, :precision => 4) + assert_equal '123 Bytes', number_to_human_size("123") + assert_equal '1.01 KB', number_to_human_size(kilobytes(1.0123), :precision => 2) + assert_equal '1.01 KB', number_to_human_size(kilobytes(1.0100), :precision => 4) + assert_equal '10 KB', number_to_human_size(kilobytes(10.000), :precision => 4) + assert_equal '1 Byte', number_to_human_size(1.1) + assert_equal '10 Bytes', number_to_human_size(10) + + assert_nil number_to_human_size(nil) + end + + should 'display number_to_human_size with options' do + assert_equal '1.18 MB', number_to_human_size(1234567, :precision => 2) + assert_equal '3 Bytes', number_to_human_size(3.14159265, :precision => 4) + assert_equal '1.01 KB', number_to_human_size(kilobytes(1.0123), :precision => 2) + assert_equal '1.01 KB', number_to_human_size(kilobytes(1.0100), :precision => 4) + assert_equal '10 KB', number_to_human_size(kilobytes(10.000), :precision => 4) + assert_equal '1 TB', number_to_human_size(1234567890123, :precision => 0) + assert_equal '500 MB', number_to_human_size(524288000, :precision => 0) + assert_equal '40 KB', number_to_human_size(41010, :precision => 0) + assert_equal '40 KB', number_to_human_size(41100, :precision => 0) + end + + should 'display number_to_human_size with custom delimiter and separator' do + assert_equal '1,01 KB', number_to_human_size(kilobytes(1.0123), :precision => 2, :separator => ',') + assert_equal '1,01 KB', number_to_human_size(kilobytes(1.0100), :precision => 4, :separator => ',') + assert_equal '1.000,1 TB', number_to_human_size(terabytes(1000.1), :delimiter => '.', :separator => ',') + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_output_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_output_helpers.rb new file mode 100644 index 00000000..2140bec2 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_output_helpers.rb @@ -0,0 +1,154 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require File.expand_path(File.dirname(__FILE__) + '/fixtures/markup_app/app') + +describe "OutputHelpers" do + def app + MarkupDemo + end + + context 'for #content_for method' do + should 'work for erb templates' do + visit '/erb/content_for' + assert_have_selector '.demo h1', :content => "This is content yielded from a content_for" + assert_have_selector '.demo2 h1', :content => "This is content yielded with name Johnny Smith" + end + + should "work for haml templates" do + visit '/haml/content_for' + assert_have_selector '.demo h1', :content => "This is content yielded from a content_for" + assert_have_selector '.demo2 h1', :content => "This is content yielded with name Johnny Smith" + end + + should "work for slim templates" do + visit '/slim/content_for' + assert_have_selector '.demo h1', :content => "This is content yielded from a content_for" + assert_have_selector '.demo2 h1', :content => "This is content yielded with name Johnny Smith" + end + end # content_for + + context "for #content_for? method" do + should 'work for erb templates' do + visit '/erb/content_for' + assert_have_selector '.demo_has_content', :content => "true" + assert_have_selector '.fake_has_content', :content => "false" + end + + should "work for haml templates" do + visit '/haml/content_for' + assert_have_selector '.demo_has_content', :content => "true" + assert_have_selector '.fake_has_content', :content => "false" + end + + should "work for slim templates" do + visit '/slim/content_for' + assert_have_selector '.demo_has_content', :content => "true" + assert_have_selector '.fake_has_content', :content => "false" + end + end # content_for? + + context 'for #capture_html method' do + should "work for erb templates" do + visit '/erb/capture_concat' + assert_have_selector 'p span', :content => "Captured Line 1" + assert_have_selector 'p span', :content => "Captured Line 2" + end + + should "work for haml templates" do + visit '/haml/capture_concat' + assert_have_selector 'p span', :content => "Captured Line 1" + assert_have_selector 'p span', :content => "Captured Line 2" + end + + should "work for slim templates" do + visit '/slim/capture_concat' + assert_have_selector 'p span', :content => "Captured Line 1" + assert_have_selector 'p span', :content => "Captured Line 2" + end + end + + context 'for #concat_content method' do + should "work for erb templates" do + visit '/erb/capture_concat' + assert_have_selector 'p', :content => "Concat Line 3", :count => 1 + end + + should "work for haml templates" do + visit '/haml/capture_concat' + assert_have_selector 'p', :content => "Concat Line 3", :count => 1 + end + + should "work for slim templates" do + visit '/slim/capture_concat' + # TODO Get Slim concat working + # assert_have_selector 'p', :content => "Concat Line 3", :count => 1 + end + end + + context 'for #block_is_template?' do + should "work for erb templates" do + visit '/erb/capture_concat' + assert_have_selector 'p', :content => "The erb block passed in is a template", :class => 'is_template' + # TODO Get ERB template detection working (fix block_is_erb? method) + # assert_have_no_selector 'p', :content => "The ruby block passed in is a template", :class => 'is_template' + end + + should "work for haml templates" do + visit '/haml/capture_concat' + assert_have_selector 'p', :content => "The haml block passed in is a template", :class => 'is_template' + assert_have_no_selector 'p', :content => "The ruby block passed in is a template", :class => 'is_template' + end + + should "work for slim templates" do + visit '/slim/capture_concat' + # TODO Get Slim template detection working + # assert_have_selector 'p', :content => "The slim block passed in is a template", :class => 'is_template' + assert_have_no_selector 'p', :content => "The ruby block passed in is a template", :class => 'is_template' + end + end + + context 'for #current_engine method' do + should 'detect correctly current engine for erb' do + visit '/erb/current_engine' + assert_have_selector 'p.start', :content => "erb" + assert_have_selector 'p.haml', :content => "haml" + assert_have_selector 'p.erb', :content => "erb" + assert_have_selector 'p.slim', :content => "slim" + assert_have_selector 'p.end', :content => "erb" + end + + should 'detect correctly current engine for haml' do + visit '/haml/current_engine' + assert_have_selector 'p.start', :content => "haml" + assert_have_selector 'p.haml', :content => "haml" + assert_have_selector 'p.erb', :content => "erb" + assert_have_selector 'p.slim', :content => "slim" + assert_have_selector 'p.end', :content => "haml" + end + + should 'detect correctly current engine for slim' do + visit '/slim/current_engine' + assert_have_selector 'p.start', :content => "slim" + assert_have_selector 'p.haml', :content => "haml" + assert_have_selector 'p.erb', :content => "erb" + assert_have_selector 'p.slim', :content => "slim" + assert_have_selector 'p.end', :content => "slim" + end + end + + context 'for #partial method in simple sinatra application' do + should 'properly output in erb' do + visit '/erb/simple_partial' + assert_have_selector 'p.erb', :content => "erb" + end + + should 'properly output in haml' do + visit '/haml/simple_partial' + assert_have_selector 'p.haml', :content => "haml" + end + + should 'properly output in slim' do + visit '/slim/simple_partial' + assert_have_selector 'p.slim', :content => "slim" + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_render_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_render_helpers.rb new file mode 100644 index 00000000..c4dffb5a --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_render_helpers.rb @@ -0,0 +1,94 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require File.expand_path(File.dirname(__FILE__) + '/fixtures/render_app/app') + +describe "RenderHelpers" do + def app + RenderDemo + end + + context 'for #partial method and object' do + setup { visit '/partial/object' } + should "render partial html with object" do + assert_have_selector "h1", :content => "User name is John" + end + should "have no counter index for single item" do + assert_have_no_selector "p", :content => "My counter is 1", :count => 1 + end + should "include extra locals information" do + assert_have_selector 'p', :content => "Extra is bar" + end + end + + context 'for #partial method and collection' do + setup { visit '/partial/collection' } + should "render partial html with collection" do + assert_have_selector "h1", :content => "User name is John" + assert_have_selector "h1", :content => "User name is Billy" + end + should "include counter which contains item index" do + assert_have_selector "p", :content => "My counter is 1" + assert_have_selector "p", :content => "My counter is 2" + end + should "include extra locals information" do + assert_have_selector 'p', :content => "Extra is bar" + end + end + + context 'for #partial method and locals' do + setup { visit '/partial/locals' } + should "render partial html with locals" do + assert_have_selector "h1", :content => "User name is John" + end + should "have no counter index for single item" do + assert_have_no_selector "p", :content => "My counter is 1", :count => 1 + end + should "include extra locals information" do + assert_have_selector 'p', :content => "Extra is bar" + end + end + + context 'for #partial method taking a path starting with forward slash' do + setup { visit '/partial/foward_slash' } + should "render partial without throwing an error" do + assert_have_selector "h1", :content => "User name is John" + end + end + + context 'for #current_engine method' do + should 'detect correctly current engine for a padrino application' do + visit '/current_engine' + assert_have_selector 'p.start', :content => "haml" + assert_have_selector 'p.haml span', :content => "haml" + assert_have_selector 'p.erb span', :content => "erb" + assert_have_selector 'p.slim span', :content => "slim" + assert_have_selector 'p.end', :content => "haml" + end + + should "detect correctly current engine for explicit engine on partials" do + visit '/explicit_engine' + assert_have_selector 'p.start', :content => "haml" + assert_have_selector 'p.haml span', :content => "haml" + assert_have_selector 'p.erb span', :content => "erb" + assert_have_selector 'p.slim span', :content => "slim" + assert_have_selector 'p.end', :content => "haml" + end + + should "capture slim template once and only once" do + $number_of_captures = 0 + visit '/double_capture_slim' + assert_equal 1,$number_of_captures + end + + should "capture haml template once and only once" do + $number_of_captures = 0 + visit '/double_capture_haml' + assert_equal 1,$number_of_captures + end + + should "capture erb template once and only once" do + $number_of_captures = 0 + visit '/double_capture_erb' + assert_equal 1,$number_of_captures + end + end +end diff --git a/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_tag_helpers.rb b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_tag_helpers.rb new file mode 100644 index 00000000..1bec5fb0 --- /dev/null +++ b/middleman-core/lib/vendored-middleman-deps/padrino-helpers-0.11.4/test/test_tag_helpers.rb @@ -0,0 +1,117 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require File.expand_path(File.dirname(__FILE__) + '/fixtures/markup_app/app') + +describe "TagHelpers" do + def app + MarkupDemo + end + + context 'for #tag method' do + should("support tags with no content no attributes") do + assert_has_tag(:br) { tag(:br) } + end + + should("support tags with no content with attributes") do + actual_html = tag(:br, :style => 'clear:both', :class => 'yellow') + assert_has_tag(:br, :class => 'yellow', :style=>'clear:both') { actual_html } + end + + should "support selected attribute by using 'selected' if true" do + actual_html = tag(:option, :selected => true) + assert_has_tag('option', :selected => 'selected') { actual_html } + end + + should "support data attributes" do + actual_html = tag(:a, :data => { :remote => true, :method => 'post'}) + assert_has_tag(:a, 'data-remote' => 'true', 'data-method' => 'post') { actual_html } + end + + should "support nested attributes" do + actual_html = tag(:div, :data => {:dojo => {:type => 'dijit.form.TextBox', :props => 'readOnly: true'}}) + assert_has_tag(:div, 'data-dojo-type' => 'dijit.form.TextBox', 'data-dojo-props' => 'readOnly: true') { actual_html } + end + + should "support open tags" do + actual_html = tag(:p, { :class => 'demo' }, true) + assert_equal "

", actual_html + end + + should "escape html" do + actual_html = tag(:br, :class => 'Example & "bar"') + assert_equal "
", actual_html + end + end + + context 'for #content_tag method' do + should "support tags with content as parameter" do + actual_html = content_tag(:p, "Demo", :class => 'large', :id => 'thing') + assert_has_tag('p.large#thing', :content => "Demo") { actual_html } + end + + should "support tags with content as block" do + actual_html = content_tag(:p, :class => 'large', :id => 'star') { "Demo" } + assert_has_tag('p.large#star', :content => "Demo") { actual_html } + end + + should "escape non-html-safe content" do + actual_html = content_tag(:p, :class => 'large', :id => 'star') { "<>" } + assert_has_tag('p.large#star') { actual_html } + assert_match('<>', actual_html) + end + + should "not escape html-safe content" do + actual_html = content_tag(:p, :class => 'large', :id => 'star') { "<>" } + assert_has_tag('p.large#star', :content => "<>") { actual_html } + end + + should "support tags with erb" do + visit '/erb/content_tag' + assert_have_selector :p, :content => "Test 1", :class => 'test', :id => 'test1' + assert_have_selector :p, :content => "Test 2" + assert_have_selector :p, :content => "Test 3" + assert_have_selector :p, :content => "Test 4" + end + + should "support tags with haml" do + visit '/haml/content_tag' + assert_have_selector :p, :content => "Test 1", :class => 'test', :id => 'test1' + assert_have_selector :p, :content => "Test 2" + assert_have_selector :p, :content => "Test 3", :class => 'test', :id => 'test3' + assert_have_selector :p, :content => "Test 4" + end + + should "support tags with slim" do + visit '/slim/content_tag' + assert_have_selector :p, :content => "Test 1", :class => 'test', :id => 'test1' + assert_have_selector :p, :content => "Test 2" + assert_have_selector :p, :content => "Test 3", :class => 'test', :id => 'test3' + assert_have_selector :p, :content => "Test 4" + end + end + + context 'for #input_tag method' do + should "support field with type" do + assert_has_tag('input[type=text]') { input_tag(:text) } + end + + should "support field with type and options" do + actual_html = input_tag(:text, :class => "first", :id => 'texter') + assert_has_tag('input.first#texter[type=text]') { actual_html } + end + + should "support checked attribute by using 'checked' if true" do + actual_html = input_tag(:checkbox, :checked => true) + assert_has_tag('input[type=checkbox]', :checked => 'checked') { actual_html } + end + + should "remove checked attribute if false" do + actual_html = input_tag(:checkbox, :checked => false) + assert_has_no_tag('input[type=checkbox][checked=false]') { actual_html } + end + + should "support disabled attribute by using 'disabled' if true" do + actual_html = input_tag(:checkbox, :disabled => true) + assert_has_tag('input[type=checkbox]', :disabled => 'disabled') { actual_html } + end + end +end