diff --git a/lib/middleman/core_extensions/assets.rb b/lib/middleman/core_extensions/assets.rb index be286e3f..b0d52d6f 100644 --- a/lib/middleman/core_extensions/assets.rb +++ b/lib/middleman/core_extensions/assets.rb @@ -2,56 +2,16 @@ module Middleman::CoreExtensions::Assets class << self def registered(app) # Disable Padrino cache buster until explicitly enabled - app.set :asset_stamp, false + # app.set :asset_stamp, false - app.extend ClassMethods - - app.helpers Helpers - - app.register_asset_handler :base do |path, prefix, request| - path.include?("://") ? path : File.join(app.http_prefix || "/", prefix, path) - end + app.send :include, InstanceMethod end alias :included :registered end - module ClassMethods - def register_asset_handler(handler_name, &block) - @asset_handler_map ||= [] - @asset_handler_stack ||= [] - - if block_given? - @asset_handler_stack << block - @asset_handler_map << handler_name - end - end - - def asset_handler_get_url(path, prefix="", request=nil) - @asset_handler_map ||= [] - @asset_handler_stack ||= [] - - @asset_handler_stack.last.call(path, prefix, request) - end - - def before_asset_handler(position, *args) - @asset_handler_map ||= [] - @asset_handler_stack ||= [] - - current_index = @asset_handler_map.index(position) - return nil unless current_index - - previous = current_index - 1 - if (previous >= 0) && (previous < @asset_handler_map.length) - @asset_handler_stack[previous].call(*args) - else - nil - end - end - end - - module Helpers + module InstanceMethod def asset_url(path, prefix="") - self.class.asset_handler_get_url(path, prefix, request) + path.include?("://") ? path : File.join(self.http_prefix || "/", prefix, path) end end end \ No newline at end of file diff --git a/lib/middleman/core_extensions/default_helpers.rb b/lib/middleman/core_extensions/default_helpers.rb index cdc2a032..01baabb4 100644 --- a/lib/middleman/core_extensions/default_helpers.rb +++ b/lib/middleman/core_extensions/default_helpers.rb @@ -1,7 +1,26 @@ +require "middleman/vendor/padrino-core-0.10.5/lib/padrino-core/support_lite" +require 'i18n' +require 'enumerator' +require 'active_support/core_ext/string/conversions' # to_date +require 'active_support/core_ext/float/rounding' # round +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('../vendor/padrino-helpers-0.10.5/lib/padrino-helpers/**/*.rb', __FILE__) + module Middleman::CoreExtensions::DefaultHelpers class << self def registered(app) - # Middleman Helpers + 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 Helpers end alias :included :registered diff --git a/lib/middleman/features/asset_host.rb b/lib/middleman/features/asset_host.rb index 3c1b58e5..6bba40a0 100644 --- a/lib/middleman/features/asset_host.rb +++ b/lib/middleman/features/asset_host.rb @@ -7,12 +7,12 @@ module Middleman::Features::AssetHost end end - app.register_asset_handler :asset_host do |path, prefix, request| - original_output = app.before_asset_handler(:asset_host, path, prefix, request) + app.register_asset_handler :asset_host do |path, prefix| + original_output = self.before_asset_handler(:asset_host, path, prefix) valid_extensions = %w(.png .gif .jpg .jpeg .js .css) - asset_prefix = app.asset_host.call(original_output) + asset_prefix = self.asset_host.call(original_output) File.join(asset_prefix, original_output) end diff --git a/lib/middleman/features/automatic_image_sizes.rb b/lib/middleman/features/automatic_image_sizes.rb index 30885a3f..4763d8d7 100755 --- a/lib/middleman/features/automatic_image_sizes.rb +++ b/lib/middleman/features/automatic_image_sizes.rb @@ -3,25 +3,28 @@ module Middleman::Features::AutomaticImageSizes def registered(app) require "middleman/features/automatic_image_sizes/fastimage" - app.helpers Helpers + app.send :include, InstanceMethods end alias :included :registered end - module Helpers + module InstanceMethods def image_tag(path, params={}) - if (!params[:width] || !params[:height]) && !path.include?("://") + if !params.has_key?(:width) && !params.has_key?(:height) && !path.include?("://") params[:alt] ||= "" - http_prefix = settings.http_images_path rescue settings.images_dir + http_prefix = self.http_images_path rescue self.images_dir begin - real_path = File.join(settings.views, settings.images_dir, path) - if File.exists? real_path - dimensions = ::FastImage.size(real_path, :raise_on_failure => true) - params[:width] ||= dimensions[0] - params[:height] ||= dimensions[1] + real_path = File.join(self.views, self.images_dir, path) + full_path = File.expand_path(real_path, self.root) + http_prefix = self.http_images_path rescue self.images_dir + if File.exists? full_path + dimensions = ::FastImage.size(full_path, :raise_on_failure => true) + params[:width] = dimensions[0] + params[:height] = dimensions[1] end rescue + # $stderr.puts params.inspect end end diff --git a/lib/middleman/features/cache_buster.rb b/lib/middleman/features/cache_buster.rb index f9cffd3f..1409badf 100755 --- a/lib/middleman/features/cache_buster.rb +++ b/lib/middleman/features/cache_buster.rb @@ -1,8 +1,8 @@ module Middleman::Features::CacheBuster class << self def registered(app) - app.register_asset_handler :cache_buster do |path, prefix, request| - http_path = app.before_asset_handler(:cache_buster, path, prefix, request) + app.register_asset_handler :cache_buster do |path, prefix| + http_path = app.before_asset_handler(:cache_buster, path, prefix) if http_path.include?("://") || !%w(.css .png .jpg .js .gif).include?(File.extname(http_path)) http_path diff --git a/lib/middleman/features/relative_assets.rb b/lib/middleman/features/relative_assets.rb index b2037082..8558c48e 100755 --- a/lib/middleman/features/relative_assets.rb +++ b/lib/middleman/features/relative_assets.rb @@ -5,20 +5,20 @@ module Middleman::Features::RelativeAssets config.relative_assets = true end - app.register_asset_handler :relative_assets do |path, prefix, request| + app.register_asset_handler :relative_assets do |path, prefix| begin - prefix = app.images_dir if prefix == app.http_images_path + prefix = self.images_dir if prefix == self.http_images_path rescue end if path.include?("://") - app.before_asset_handler(:relative_assets, path, prefix, request) + self.before_asset_handler(:relative_assets, path, prefix) elsif path[0,1] == "/" path else path = File.join(prefix, path) if prefix.length > 0 - request_path = request.path_info.dup - request_path << app.index_file if path.match(%r{/$}) + request_path = @request_path.dup + request_path << self.index_file if path.match(%r{/$}) request_path.gsub!(%r{^/}, '') parts = request_path.split('/') diff --git a/lib/middleman/vendor/padrino-core-0.10.5/.document b/lib/middleman/vendor/padrino-core-0.10.5/.document new file mode 100644 index 00000000..136eea59 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/.document @@ -0,0 +1,5 @@ +lib/**/*.rb +bin/* +- +README.rdoc +LICENSE.txt diff --git a/lib/middleman/vendor/padrino-core-0.10.5/.gitignore b/lib/middleman/vendor/padrino-core-0.10.5/.gitignore new file mode 100644 index 00000000..2a3a6401 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/.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/lib/middleman/vendor/padrino-core-0.10.5/.yardopts b/lib/middleman/vendor/padrino-core-0.10.5/.yardopts new file mode 100644 index 00000000..30447b7f --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/.yardopts @@ -0,0 +1 @@ +--title 'Padrino Core Documentation' --protected diff --git a/lib/middleman/vendor/padrino-core-0.10.5/LICENSE.txt b/lib/middleman/vendor/padrino-core-0.10.5/LICENSE.txt new file mode 100644 index 00000000..8f1ef777 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/README.rdoc b/lib/middleman/vendor/padrino-core-0.10.5/README.rdoc new file mode 100644 index 00000000..53f88444 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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, respond_to support, 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 respond_to 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], respond_to => [: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 Padrino. See LICENSE for details. diff --git a/lib/middleman/vendor/padrino-core-0.10.5/Rakefile b/lib/middleman/vendor/padrino-core-0.10.5/Rakefile new file mode 100644 index 00000000..f33347d2 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/bin/padrino b/lib/middleman/vendor/padrino-core-0.10.5/bin/padrino new file mode 100755 index 00000000..ccc4c62e --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core.rb new file mode 100644 index 00000000..98719cad --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core.rb @@ -0,0 +1,167 @@ +require 'sinatra/base' +require 'padrino-core/support_lite' unless defined?(SupportLite) + +FileSet.glob_require('padrino-core/application/*.rb', __FILE__) +FileSet.glob_require('padrino-core/*.rb', __FILE__) + +# The Padrino environment (falls back to the rack env or finally develop) +PADRINO_ENV = ENV["PADRINO_ENV"] ||= ENV["RACK_ENV"] ||= "development" unless defined?(PADRINO_ENV) +# The Padrino project root path (falls back to the first caller) +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) + @_global_configuration = block if block_given? + 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 + + ## + # Determines whether the dependencies are locked by Bundler. + # otherwise return nil + # + # @return [:locked, :unlocked, nil] + # Returns +:locked+ if the +Gemfile.lock+ file exists, or +:unlocked+ + # if only the +Gemfile+ exists. + # + # @deprecated Will be removed in 1.0.0 + # + def bundle + return :locked if File.exist?(root('Gemfile.lock')) + return :unlocked if File.exist?(root("Gemfile")) + 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 + end # self +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application.rb new file mode 100644 index 00000000..0bcdc1e9 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application.rb @@ -0,0 +1,270 @@ +module Padrino + class ApplicationSetupError < RuntimeError # @private + 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) # @private + logger.devel "Setup #{base}" + 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) + 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 #{self}" + @_dependencies = nil # Reset dependencies + reset! # Reset sinatra app + reset_router! # Reset all routes + Padrino.require_dependencies(self.app_file, :force => true) # Reload the app file + require_dependencies # Reload dependencies + default_filters! # Reload filters + default_routes! # Reload default routes + default_errors! # Reload our errors + I18n.reload! if defined?(I18n) # Reload also our translations + 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 + self.require_dependencies + self.default_filters! + self.default_routes! + self.default_errors! + if defined?(I18n) + I18n.load_path << self.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(self.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(self.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 + @_dependencies ||= [ + "urls.rb", "config/urls.rb", "mailers/*.rb", "mailers.rb", + "controllers/**/*.rb", "controllers.rb", "helpers/**/*.rb", "helpers.rb" + ].map { |file| Dir[File.join(self.root, file)] }.flatten + end + + ## + # An array of file to load before your app.rb, basically are files wich 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 perequisite + # 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, "images") } + set :protection, false + # Padrino specific + set :uri_root, "/" + set :app_name, self.to_s.underscore.to_sym + set :default_builder, 'StandardFormBuilder' + set :flash, defined?(Sinatra::Flash) || defined?(Rack::Flash) + set :authentication, false + # Padrino locale + set :locale_path, Proc.new { Dir[File.join(self.root, "/locale/**/*.{rb,yml}")] } + # 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 + @_content_type = :html + 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 + setup_flash 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 + setup_protection builder + setup_application! + end + + # TODO Remove this in a few versions (rack-flash deprecation) + # Move register Sinatra::Flash into setup_default_middleware + # Initializes flash using sinatra-flash or rack-flash + def setup_flash(builder) + register Sinatra::Flash if flash? && defined?(Sinatra::Flash) + if defined?(Rack::Flash) && !defined?(Sinatra::Flash) + logger.warn %Q{ + [Deprecation] In Gemfile, 'rack-flash' should be replaced with 'sinatra-flash'! + Rack-Flash is not compatible with later versions of Rack and should be replaced. + } + builder.use Rack::Flash, :sweep => true if flash? + end + end + end # self + end # Application +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application/rendering.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application/rendering.rb new file mode 100644 index 00000000..382e63df --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application/rendering.rb @@ -0,0 +1,292 @@ +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 + ## + # 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 rendering options used in the #render-method. + # + DEFAULT_RENDERING_OPTIONS = { :strict_format => false, :raise_exceptions => true } unless defined?(DEFAULT_RENDERING_OPTIONS) + + 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 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' + # * Use render { :a => 1, :b => 2, :c => 3 } # => return a json string + # + def render(engine, data=nil, options={}, locals={}, &block) + # If engine is a hash then render data converted to json + content_type(:json, :charset => 'utf-8') and return engine.to_json if engine.is_a?(Hash) + + # 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? + + # Setup root + root = settings.respond_to?(:root) ? settings.root : "" + + # Use @layout if it exists + options[:layout] = @layout if options[:layout].nil? + + # Resolve layouts similar to in Rails + if (options[:layout].nil? || options[:layout] == true) && !settings.templates.has_key?(:layout) + layout_path, layout_engine = *resolved_layout + options[:layout] = layout_path || false # We need to force layout false so sinatra don't try to render it + 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 + + # Cleanup the template + @current_engine, engine_was = engine, @current_engine + @_out_buf, _buf_was = "", @_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 + # 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 # InstanceMethods + end # Rendering +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application/routing.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application/routing.rb new file mode 100644 index 00000000..88f43f76 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application/routing.rb @@ -0,0 +1,934 @@ +require 'http_router' unless defined?(HttpRouter) +require 'padrino-core/support_lite' unless defined?(SupportLite) + +## +# Adds to Sinatra +controller+ informations +# +# @private +class Sinatra::Request + attr_accessor :route_obj + + def controller + route_obj && route_obj.controller + end +end + +## +# HttpRouter adapter +# +# @private +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 path.route.is_a?(HttpRouter::RegexRoute) + params_list = env['router.request'].extra_env['router.regex_match'].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 } if @route.custom_conditions + @block_params = @block_params[0, @route.dest.arity] if @route.dest.arity > 0 + 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 + + # @private + class Route + attr_accessor :use_layout, :controller, :cache, :cache_key, :cache_expires_in + + 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 + end +end + +module Padrino + class Filter # @private + 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.named == arg or request.route_obj.named == [@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 # @private + 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 for organize in a better way our routes. + # + # @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 didn't affect other controllers or main app. + # In a controller layout are scoped and didn't affect others controllers and 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 oly path that are +/+ or contains +main+ + # + # @example filtering everything except an occurency + # 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 + + # Compiles the routes including deferred routes. + def compiled_router + if deferred_routes.empty? + router + else + deferred_routes.each { |_, routes| routes.each { |(route, dest)| route.to(dest) } } + @deferred_routes = nil + router + end + end + + # Returns all routes that were deferred based on their priority. + def deferred_routes + @deferred_routes ||= Hash[ROUTE_PRIORITY.values.sort.map{|p| [p, []]}] + end + + ## + # Resets the http router and all deferred routes. + # + 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[0].path.route.named, 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.url(name, params) + else + compiled_router.url(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) # @private + 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 + # + 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 + path, *route_options[:with] = path if path.is_a?(Array) + path, name, 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.name(name) if name + 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.send(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.default(defaults) if defaults + end + options.delete_if do |option, args| + if route.send(:significant_variable_names).include?(option) + route.matching(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) + # We need save our originals path/options so we can perform correctly cache. + original = [path, options.dup] + + # We need check if path is a symbol, if that it's a named route + map = options.delete(:map) + + if path.kind_of?(Symbol) # path i.e :index or :show + name = path # The route name + path = map ? map.dup : (path == :index ? '/' : path.to_s) # The route path + end + + if path.kind_of?(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[:matching] ||= {} + options[:matching][:format] = /[^\.]+/ + end + + # Build our controller + controller = Array(@_controller).map { |c| c.to_s } + + 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) + end + # Here we build the correct name route + if name + controller_name = controller.join("_") + name = "#{controller_name}_#{name}".to_sym unless controller_name.blank? + 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) + 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!('/') + end + + # Merge in option defaults + options.reverse_merge!(:default_values => @_defaults) + + [path, name, 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) } + url_format = params[:format].to_sym if params[:format] + accepts = request.accept.map { |a| a.split(";")[0].strip } + + # 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 !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 + 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 + 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 the recognized path for a route. + # + 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.url(*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! + static! if settings.static? && (request.get? || request.head?) + route! + rescue ::Exception => boom + filter! :before + handle_exception!(boom) + ensure + filter! :after unless env['sinatra.static_file'] + 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 + 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 # InstanceMethods + end # Routing +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application/showexceptions.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application/showexceptions.rb new file mode 100644 index 00000000..7430aa5e --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application/showexceptions.rb @@ -0,0 +1,20 @@ +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 # ShowExceptions +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/caller.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/caller.rb new file mode 100644 index 00000000..a8c52e6a --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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-.*$}, # all padrino code + %r{/padrino-.*/(lib|bin)}, # all padrino code + %r{/bin/padrino$}, # all padrino code + %r{/sinatra(/(base|main|showexceptions))?\.rb$}, # all sinatra code + %r{lib/tilt.*\.rb$}, # all tilt code + %r{lib/rack.*\.rb$}, # all rack code + %r{lib/mongrel.*\.rb$}, # all mongrel code + %r{lib/shotgun.*\.rb$}, # all shotgun lib + %r{bin/shotgun$}, # shotgun binary + %r{\(.*\)}, # generated code + %r{shoulda/context\.rb$}, # shoulda hacks + %r{mocha/integration}, # mocha hacks + %r{test/unit}, # test unit hacks + %r{rake_test_loader\.rb}, # rake hacks + %r{custom_require\.rb$}, # rubygems require hacks + %r{active_support}, # active_support require hacks + %r{/thor} # thor require hacks + ] 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 # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/adapter.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/adapter.rb new file mode 100644 index 00000000..6b47d4a7 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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 # self + end # Adapter + end # Cli +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/base.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/base.rb new file mode 100644 index 00000000..a183b820 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/base.rb @@ -0,0 +1,151 @@ +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" + method_option :server, :type => :string, :aliases => "-a", :desc => "Rack Handler (default: autodetect)" + method_option :host, :type => :string, :aliases => "-h", :required => true, :default => "0.0.0.0", :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 "s", "Starts the Padrino application" + def s + invoke :start + end + + desc "stop", "Stops the Padrino application" + 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." + method_option :verbose, :type => :boolean, :aliases => "-v", :desc => "Log message to standard output." + 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(' ')} ..." + ENV['PADRINO_LOG_LEVEL'] ||= "test" + load File.expand_path('../rake.rb', __FILE__) + silence(:stdout) { require File.expand_path('config/boot.rb') } + PadrinoTasks.init(true) + end + + desc "console", "Boots up the Padrino application irb console" + def console + prepare :console + require File.expand_path("../../version", __FILE__) + ARGV.clear + puts "=> Loading #{options.environment} console (Padrino v.#{Padrino.version})" + require 'irb' + require "irb/completion" + require File.expand_path('config/boot.rb') + require File.expand_path('../console', __FILE__) + IRB.start + end + + desc "generate", "Executes the Padrino generator with given options." + def generate(*args) + # Build Padrino g as an alias of padrino-gen + 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 + Padrino.bin_gen(ARGV) + rescue + puts "<= You need padrino-gen! Run: gem install padrino-gen" + end + end + + desc "g", "Executes the Padrino generator with given options." + def g(*args) + invoke(:generate, args) + end + + desc "gen", "Executes the Padrino generator with given options." + def gen(*args) + invoke(:generate, args) + end + + desc "version", "Show current Padrino Version" + map "-v" => :version, "--version" => :version + def version + require 'padrino-core/version' + puts "Padrino v. #{Padrino.version}" + 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 # Base + end # Cli +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/console.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/console.rb new file mode 100644 index 00000000..c1acde4e --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/rake.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/rake.rb new file mode 100644 index 00000000..baaccd1f --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/rake.rb @@ -0,0 +1,24 @@ +require File.expand_path('../../tasks', __FILE__) +require 'rake' +require 'thor' +require 'securerandom' unless defined?(SecureRandom) + +module PadrinoTasks + def self.init(init=false) + Padrino::Tasks.files.flatten.uniq.each { |rakefile| Rake.application.add_import(rakefile) rescue puts "<= Failed load #{ext}" } + if init + Rake.application.init + Rake.application.instance_variable_set(:@rakefile, __FILE__) + load(File.expand_path('../rake_tasks.rb', __FILE__)) + Rake.application.load_imports + Rake.application.top_level + else + load(File.expand_path('../rake_tasks.rb', __FILE__)) + Rake.application.load_imports + end + end +end + +def shell + @_shell ||= Thor::Base.shell.new +end diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/rake_tasks.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/rake_tasks.rb new file mode 100644 index 00000000..076affa3 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/rake_tasks.rb @@ -0,0 +1,59 @@ +# Load rake tasks from common rake task definition locations +Dir["lib/tasks/**/*.rake"]. + concat(Dir["tasks/**/*.rake"]). + concat(Dir["{test,spec}/*.rake"]).each { |rake| load(rake) } + +# Loads the Padrino applications mounted within the project +# setting up the required environment for Padrino +task :environment do + 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 + +# lists all routes of a given app +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 + +desc "Generate the Rakefile" +task :gen do + File.open(Padrino.root("Rakefile"), "w") do |file| + file.puts <<-RUBY.gsub(/^ {6}/, '') + require File.expand_path('../config/boot.rb', __FILE__) + require 'padrino-core/cli/rake' + PadrinoTasks.init + RUBY + end +end diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/command.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/command.rb new file mode 100644 index 00000000..84d3c04d --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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 # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/images/404.png b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/images/404.png new file mode 100644 index 00000000..2dc2538a Binary files /dev/null and b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/images/404.png differ diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/images/500.png b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/images/500.png new file mode 100644 index 00000000..87187a11 Binary files /dev/null and b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/images/500.png differ diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/loader.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/loader.rb new file mode 100644 index 00000000..d07402bb --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/loader.rb @@ -0,0 +1,210 @@ +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? + @_called_from = first_caller + Padrino.set_encoding + Padrino.set_load_paths(*load_paths) # We set the padrino 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 + 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! + 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 ablity 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? + # List of errors and failed files + errors, failed = [], [] + + # We need a size to make sure things are loading + 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 LoadError => e + errors << e + failed << file + rescue NameError => 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_was = [ + "#{root}/config/database.rb", "#{root}/lib/**/*.rb", "#{root}/shared/lib/**/*.rb", + "#{root}/models/**/*.rb", "#{root}/shared/models/**/*.rb", "#{root}/config/apps.rb" + ] + @_dependency_paths ||= @_dependency_paths_was + 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 + end # self +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/cs.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/cs.yml new file mode 100644 index 00000000..e7b1e5a7 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/cs.yml @@ -0,0 +1,34 @@ +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" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " a " + last_word_connector: " a " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/da.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/da.yml new file mode 100644 index 00000000..5cc5c2d2 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/da.yml @@ -0,0 +1,34 @@ +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: "" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " og " + last_word_connector: " og " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/de.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/de.yml new file mode 100644 index 00000000..d2675193 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/de.yml @@ -0,0 +1,34 @@ +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: "%b %d" + long: "%B %d, %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: "%B %d, %Y %H:%M" + am: "am" + pm: "pm" + +# Benutzt in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " und " + last_word_connector: ", und " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/en.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/en.yml new file mode 100644 index 00000000..87e678f8 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/en.yml @@ -0,0 +1,34 @@ +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" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " and " + last_word_connector: ", and " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/es.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/es.yml new file mode 100644 index 00000000..05274926 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/es.yml @@ -0,0 +1,34 @@ +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" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " y " + last_word_connector: ", y " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/fr.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/fr.yml new file mode 100644 index 00000000..dba1adb4 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/fr.yml @@ -0,0 +1,34 @@ +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: [Lun, Mar, Mer, Jeu, Ven, Sam, Dim] + 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, Jui, Jui, 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" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " et " + last_word_connector: ", et " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/hu.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/hu.yml new file mode 100644 index 00000000..8252c9bc --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/hu.yml @@ -0,0 +1,34 @@ +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" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " és " + last_word_connector: " és " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/it.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/it.yml new file mode 100644 index 00000000..e025194e --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/it.yml @@ -0,0 +1,40 @@ +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' + +# Used in array.to_sentence. + support: + array: + sentence_connector: "e" + skip_last_comma: false diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/ja.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/ja.yml new file mode 100644 index 00000000..a6bcf215 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/ja.yml @@ -0,0 +1,34 @@ +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: "午後" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " と " + last_word_connector: ", と " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/lv.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/lv.yml new file mode 100644 index 00000000..e3cfd433 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/lv.yml @@ -0,0 +1,34 @@ +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" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " un " + last_word_connector: ", un " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/nl.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/nl.yml new file mode 100644 index 00000000..3ea79fa8 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/nl.yml @@ -0,0 +1,34 @@ +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" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " en " + last_word_connector: " en " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/no.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/no.yml new file mode 100644 index 00000000..b40727f0 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/no.yml @@ -0,0 +1,35 @@ +"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: "" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " og " + last_word_connector: " og " + diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/pl.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/pl.yml new file mode 100644 index 00000000..730c16c8 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/pl.yml @@ -0,0 +1,34 @@ +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" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " i " + last_word_connector: " i " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/pt_br.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/pt_br.yml new file mode 100644 index 00000000..cad95945 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/pt_br.yml @@ -0,0 +1,40 @@ +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' + +# Used in array.to_sentence. + support: + array: + sentence_connector: "e" + skip_last_comma: false diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/ru.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/ru.yml new file mode 100644 index 00000000..e2bb550d --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/ru.yml @@ -0,0 +1,35 @@ +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: "п.п." + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " и " + last_word_connector: " и " + diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/tr.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/tr.yml new file mode 100644 index 00000000..bbe6bc38 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/tr.yml @@ -0,0 +1,34 @@ +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" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " ve " + last_word_connector: " ve " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/uk.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/uk.yml new file mode 100644 index 00000000..2e35bde0 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/uk.yml @@ -0,0 +1,34 @@ +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: "п.п" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " і " + last_word_connector: ", і " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/zh_cn.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/zh_cn.yml new file mode 100644 index 00000000..285e9d48 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/zh_cn.yml @@ -0,0 +1,34 @@ +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: [~, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月] + 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: "下午" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " 和 " + last_word_connector: ", 和 " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/zh_tw.yml b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/zh_tw.yml new file mode 100644 index 00000000..12bc0faa --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/zh_tw.yml @@ -0,0 +1,34 @@ +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: "下午" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " 和 " + last_word_connector: ", 和 " diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/logger.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/logger.rb new file mode 100644 index 00000000..fa5b6900 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/logger.rb @@ -0,0 +1,345 @@ +# 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.setup! if Thread.current[:padrino_logger].nil? + Thread.current[:padrino_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) + Thread.current[:padrino_logger] = value + end + + ## + # Extensions to the built in Ruby logger. + # + class Logger + + attr_accessor :level + attr_accessor :auto_flush + attr_reader :buffer + attr_reader :log + attr_reader :init_args + attr_accessor :log_static + + ## + # Ruby (standard) logger levels: + # + # :fatal:: An unhandleable 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 + # + Levels = { + :fatal => 7, + :error => 6, + :warn => 4, + :info => 3, + :debug => 0, + :devel => -1, + } unless const_defined?(:Levels) + + @@mutex = {} + + ## + # 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 + # + # @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 + + # Colors for levels + ColoredLevels = { + :fatal => [:bold, :red], + :error => [:red], + :warn => [:yellow], + :info => [:green], + :debug => [:cyan], + :devel => [:magenta] + } unless defined?(ColoredLevels) + + ## + # Setup a new logger + # + # @return [Padrino::Logger] + # A {Padrino::Logger} instance + # + def self.setup! + 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 + Thread.current[:padrino_logger] = Padrino::Logger.new(config.merge(:stream => stream)) + 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. + # + def initialize(options={}) + @buffer = [] + @auto_flush = options.has_key?(:auto_flush) ? options[:auto_flush] : true + @level = options[:log_level] ? Levels[options[:log_level]] : Levels[:debug] + @log = options[:stream] || $stdout + @log.sync = true + @mutex = @@mutex[@log] ||= Mutex.new + @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 + end + + ## + # Colorize our level + # + # @param [String, Symbol] level + # + # @see Padrino::Logger::ColoredLevels + # + def colored_level(level) + style = ColoredLevels[level].map { |c| "\e[%dm" % String.colors[c] } * '' + [style, level.to_s.upcase.rjust(7), "\e[0m"] * '' + end + + ## + # Flush the entire buffer to the log object. + # + def flush + return unless @buffer.size > 0 + @mutex.synchronize do + @log.write(@buffer.slice!(0..-1).join('')) + 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 + + ## + # 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) + write @format_message % [colored_level(level), Time.now.strftime(@format_datetime).yellow, message.to_s.strip] + 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.056ms) - /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 + push "%s (" % action.to_s.upcase.rjust(@_pad).send(color) + "%0.4fms".bold.send(color) % duration + ") %s" % message.to_s, level + end + + ## + # Directly append message to the log. + # + # @param [String] message + # The message + # + def <<(message = nil) + message << "\n" unless message[-1] == ?\n + @buffer << message + flush if @auto_flush + message + end + alias :write :<< + + ## + # Generate the logging methods for {Padrino.logger} for each log level. + # + Levels.each_pair do |name, number| + define_method(name) do |*args| + return if number < level + if args.size > 1 + bench(*args) + else + push(args * '', name) + end + end + + define_method(:"#{name}?") do + number >= level + end + end + + ## + # Padrino::Loggger::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) # @private + @app = app + @uri_root = uri_root.sub(/\/$/,"") + end + + def call(env) # @private + env['rack.logger'] = Padrino.logger + env['rack.errors'] = Padrino.logger.log + began_at = Time.now + status, header, body = @app.call(env) + log(env, status, header, began_at) + [status, header, body] + end + + private + def log(env, status, header, began_at) + return if env['sinatra.static_file'] and !logger.log_static + logger.bench( + env["REQUEST_METHOD"], + began_at, + [ + @uri_root.to_s, + env["PATH_INFO"], + env["QUERY_STRING"].empty? ? "" : "?" + env["QUERY_STRING"], + ' - ', + 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 # Rack + end # Logger +end # Padrino + +module Kernel # @private + ## + # Define a logger available every where in our app + # + def logger + Padrino.logger + end +end # Kernel diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/mounter.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/mounter.rb new file mode 100644 index 00000000..d7a4afe1 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/mounter.rb @@ -0,0 +1,224 @@ +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 # @private + 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) + # + def initialize(name, options={}) + @name = name.to_s + @app_class = options[:app_class] || @name.camelize + @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.named.to_s.split("_").map { |piece| %Q[:#{piece}] }.join(", ")})" + request_method = route.conditions[:request_method][0] + full_path = File.join(uri_root, route.original_path) + next if route.named.blank? || request_method == 'HEAD' + OpenStruct.new(:verb => request_method, :identifier => route.named, :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") + 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 # Mounter +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/reloader.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/reloader.rb new file mode 100644 index 00000000..af1052af --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/reloader.rb @@ -0,0 +1,254 @@ +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 ||= [] + end + + ## + # Specified constants can be configured to be reloaded on every request. + # Default included constants are: [none] + # + def include_constants + @_include_constants ||= [] + 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! + MTIMES.clear + LOADED_CLASSES.each do |file, klasses| + klasses.each { |klass| remove_constant(klass) } + LOADED_CLASSES.delete(file) + end + LOADED_FILES.each do |file, dependencies| + dependencies.each { |dependency| $LOADED_FEATURES.delete(dependency) } + $LOADED_FEATURES.delete(file) + end + 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] ||= mtime + 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.map { |klass| klass.name.to_s.split("::")[0] }.uniq + klasses = klasses | Padrino.mounted_apps.map { |app| app.app_class } + Padrino::Reloader.exclude_constants.concat(klasses) + end + + ## + # A safe Kernel::require which issues the necessary hooks depending on results + # + def safe_load(file, options={}) + began_at = Time.now + force, file = options[:force], figure_path(file) + + # Check if file was changed or if force a reload + reload = MTIMES[file] && File.mtime(file) > MTIMES[file] + return if !force && !reload && MTIMES[file] + + # Removes all classes declared in the specified file + if klasses = LOADED_CLASSES.delete(file) + klasses.each { |klass| remove_constant(klass) } + end + + # Remove all loaded fatures with our file + if features = LOADED_FILES[file] + features.each { |feature| $LOADED_FEATURES.delete(feature) } + end + + # Duplicate objects and loaded features before load file + klasses = ObjectSpace.classes.dup + files = $LOADED_FEATURES.dup + + # Now we can reload dependencies of our file + if features = LOADED_FILES.delete(file) + features.each { |feature| safe_load(feature, :force => true) } + end + + # 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) + verbosity_was, $-v = $-v, nil + loaded = false + require(file) + loaded = true + MTIMES[file] = File.mtime(file) + rescue SyntaxError => e + logger.error "Cannot require #{file} due to a syntax error: #{e.message}" + ensure + $-v = verbosity_was + new_constants = (ObjectSpace.classes - klasses).uniq + if loaded + # Store the file details + LOADED_CLASSES[file] = new_constants + LOADED_FILES[file] = ($LOADED_FEATURES - files - [file]).uniq + # Track only features in our Padrino.root + LOADED_FILES[file].delete_if { |feature| !in_root?(feature) } + else + logger.devel "Failed to load #{file}; removing partially defined constants" + new_constants.each { |klass| remove_constant(klass) } + 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.compact.uniq.any? { |c| (const.to_s =~ %r{^#{Regexp.escape(c)}}) } && + !include_constants.compact.uniq.any? { |c| (const.to_s =~ %r{^#{Regexp.escape(c)}}) } + begin + parts = const.to_s.split("::") + base = parts.size == 1 ? Object : parts[0..-2].join("::").constantize + object = parts[-1].to_s + base.send(:remove_const, object) + logger.devel "Removed constant: #{const}" + rescue NameError; end + end + + private + ## + # Return the mounted_apps providing the app location + # Can be an array because in one app.rb we can define multiple Padrino::Appplications + # + 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) =~ %r{^#{Regexp.escape(Padrino.root)}} + end + + ## + # Searches Ruby files in your +Padrino.load_paths+ , Padrino::Application.load_paths + # and monitors them for any changes. + # + def 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 + files.uniq.map { |file| + file = File.expand_path(file) + next if Padrino::Reloader.exclude.any? { |base| file =~ %r{^#{Regexp.escape(base)}} } || !File.exist?(file) + yield(file, File.mtime(file)) + }.compact + 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 # Reloader +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/router.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/router.rb new file mode 100644 index 00000000..d943d55e --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/router.rb @@ -0,0 +1,98 @@ +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 doman 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 + + # Constructs a new route mapper instance + 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. + # @api private + def call(env) + rPath = env["PATH_INFO"].to_s + script_name = env['SCRIPT_NAME'] + hHost, sName, sPort = env.values_at('HTTP_HOST','SERVER_NAME','SERVER_PORT') + @mapping.each do |host, path, match, app| + next unless host.nil? || hHost =~ host + next unless rPath =~ 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: #{rPath}"]] + end + + private + + # Sorts the mapped routes in consistent order + def sort! + @mapping = @mapping.sort_by { |h, p, m, a| -p.size } + end + end # Router +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/server.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/server.rb new file mode 100644 index 00000000..bd7daaec --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/server.rb @@ -0,0 +1,79 @@ +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: "localhost", port: "3000", adapter: the first found + # Padrino.run!("localhost", "4000", "mongrel") # use => host: "0.0.0.0", port: "3000", 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, :mongrel, :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) || '0.0.0.0' + options[:Port] = options.delete(:port) || 3000 + options[:AccessLog] = [] + if options[:daemonize] + options[:pid] = options[:pid].blank? ? File.expand_path('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 has ended his set (crowd applauds)" unless options[:daemonize] + end + + # The application the server will run. + def app + @app + end + alias :wrapped_app :app + + # The options specified to the server. + 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 # Server +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/support_lite.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/support_lite.rb new file mode 100644 index 00000000..d5c64260 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/support_lite.rb @@ -0,0 +1,199 @@ +## +# 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/inflections' # load default inflections +require 'yaml' unless defined?(YAML) # load yaml for i18n +require 'Win32/Console/ANSI' if RUBY_PLATFORM =~ /win32/ # ruby color suppor 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. + def classes + ObjectSpace.each_object(Module).select do |klass| + # Why this? Ruby when you remove a constant don't clean it from + # rb_tables, this mean that here we can found classes that was + # removed. + klass.name rescue false + 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 + +## +# 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 diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/tasks.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/tasks.rb new file mode 100644 index 00000000..204aa709 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/tasks.rb @@ -0,0 +1,21 @@ +module Padrino + ## + # This module it's used for bootstrap with padrino rake + # thirdy 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 # Tasks +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/version.rb b/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/version.rb new file mode 100644 index 00000000..f292ab71 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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.10.5' unless defined?(Padrino::VERSION) + + # + # The current Padrino version. + # + # @return [String] + # The version number. + # + def self.version + VERSION + end +end # Padrino diff --git a/lib/middleman/vendor/padrino-core-0.10.5/padrino-core.gemspec b/lib/middleman/vendor/padrino-core-0.10.5/padrino-core.gemspec new file mode 100755 index 00000000..61d89257 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/padrino-core.gemspec @@ -0,0 +1,38 @@ +#!/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.3.0") + s.add_dependency("sinatra", "~> 1.3.1") + s.add_dependency("http_router", "~> 0.10.2") + s.add_dependency("thor", "~> 0.14.3") + s.add_dependency("activesupport", "~> 3.1.0") +end diff --git a/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/apps/.components b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/apps/.components new file mode 100644 index 00000000..516c4a23 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/apps/.components @@ -0,0 +1,6 @@ +--- +:test: bacon +:mock: mocha +:orm: datamapper +:renderer: erb +:script: jquery diff --git a/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/apps/.gitignore b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/apps/.gitignore new file mode 100644 index 00000000..ba335e37 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/apps/complex.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/apps/complex.rb new file mode 100644 index 00000000..1d0a3975 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/apps/simple.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/apps/simple.rb new file mode 100644 index 00000000..fd9d3bc8 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/a.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/a.rb new file mode 100644 index 00000000..eecc8410 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/b.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/b.rb new file mode 100644 index 00000000..a9fcf5ac --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/c.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/c.rb new file mode 100644 index 00000000..adb57549 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/c.rb @@ -0,0 +1 @@ +C = "C" diff --git a/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/e.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/e.rb new file mode 100644 index 00000000..780b0ff4 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/f.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/f.rb new file mode 100644 index 00000000..96ceea1c --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/f.rb @@ -0,0 +1,2 @@ +class F < E +end diff --git a/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/g.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/g.rb new file mode 100644 index 00000000..a9ecb812 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/g.rb @@ -0,0 +1,2 @@ +class G +end diff --git a/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/d.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/d.rb new file mode 100644 index 00000000..851aae1f --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/d.rb @@ -0,0 +1,4 @@ +D = 0 unless defined?(D) +D += 1 + +raise "SomeThing" diff --git a/lib/middleman/vendor/padrino-core-0.10.5/test/helper.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/helper.rb new file mode 100644 index 00000000..6f55c849 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/helper.rb @@ -0,0 +1,81 @@ +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 + 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/lib/middleman/vendor/padrino-core-0.10.5/test/mini_shoulda.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/mini_shoulda.rb new file mode 100644 index 00000000..1930d384 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/mini_shoulda.rb @@ -0,0 +1,45 @@ +gem 'minitest' +require 'minitest/spec' +require 'minitest/autorun' +require 'mocha' # Load mocha after minitest + +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/lib/middleman/vendor/padrino-core-0.10.5/test/test_application.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/test_application.rb new file mode 100644 index 00000000..be9c6202 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/test_application.rb @@ -0,0 +1,108 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +class PadrinoPristine < Padrino::Application; end +class PadrinoTestApp < Padrino::Application; end +class PadrinoTestApp2 < Padrino::Application; end + +describe "Application" do + def setup + Padrino.clear! + end + + def teardown + remove_views + end + + 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 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? + assert !PadrinoPristine.flash + 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 "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.tap { |app| app.send(:default_configuration!) + app.get("/") { session[:foo] = "shared" } } + PadrinoTestApp2.tap { |app| app.send(:default_configuration!) + app.get("/") { session[:foo] } } + browser = Rack::Test::Session.new(Rack::MockSession.new(Padrino.application)) + browser.get '/write' + browser.get '/read' + assert_equal 'shared', browser.last_response.body + end + + # compare to: test_routing: allow global provides + should "set content_type to :html if none can be determined" do + mock_app do + provides :xml + + get("/foo"){ "Foo in #{content_type}" } + get("/bar"){ "Foo in #{content_type}" } + 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 html", body + end # content_type to :html + + 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/lib/middleman/vendor/padrino-core-0.10.5/test/test_core.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/test_core.rb new file mode 100644 index 00000000..8d832f0d --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/test_core.rb @@ -0,0 +1,79 @@ +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, :bundle + assert_respond_to Padrino, :configure_apps + end + + + should 'validate global helpers' do + assert_equal :test, Padrino.env + assert_match /\/test/, Padrino.root + assert_equal nil, Padrino.bundle + 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/lib/middleman/vendor/padrino-core-0.10.5/test/test_dependencies.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/test_dependencies.rb new file mode 100644 index 00000000..4e2cfdd0 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/test/test_filters.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/test_filters.rb new file mode 100644 index 00000000..b1ebe47b --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/test_filters.rb @@ -0,0 +1,278 @@ +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 +end diff --git a/lib/middleman/vendor/padrino-core-0.10.5/test/test_locale.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/test_locale.rb new file mode 100644 index 00000000..7972fc59 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/test/test_logger.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/test_logger.rb new file mode 100644 index 00000000..abb4001c --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/test_logger.rb @@ -0,0 +1,100 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') + +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 + end +end diff --git a/lib/middleman/vendor/padrino-core-0.10.5/test/test_mounter.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/test_mounter.rb new file mode 100644 index 00000000..557de834 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/test_mounter.rb @@ -0,0 +1,177 @@ +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" } + 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" } + 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 11, Padrino.mounted_apps[0].routes.size + assert_equal 7, Padrino.mounted_apps[1].routes.size + assert_equal 5, 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 + 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 + end +end diff --git a/lib/middleman/vendor/padrino-core-0.10.5/test/test_reloader_complex.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/test_reloader_complex.rb new file mode 100644 index 00000000..d64af1a2 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/test/test_reloader_simple.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/test_reloader_simple.rb new file mode 100644 index 00000000..2e9e81e6 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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 1, @app.filters[:after].size + assert_equal 0, @app.middleware.size + assert_equal 4, @app.routes.size # GET+HEAD of "/" + GET+HEAD of "/rand" = 4 + assert_equal 2, @app.extensions.size # [Padrino::Routing, Padrino::Rendering] + 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 1, @app.filters[:after].size + assert_equal 0, @app.middleware.size + assert_equal 4, @app.routes.size # GET+HEAD of "/" = 2 + assert_equal 2, @app.extensions.size # [Padrino::Routing, Padrino::Rendering] + assert_equal 0, @app.templates.size + end + end +end diff --git a/lib/middleman/vendor/padrino-core-0.10.5/test/test_rendering.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/test_rendering.rb new file mode 100644 index 00000000..9d03959e --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/test_rendering.rb @@ -0,0 +1,461 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require 'i18n' + +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" } + 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 a <%= 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 a 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 :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 :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 "/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 => true }, { :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 405, 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 405, 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 + end +end diff --git a/lib/middleman/vendor/padrino-core-0.10.5/test/test_restful_routing.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/test_restful_routing.rb new file mode 100644 index 00000000..6d22634e --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/test/test_router.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/test_router.rb new file mode 100644 index 00000000..0bb7767d --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/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/lib/middleman/vendor/padrino-core-0.10.5/test/test_routing.rb b/lib/middleman/vendor/padrino-core-0.10.5/test/test_routing.rb new file mode 100644 index 00000000..47764627 --- /dev/null +++ b/lib/middleman/vendor/padrino-core-0.10.5/test/test_routing.rb @@ -0,0 +1,1673 @@ +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 /\/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 "/1234/" + assert_equal "Your lucky number: 1234 1234", body + get "/page/99" + assert_equal "My lucky number: 99 99", body + 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 '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 "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].conditions[:request_method] + assert_equal ["HEAD"], app.routes[1].conditions[:request_method] + assert_equal ["POST"], app.routes[2].conditions[:request_method] + 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 405, status + get "/c.js" + assert_equal "/c.json", body + get "/c.json" + assert_equal "/c.json", body + get "/c.ru" + assert_equal 405, 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 '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 405, 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 content_type to :json if render => :json" do + mock_app do + get("/foo"){ render :foo => :bar } + end + + get '/foo' + assert_equal 'application/json;charset=utf-8', content_type + 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 + 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 405, 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 "support not_found" do + mock_app do + not_found do + response.status = 404 + 'whatever' + end + + get :index, :map => "/" do + 'index' + end + end + get '/something' + assert_equal 'whatever', body + assert_equal 404, status + 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.named.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 '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 '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 "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}" } + get("/bar"){ "Bar in #{content_type}" } + 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 html', 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}" } + get(:bar, "/bar"){ "Bar in #{content_type}" } + 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 html', 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 '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 405, status + post "/.json" + assert_equal "This is the post index.json", body + post "/.js" + assert_equal 405, 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 '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 "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 + mock_app do + ::Rack::Mime::MIME_TYPES[".other"] = "text/html" + before do + params[:format] ||= :other + end + get("/format_test", :provides => [:html, :other]){ content_type.to_s } + end + get "/format_test" + assert_equal "other", body + 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' do + mock_app do + error(404) { "not found" } + end + get "/" + assert_equal 404, status + assert_match /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 +end diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/.document b/lib/middleman/vendor/padrino-helpers-0.10.5/.document new file mode 100644 index 00000000..136eea59 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/.document @@ -0,0 +1,5 @@ +lib/**/*.rb +bin/* +- +README.rdoc +LICENSE.txt diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/.gitignore b/lib/middleman/vendor/padrino-helpers-0.10.5/.gitignore new file mode 100644 index 00000000..c1e0dafa --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/.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/lib/middleman/vendor/padrino-helpers-0.10.5/.yardopts b/lib/middleman/vendor/padrino-helpers-0.10.5/.yardopts new file mode 100644 index 00000000..57854bc2 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/.yardopts @@ -0,0 +1 @@ +--title 'Padrino Helpers Documentation' --protected diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/LICENSE.txt b/lib/middleman/vendor/padrino-helpers-0.10.5/LICENSE.txt new file mode 100644 index 00000000..8f1ef777 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/README.rdoc b/lib/middleman/vendor/padrino-helpers-0.10.5/README.rdoc new file mode 100644 index 00000000..1903a926 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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 Padrino. See LICENSE for details. diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/Rakefile b/lib/middleman/vendor/padrino-helpers-0.10.5/Rakefile new file mode 100644 index 00000000..f33347d2 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers.rb new file mode 100644 index 00000000..20ef3c89 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers.rb @@ -0,0 +1,58 @@ +require 'padrino-core/support_lite' unless defined?(SupportLite) +require 'cgi' +require 'i18n' +require 'enumerator' +require 'active_support/core_ext/string/conversions' # to_date +require 'active_support/core_ext/float/rounding' # round +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__) + +# Load our locales +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 + # + # @param [Sinatra::Application] app + # The specified padrino application + # + # @example Register the helper module + # require 'padrino-helpers' + # class Padrino::Appliocation + # 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 + end + alias :included :registered + end + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/asset_tag_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/asset_tag_helpers.rb new file mode 100644 index 00000000..576e43de --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/asset_tag_helpers.rb @@ -0,0 +1,420 @@ +module Padrino + module Helpers + ### + # Helpers related to producing assets (images,stylesheets,js,etc) within templates. + # + module AssetTagHelpers + ## + # 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. + # + # @return [String] Flash tag html with specified +options+. + # + # @example + # flash_tag(:notice, :id => 'flash-notice') + # # Generates:
flash-notice
+ # + # @api public + def flash_tag(kind, options={}) + flash_text = flash[kind] + return '' if flash_text.blank? + options.reverse_merge!(:class => kind) + content_tag(:div, flash_text, options) + 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 [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 a 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 + # + # @api public + def link_to(*args, &block) + options = args.extract_options! + options = parse_js_attributes(options) # parses remote, method and confirm options + anchor = "##{CGI.escape options.delete(:anchor).to_s}" if options[:anchor] + + if block_given? + url = args[0] ? args[0] + anchor.to_s : anchor || 'javascript:void(0);' + 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 + name, url = args[0], (args[1] ? args[1] + anchor.to_s : anchor || 'javascript:void(0);') + return name unless parse_conditions(url, options) + options.reverse_merge!(:href => url) + content_tag(:a, name, options) + 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). + # + # @return [String] Form and button html with specified +options+. + # + # @example + # button_to 'Delete', url(:accounts_destroy, :id => account), :method => :delete, :class => :form + # # Generates: + # #
+ # # + # # + # #
+ # + # @api public + def button_to(*args, &block) + name, url = args[0], args[1] + options = args.extract_options! + desired_method = options[:method] + options.delete(:method) if options[:method].to_s !~ /get|post/i + options.reverse_merge!(:method => 'post', :action => url) + options[:enctype] = "multipart/form-data" if options.delete(:multipart) + options["data-remote"] = "true" if options.delete(:remote) + inner_form_html = hidden_form_method_field(desired_method) + inner_form_html += block_given? ? capture_html(&block) : submit_tag(name) + content_tag('form', inner_form_html, options) + 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: + # + # @api public + def feed_tag(mime, url, options={}) + full_mime = (mime == :atom) ? 'application/atom+xml' : 'application/rss+xml' + content_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" + # + # @api public + 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', '@') + 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" + # + # @api public + 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' + # + # @api public + 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') + # + # @api public + 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") + 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 + # + # @api public + def javascript_include_tag(*sources) + options = sources.extract_options!.symbolize_keys + options.reverse_merge!(:type => 'text/javascript', :content => "") + sources.flatten.map { |source| + tag(:script, options.reverse_merge(:src => asset_path(:js, source))) + }.join("\n") + 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' + # + # @api semipublic + def asset_path(kind, source) + return source if source =~ /^http/ + asset_folder = case kind + when :css then 'stylesheets' + when :js then 'javascripts' + else kind.to_s + end + source = source.to_s.gsub(/\s/, '%20') + ignore_extension = (asset_folder.to_s == kind.to_s) # don't append extension + source << ".#{kind}" unless ignore_extension or source =~ /\.#{kind}/ + result_path = source if source =~ %r{^/} # absolute path + result_path ||= uri_root_path(asset_folder, source) + timestamp = asset_timestamp(result_path) + "#{result_path}#{timestamp}" + end + + private + + ## + # Returns the uri root of the application. + # + # @example + # uri_root_path("/some/path") => "/base/some/path" + # + 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 = Padrino.root("public", file_path) if Padrino.respond_to?(:root) + stamp = Time.now.to_i unless public_path && File.exist?(public_path) + stamp ||= File.mtime(public_path).to_i + "?#{stamp}" + 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 + + ## + # Parses link_to options for given js declarations (remote, method, confirm) + # Not destructive on options; returns updated options + # + # parse_js_attributes(:remote => true, :confirm => "test", :method => :delete) + # => { "data-remote" => true, "data-method" => "delete", "data-confirm" => "test" } + # + def parse_js_attributes(options) + options = options.dup + options["data-remote"] = "true" if options.delete(:remote) + if link_confirm = options.delete(:confirm) + options["data-confirm"] = link_confirm + end + if link_method = options.delete(:method) + options["data-method"] = link_method + options["rel"] = "nofollow" + end + options + end + end # AssetTagHelpers + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_builder/abstract_form_builder.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_builder/abstract_form_builder.rb new file mode 100644 index 00000000..6e051281 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_builder/abstract_form_builder.rb @@ -0,0 +1,220 @@ +module Padrino + module Helpers + module FormBuilder # @private + class AbstractFormBuilder # @private + attr_accessor :template, :object + + 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 + + # f.error_messages + def error_messages(*params) + params.unshift object + @template.error_messages_for(*params) + end + + # f.error_message_on(field) + def error_message_on(field, options={}) + @template.error_message_on(object, field, options) + end + + # f.label :username, :caption => "Nickname" + def label(field, options={}) + options.reverse_merge!(:caption => "#{field_human_name(field)}: ") + @template.label_tag(field_id(field), options) + end + + # f.hidden_field :session_id, :value => "45" + 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 + + # f.text_field :username, :value => "(blank)", :id => 'username' + 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 + + # f.text_area :summary, :value => "(enter summary)", :id => 'summary' + 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 + + # f.password_field :password, :id => 'password' + 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 + + # f.select :color, :options => ['red', 'green'], :include_blank => true + # f.select :color, :collection => @colors, :fields => [:name, :id] + 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 + + # f.check_box :remember_me, :value => 'true', :uncheck_value => '0' + def check_box(field, options={}) + 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 + + # f.radio_button :gender, :value => 'male' + 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 + + # f.file_field :photo, :class => 'avatar' + def file_field(field, options={}) + options.reverse_merge!(:id => field_id(field)) + options.merge!(:class => field_error(field, options)) + @template.file_field_tag field_name(field), options + end + + # f.submit "Update", :class => 'large' + def submit(caption="Submit", options={}) + @template.submit_tag caption, options + end + + # f.image_submit "buttons/submit.png", :class => 'large' + 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) + result = 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") + 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 = [] + if root_form? + result << object_model_name + elsif nested_form? + parent_form = @options[:nested][:parent] + attributes_name = "#{@options[:nested][:association]}_attributes" + nested_index = @options[:nested][:index] + fragment = [parent_form.field_name, "[#{attributes_name}", "]"] + fragment.insert(2, "][#{nested_index}") if nested_index + result << fragment + end + 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 = [] + if root_form? + result << object_model_name + elsif nested_form? + parent_form = @options[:nested][:parent] + attributes_name = "#{@options[:nested][:association]}_attributes" + nested_index = @options[:nested][:index] + fragment = [parent_form.field_id, "_#{attributes_name}"] + fragment.push("_#{nested_index}") if nested_index + result << fragment + end + 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 + # field_value(:username) => "Joey" + def field_value(field) + @object && @object.respond_to?(field) ? @object.send(field) : "" + end + + # explicit_object is either a symbol or a record + # 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 + # => user_assignment + 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 + end # AbstractFormBuilder + end # FormBuilder + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_builder/standard_form_builder.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_builder/standard_form_builder.rb new file mode 100644 index 00000000..cbe11cc1 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_builder/standard_form_builder.rb @@ -0,0 +1,43 @@ +require File.expand_path(File.dirname(__FILE__) + '/abstract_form_builder') unless defined?(AbstractFormBuilder) + +module Padrino + module Helpers + module FormBuilder # @private + class StandardFormBuilder < AbstractFormBuilder # @private + + ## + # 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 + + # submit_block("Update") + def submit_block(caption, options={}) + submit_html = self.submit(caption, options) + @template.content_tag(:p, submit_html) + end + + # image_submit_block("submit.png") + def image_submit_block(source, options={}) + submit_html = self.image_submit(source, options) + @template.content_tag(:p, submit_html) + end + end # StandardFormBuilder + end # FormBuilder + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_helpers.rb new file mode 100644 index 00000000..54335a1c --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_helpers.rb @@ -0,0 +1,602 @@ +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 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 + # + # @api public + def form_for(object, url, settings={}, &block) + form_html = capture_html(builder_instance(object, settings), &block) + form_tag(url, settings) { form_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 + # + # @api public + 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_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 + # + # @api public + def form_tag(url, options={}, &block) + desired_method = options[:method] + data_method = options.delete(:method) if options[:method].to_s !~ /get|post/i + options.reverse_merge!(:method => "post", :action => url) + options[:enctype] = "multipart/form-data" if options.delete(:multipart) + options["data-remote"] = "true" if options.delete(:remote) + options["data-method"] = data_method if data_method + options["accept-charset"] ||= "UTF-8" + inner_form_html = hidden_form_method_field(desired_method) + inner_form_html += capture_html(&block) + concat_content content_tag(:form, inner_form_html, options) + 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') + # + # @api semipublic + def hidden_form_method_field(desired_method) + return '' 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') { } + # + # @api public + 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? ? '' : content_tag(:legend, legend_text) + field_set_content = legend_html + 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 ("errorExplanation") + # The id of the error div. + # @option options [String] :class ("errorExplanation") + # 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 + # + # @api public + 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.size } + + 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 + + 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].to_s.underscore.gsub(/\//, ' ') + 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].to_s.underscore.gsub(/\//, ' ') + 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 = '' + contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank? + contents << content_tag(:p, message) unless message.blank? + contents << 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 ("div") + # 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 + if error + options.reverse_merge!(:tag => :span, :class => :error) + tag = options.delete(:tag) + # Array(error).first is necessary because some orm give us an array others directly a value + error = [options.delete(:prepend), Array(error).first, 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 + # + # @api public + def label_tag(name, options={}, &block) + options.reverse_merge!(:caption => "#{name.to_s.humanize}: ", :for => name) + caption_text = options.delete(:caption) + caption_text << "* " if options.delete(:required) + if block_given? # label with inner content + label_content = caption_text + capture_html(&block) + concat_content(content_tag(:label, label_content, options)) + else # regular label + content_tag(:label, caption_text, options) + end + end + + ## + # Constructs a text field input from the given options + # + # @macro [new] input_field_doc + # @param [String] name + # The name of the input field. + # @param [Hash] options + # The html options for the input field. + # + # @return [String] The html input field based on the +options+ specified + # + # @example + # text_field_tag :username, :class => 'long' + # + # @api public + def text_field_tag(name, options={}) + options.reverse_merge!(:name => name) + input_tag(:text, options) + end + + ## + # Constructs a hidden field input from the given options + # + # @macro input_field_doc + # + # @example + # hidden_field_tag :session_key, :value => "__secret__" + # + # @api public + 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 + # + # @macro input_field_doc + # + # @example + # text_area_tag :username, :class => 'long', :value => "Demo?" + # + # @api public + 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 + # + # @macro input_field_doc + # + # @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 + # + # @macro input_field_doc + # + # @example + # check_box_tag :remember_me, :value => 'Yes' + # + # @api public + 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 + # + # @macro input_field_doc + # + # @example + # radio_button_tag :remember_me, :value => 'true' + # + # @api public + 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 + # + # @macro input_field_doc + # + # @example + # file_field_tag :photo, :class => 'long' + # + # @api public + def file_field_tag(name, options={}) + 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 + # + # @api public + 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] + 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' + # + # @api public + 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 + # 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' + # + # @api public + def submit_tag(caption="Submit", options={}) + 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' + # + # @api public + def image_submit_tag(source, options={}) + options.reverse_merge!(:src => image_path(source)) + input_tag(:image, options) + end + + protected + + ## + # Returns an array of option items for a select field based on the given collection + # 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| + value ||= caption + content_tag(:option, caption, :value => value, :selected => option_is_selected?(value, caption, selected_value)) + 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| + content_tag :optgroup, :label => key do + options_for_select(value, selected) + end + end + elsif collection.is_a?(Array) + collection.map do |optgroup| + content_tag :optgroup, :label => optgroup.first do + options_for_select(optgroup.last, selected) + end + 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 + + 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 + # + # @api private + 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 => { ... }) => + # + # @api private + 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 + # + # @api private + 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 # FormHelpers + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/format_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/format_helpers.rb new file mode 100644 index 00000000..fa3cb552 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/format_helpers.rb @@ -0,0 +1,381 @@ +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" + # + # @api public + def escape_html(text) + Rack::Utils.escape_html(text) + end + alias h escape_html + alias sanitize_html escape_html + + ## + # Returns escaped text to protect against malicious content + # Returns blank if the text is empty + # + # @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" + # + # @api public + def h!(text, blank_text = ' ') + return blank_text 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" + # + # @api public + 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
" + # + # @api public + def simple_format(text, options={}) + t = options.delete(:tag) || :p + start_tag = tag(t, options.merge(:open => true)) + text = 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 << "" + 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 the 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' + # + # @api public + 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..." + # + # @api public + 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..." + # + # @api public + 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" + # + # @api public + 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 + # + # @api public + 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 + # + # @api public + 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 + # + # @api public + 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

") + # + # @api public + def js_escape_html(html_content) + return '' unless html_content + javascript_mapping = { '\\' => '\\\\', ' '<\/', "\r\n" => '\n', "\n" => '\n', "\r" => '\n', '"' => '\\"', "'" => "\\'" } + html_content.gsub(/(\\|<\/|\r\n|[\n\r"'])/) { javascript_mapping[$1] } + end + + end # FormatHelpers + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/cs.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/cs.yml new file mode 100644 index 00000000..544d650a --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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: "," + # 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: "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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/da.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/da.yml new file mode 100644 index 00000000..c4664bf8 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/de.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/de.yml new file mode 100644 index 00000000..3db008ac --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/en.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/en.yml new file mode 100644 index 00000000..1d747701 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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: "." + # 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: "$" + # 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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/es.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/es.yml new file mode 100644 index 00000000..946680c5 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/fr.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/fr.yml new file mode 100644 index 00000000..72113130 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/fr.yml @@ -0,0 +1,80 @@ +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: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + + 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 ans" + other: "près de %{count} years" + 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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/hu.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/hu.yml new file mode 100644 index 00000000..704510d7 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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: "," + # 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: "%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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/it.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/it.yml new file mode 100644 index 00000000..7962fea8 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/ja.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/ja.yml new file mode 100644 index 00000000..b03a83d5 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/lv.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/lv.yml new file mode 100644 index 00000000..fcca5799 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/nl.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/nl.yml new file mode 100644 index 00000000..6944a63f --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/no.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/no.yml new file mode 100644 index 00000000..4a475b61 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/pl.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/pl.yml new file mode 100644 index 00000000..b690a5b9 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/pt_br.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/pt_br.yml new file mode 100644 index 00000000..35c4b1bc --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/ru.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/ru.yml new file mode 100644 index 00000000..838de2ba --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/tr.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/tr.yml new file mode 100644 index 00000000..22200cd7 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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: "." + # 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: "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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/uk.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/uk.yml new file mode 100644 index 00000000..e2461518 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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: "," + # 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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/zh_cn.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/zh_cn.yml new file mode 100644 index 00000000..1a5ce1d6 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/zh_cn.yml @@ -0,0 +1,104 @@ +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: "." + # 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: "元" + # 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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/zh_tw.yml b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/zh_tw.yml new file mode 100644 index 00000000..b3916702 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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: "." + # 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: "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/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/number_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/number_helpers.rb new file mode 100644 index 00000000..17d279f2 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/number_helpers.rb @@ -0,0 +1,288 @@ +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 £ + # + # @api public + 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% + # + # @api public + 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 + # + # @api public + 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 + # + # @api public + 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 + # + # @api public + 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 # NumberHelpers + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers.rb new file mode 100644 index 00000000..792eaf5c --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers.rb @@ -0,0 +1,175 @@ +module Padrino + module Helpers + ### + # Helpers related to buffer output for various template engines. + # + module OutputHelpers + + def self.included(base) # @private + base.send(:include, SinatraCurrentEngine) unless base.method_defined?(:current_engine) + end + + ## + # Module used to detect the current engine in vanilla sinatra apps. + # @private + module SinatraCurrentEngine + attr_reader :current_engine + + def render(engine, *) # @private + @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. + # + # @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..." + # + # @api semipublic + def capture_html(*args, &block) + handler = find_proper_handler + captured_html = "" + if handler && handler.is_type? && handler.block_is_type?(block) + captured_html = handler.capture_from_template(*args, &block) + end + # invoking the block directly if there was no template + captured_html = block_given? && block.call(*args) if captured_html.blank? + captured_html + end + alias :capture :capture_html + + ## + # Outputs the given text to the templates buffer directly. + # + # @param [String] text + # Text to concatenate to the buffer. + # + # @example + # concat_content("This will be output to the template buffer") + # + # @api semipublic + 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 + + ## + # 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. + # + # @api semipublic + 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") + # + # @api public + 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 + # + # @api public + 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" + # + # @api public + def yield_content(key, *args) + blocks = content_blocks[key.to_sym] + return nil if blocks.empty? + 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 concating 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 + end # OutputHelpers + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/abstract_handler.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/abstract_handler.rb new file mode 100644 index 00000000..fe6940b9 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/abstract_handler.rb @@ -0,0 +1,98 @@ +module Padrino + module Helpers + module OutputHelpers + ## + # Returns the list of all available template handlers + # + # @example + # OutputHelpers.handlers => [, ] + # + # @private + def self.handlers + @_template_handlers ||= [] + end + + ## + # Registers a new handler as available to the output helpers + # + # @example + # OutputHelpers.register(OutputHelpers::HamlHandler) + # + # @private + 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 # AbstractHandler + end # OutputHelpers + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/erb_handler.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/erb_handler.rb new file mode 100644 index 00000000..f40cf715 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/erb_handler.rb @@ -0,0 +1,79 @@ +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 = "", self.output_buffer + block.call(*args) + ret = eval("@_out_buf", block.binding) + self.output_buffer = _buf_was + ret + 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 # ErbHandler + + OutputHelpers.register(ErbHandler) + end # OutputHelpers + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/haml_handler.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/haml_handler.rb new file mode 100644 index 00000000..5c76c894 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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) # this is for rbx + 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 # HamlHandler + + OutputHelpers.register(HamlHandler) + end # OutputHelpers + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/slim_handler.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/slim_handler.rb new file mode 100644 index 00000000..9630f0dd --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/slim_handler.rb @@ -0,0 +1,81 @@ +# Make slim works with sinatra/padrino +Slim::Engine.set_default_options(:buffer => '@_out_buf', :generator => Temple::Generators::StringBuffer) if defined?(Slim) + +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 = "", self.output_buffer + block.call(*args) + ret = eval("@_out_buf", block.binding) + self.output_buffer = _buf_was + ret + 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 # SlimHandler + + OutputHelpers.register(SlimHandler) + end # OutputHelpers + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/render_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/render_helpers.rb new file mode 100644 index 00000000..f51bc94f --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/render_helpers.rb @@ -0,0 +1,60 @@ +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 + # + # @api public + 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") + else + if member = options.delete(:object) + options[:locals].merge!(object_name => member) + end + render(explicit_engine, template_path, options.dup) + end + end + alias :render_partial :partial + end # RenderHelpers + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/tag_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/tag_helpers.rb new file mode 100644 index 00000000..4629c4b6 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/tag_helpers.rb @@ -0,0 +1,103 @@ +module Padrino + module Helpers + ## + # Helpers related to producing html tags within templates. + # + module TagHelpers + ## + # Tag values escaped to html entities + # + ESCAPE_VALUES = { + "<" => "<", + ">" => ">", + '"' => """ + } + + ## + # Creates an html tag with given name, content and options + # + # @overload content_tag(name, content, options) + # @param [Symbol] name The html type of tag. + # @param [String] content The contents in the tag. + # @param [Hash] options The html options to include in this tag. + # @overload content_tag(name, options, &block) + # @param [Symbol] name The html type of tag. + # @param [Hash] options The html options to include in this tag. + # @param [Proc] block The block returning html content + # + # @return [String] The html generated for the tag. + # + # @example + # content_tag(:p, "hello", :class => 'light') + # content_tag(:p, :class => 'dark') { ... } + # + # @api public + def content_tag(*args, &block) + name = args.first + options = args.extract_options! + tag_html = block_given? ? capture_html(&block) : args[1] + tag_result = tag(name, options.merge(:content => tag_html)) + block_is_template?(block) ? concat_content(tag_result) : tag_result + end + + ## + # Creates an html input field with given type and options + # + # @param [Symbol] type + # The html type of tag to create. + # @param [Hash] options + # The html options to include in this tag. + # + # @return [String] The html for the input tag. + # + # @example + # input_tag :text, :class => "test" + # input_tag :password, :size => "20" + # + # @api semipublic + def input_tag(type, options = {}) + options.reverse_merge!(:type => type) + tag(:input, options) + end + + ## + # Creates an html tag with the given name and options + # + # @param [Symbol] type + # The html type of tag to create. + # @param [Hash] options + # The html options to include in this tag. + # + # @return [String] The html for the input tag. + # + # @example + # tag(:br, :style => 'clear:both') + # tag(:p, :content => "hello", :class => 'large') + # + # @api public + def tag(name, options={}) + content, open_tag = options.delete(:content), options.delete(:open) + content = content.join("\n") if content.respond_to?(:join) + identity_tag_attributes.each { |attr| options[attr] = attr.to_s if options[attr] } + html_attrs = options.map { |a, v| v.nil? || v == false ? nil : "#{a}=\"#{escape_value(v)}\"" }.compact.join(" ") + base_tag = (html_attrs.present? ? "<#{name} #{html_attrs}" : "<#{name}") + base_tag << (open_tag ? ">" : (content ? ">#{content}" : " />")) + end + + private + ## + # Returns a list of attributes which can only contain an identity value (i.e selected) + # + def identity_tag_attributes + [:checked, :disabled, :selected, :multiple] + end + + ## + # Escape tag values to their HTML/XML entities. + # + def escape_value(string) + string.to_s.gsub(Regexp.union(*ESCAPE_VALUES.keys)){|c| ESCAPE_VALUES[c] } + end + end # TagHelpers + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/translation_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/translation_helpers.rb new file mode 100644 index 00000000..35088ff6 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/translation_helpers.rb @@ -0,0 +1,38 @@ +module Padrino + module Helpers + ## + # Helpers related to locale1 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. + # + # @api public + 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. + # + # @api public + def localize(*args) + I18n.localize(*args) + end + alias :l :localize + end # TranslationHelpers + end # Helpers +end # Padrino diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/padrino-helpers.gemspec b/lib/middleman/vendor/padrino-helpers-0.10.5/padrino-helpers.gemspec new file mode 100755 index 00000000..01d1d61c --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/app.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/app.rb new file mode 100644 index 00000000..6c44f893 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/app.rb @@ -0,0 +1,73 @@ +require 'sinatra/base' +require 'haml' +require 'erubis' +require 'slim' + +class MarkupDemo < Sinatra::Base + register Padrino::Helpers + + configure do + set :root, File.dirname(__FILE__) + 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}

" + end + + def concat_in_p(content_html) + concat_content "

#{content_html}

" + end + + def determine_block_is_template(name, &block) + concat_content "

The #{name} block passed in is a template

" if block_is_template?(block) + end + + def ruby_not_template_block + determine_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 a 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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/capture_concat.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/capture_concat.erb new file mode 100644 index 00000000..395536ad --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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') %> + +<% determine_block_is_template('erb') do %> + This is erb + This is erb +<% end %> + +<% ruby_not_template_block %> diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/capture_concat.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/capture_concat.haml new file mode 100644 index 00000000..54831676 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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') + +- determine_block_is_template('haml') do + %span This is haml + %span This is haml + +- ruby_not_template_block diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/capture_concat.slim b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/capture_concat.slim new file mode 100644 index 00000000..39fe7dd1 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/capture_concat.slim @@ -0,0 +1,13 @@ +-@content = captured_content do + span Captured Line 1 + span Captured Line 2 + +==@content + +==determine_block_is_template('slim') do + span This is slim + span This is slim + +==concat_in_p('Concat Line 3') + +==ruby_not_template_block diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_for.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_for.erb new file mode 100644 index 00000000..bede704d --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_for.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_for.haml new file mode 100644 index 00000000..80055aa8 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_for.slim b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_for.slim new file mode 100644 index 00000000..f6e6770d --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_tag.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_tag.erb new file mode 100644 index 00000000..2771f33a --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_tag.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_tag.haml new file mode 100644 index 00000000..780a2332 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_tag.slim b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_tag.slim new file mode 100644 index 00000000..84e42bf3 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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 diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/current_engine.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/current_engine.erb new file mode 100644 index 00000000..94f9d7f0 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/current_engine.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/current_engine.haml new file mode 100644 index 00000000..3522395c --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/current_engine.slim b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/current_engine.slim new file mode 100644 index 00000000..6c7d0926 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/fields_for.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/fields_for.erb new file mode 100644 index 00000000..cb43d2e0 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/fields_for.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/fields_for.haml new file mode 100644 index 00000000..6a67d79b --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/fields_for.slim b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/fields_for.slim new file mode 100644 index 00000000..517ef210 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.erb new file mode 100644 index 00000000..f36a6f0b --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.erb @@ -0,0 +1,56 @@ +<% 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 :email, :caption => "Email", :class => 'user-email' %> + <%= f.text_field :email %> +

+

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

+

+ <%= 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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.haml new file mode 100644 index 00000000..669b09a6 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.haml @@ -0,0 +1,47 @@ +- 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 :email, :caption => "Email", :class => 'user-email' + = f.text_field :email + %p + = f.label :password + = f.password_field :password, :class => 'user-password', :value => "secret" + %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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.slim b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.slim new file mode 100644 index 00000000..7a7c3590 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.slim @@ -0,0 +1,47 @@ +== 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 :email, :caption => "Email", :class => 'user-email' + == f.text_field :email + p + == f.label :password + == f.password_field :password, :class => 'user-password', :value => "secret" + 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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.erb new file mode 100644 index 00000000..0872d78e --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.erb @@ -0,0 +1,56 @@ +<% 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 %> + <%= check_box_tag :remember_me %> + <%= label_tag :gender %> + <%= label_tag :color %> + <%= select_tag :color, :options => ['green', 'orange', 'purple'] %> + <%= 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 :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 %> +

+ <% end %> + <% field_set_tag(:class => 'buttons') do %> + <%= submit_tag "Login" %> + <%= button_tag "Cancel" %> + <%= image_submit_tag "buttons/submit.png" %> + <% end %> +<% end %> diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.haml new file mode 100644 index 00000000..bf392861 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.haml @@ -0,0 +1,45 @@ +- 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 :color + = select_tag :color, :options => ['green', 'orange', 'purple'] + = 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 :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 + - field_set_tag(:class => 'buttons') do + = submit_tag "Login" + = button_tag "Cancel" + = image_submit_tag "buttons/submit.png" diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.slim b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.slim new file mode 100644 index 00000000..e71846c7 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.slim @@ -0,0 +1,45 @@ +== 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 :color + == select_tag :color, :options => ['green', 'orange', 'purple'] + == 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 :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 + == field_set_tag(:class => 'buttons') do + == submit_tag "Login" + == button_tag "Cancel" + == image_submit_tag "buttons/submit.png" diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/link_to.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/link_to.erb new file mode 100644 index 00000000..56631c4f --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/link_to.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/link_to.haml new file mode 100644 index 00000000..b53277d4 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/link_to.slim b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/link_to.slim new file mode 100644 index 00000000..5e0a837f --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/mail_to.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/mail_to.erb new file mode 100644 index 00000000..a0b54128 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/mail_to.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/mail_to.haml new file mode 100644 index 00000000..4cd7b791 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/mail_to.slim b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/mail_to.slim new file mode 100644 index 00000000..e17a1a44 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/meta_tag.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/meta_tag.erb new file mode 100644 index 00000000..a9d086d3 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/meta_tag.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/meta_tag.haml new file mode 100644 index 00000000..9ed5ae35 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/meta_tag.slim b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/meta_tag.slim new file mode 100644 index 00000000..7d809deb --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_erb.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_erb.erb new file mode 100644 index 00000000..365e638f --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_erb.erb @@ -0,0 +1 @@ +<%= current_engine %> diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_haml.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_haml.haml new file mode 100644 index 00000000..790066c9 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_haml.haml @@ -0,0 +1 @@ +=current_engine diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_slim.slim b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_slim.slim new file mode 100644 index 00000000..790066c9 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_slim.slim @@ -0,0 +1 @@ +=current_engine diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.erb new file mode 100644 index 00000000..1bfd39ae --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.erb @@ -0,0 +1 @@ +

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

diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.haml new file mode 100644 index 00000000..bc120c58 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.haml @@ -0,0 +1 @@ +%p.haml= partial 'partials/haml', :engine => "haml" diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.slim b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.slim new file mode 100644 index 00000000..698d9a0e --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.slim @@ -0,0 +1 @@ +p.slim= partial 'partials/slim', :engine => "slim" diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/app.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/app.rb new file mode 100644 index 00000000..809bf766 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/app.rb @@ -0,0 +1,50 @@ +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 + 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 + + # 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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engine.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engine.haml new file mode 100644 index 00000000..e49423d1 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_erb.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_erb.erb new file mode 100644 index 00000000..d10c2b3b --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_erb.erb @@ -0,0 +1 @@ +<%= current_engine %> diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_haml.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_haml.haml new file mode 100644 index 00000000..4db543bc --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_haml.haml @@ -0,0 +1 @@ +%span=current_engine diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_slim.slim b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_slim.slim new file mode 100644 index 00000000..480cb50b --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_slim.slim @@ -0,0 +1 @@ +span=current_engine diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/erb/test.erb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/erb/test.erb new file mode 100644 index 00000000..6549fd1e --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/erb/test.erb @@ -0,0 +1 @@ +

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

diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/explicit_engine.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/explicit_engine.haml new file mode 100644 index 00000000..337ff147 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/haml/test.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/haml/test.haml new file mode 100644 index 00000000..352e28f6 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/haml/test.haml @@ -0,0 +1 @@ +%h1 This is a #{@template} template! diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/template/_user.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/template/_user.haml new file mode 100644 index 00000000..cba4cc4b --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/template/haml_template.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/template/haml_template.haml new file mode 100644 index 00000000..519fc9d2 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/template/some_template.haml b/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/template/some_template.haml new file mode 100644 index 00000000..c98a33e5 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/helper.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/helper.rb new file mode 100644 index 00000000..b1452e6d --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/helper.rb @@ -0,0 +1,66 @@ +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 + 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/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_asset_tag_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_asset_tag_helpers.rb new file mode 100644 index 00000000..cfe532be --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_asset_tag_helpers.rb @@ -0,0 +1,320 @@ +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.tap { |app| app.set :environment, :test } + end + + def 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 + 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 => 'javascript:void(0);', :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 "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 + 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 "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?#{time.to_i}") { image_tag('/absolute/pic.gif') } + end + + should "display image tag absolute 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 + self.class.expects(:asset_stamp).returns(false) + assert_has_tag('img', :src => "/absolute/pic.gif") { image_tag('/absolute/pic.gif') } + end + + should "have xhtml convention tag" do + self.class.expects(:asset_stamp).returns(false) + 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 + expected_options = { :media => "screen", :rel => "stylesheet", :type => "text/css" } + assert_has_tag('link', expected_options.merge(:href => "/stylesheets/style.css?#{time.to_i}")) { stylesheet_link_tag('style') } + 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?#{time.to_i}")) { 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 } + 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?#{time.to_i}", :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 "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/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_form_builder.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_form_builder.rb new file mode 100644 index 00000000..74d35988 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_form_builder.rb @@ -0,0 +1,996 @@ +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 + + # Dummy form builder for testing + module Padrino::Helpers::FormBuilder + class FakeFormBuilder < AbstractFormBuilder + def foo_field; @template.content_tag(:span, "bar"); end + end + end + + def app + MarkupDemo.tap { |app| app.set :environment, :test } + 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") + @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')).once + actual_html = "" + 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 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-method" => 'put', "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' + 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' + 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' + 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 => '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 => '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 => '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 "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 #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 #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]', :rows => '', :cols => '') { 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 + 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" 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?#{@stamp}") { 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/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_form_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_form_helpers.rb new file mode 100644 index 00000000..ba9d2afa --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_form_helpers.rb @@ -0,0 +1,645 @@ +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.tap { |app| app.set :environment, :test } + 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", :"data-method" => 'put') { 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 "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' + 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' + 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' + 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 a 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 a 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 a 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 + 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 erb for simple form" do + visit '/erb/form_tag' + assert_have_selector 'form.simple-form label', :count => 4 + 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 => 6 + 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 => 4 + 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 => 6 + 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 => 4 + 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 => 6 + 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 #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', :rows => '', :cols => '') { 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 "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 "return a select tag with grouped options for an 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 "return a 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 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 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') + 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') + 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') + 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 + 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?#{@stamp}") { 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 +end diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_format_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_format_helpers.rb new file mode 100644 index 00000000..19e9c5ed --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_format_helpers.rb @@ -0,0 +1,227 @@ +require File.expand_path(File.dirname(__FILE__) + '/helper') +require File.expand_path(File.dirname(__FILE__) + '/fixtures/markup_app/app') + +describe "FormatHelpers" do + def app + MarkupDemo.tap { |app| app.set :environment, :test } + end + + def setup + Time.stubs(:now).returns(Time.utc(1983, 11, 9, 5)) + end + + include Padrino::Helpers::FormatHelpers + + 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 "

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 + 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"') + end + should "escape single quotes" do + assert_equal "\\'hello\\'", js_escape_html("'hello'") + end + should "escape html tags and breaks" do + assert_equal "\\n\\n

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

hello

\r\n") + end + should "escape data-confirm attribute" do + assert_equal "", js_escape_html("") + end + end +end diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_locale.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_locale.rb new file mode 100644 index 00000000..06b8b501 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/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/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_number_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_number_helpers.rb new file mode 100644 index 00000000..b9d1e66c --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_number_helpers.rb @@ -0,0 +1,136 @@ +describe "NumberHelpers" do + include Padrino::Helpers::NumberHelpers + + 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/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_output_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_output_helpers.rb new file mode 100644 index 00000000..54f20857 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_output_helpers.rb @@ -0,0 +1,153 @@ +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.tap { |app| app.set :environment, :test } + 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' + 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_eventually "work for slim templates" do + visit '/slim/capture_concat' + assert_have_selector 'p', :content => "The slim block passed in is a template", :class => 'is_template' + # TODO Get SLIM 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 + 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/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_render_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_render_helpers.rb new file mode 100644 index 00000000..68bc6538 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_render_helpers.rb @@ -0,0 +1,76 @@ +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.tap { |app| app.set :environment, :test } + 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 + end +end diff --git a/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_tag_helpers.rb b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_tag_helpers.rb new file mode 100644 index 00000000..7dd14a87 --- /dev/null +++ b/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_tag_helpers.rb @@ -0,0 +1,105 @@ +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.tap { |app| app.set :environment, :test } + 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 tags with content no attributes" do + assert_has_tag(:p, :content => "Demo String") { tag(:p, :content => "Demo String") } + end + + should "support tags with content and attributes" do + actual_html = tag(:p, :content => "Demo", :class => 'large', :id => 'intro') + assert_has_tag('p#intro.large', :content => "Demo") { actual_html } + end + + should "support open tags" do + actual_html = tag(:p, :class => 'demo', :open => 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 "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