refactoring the middlewares (WIP)
did
committed Feb 10, 2015
commit 34b5dd19229b8dd1877573ab9eacf93317c6789c
Showing 45
changed files with
1273 additions
and 420 deletions
Gemfile
+2
-2
| @@ | @@ -3,11 +3,11 @@ source 'https://rubygems.org' |
| gemspec | |
| group :development do | |
| - | # gem 'locomotivecms_common', '~> 0.0.2', path: '../common' |
| + | gem 'locomotivecms_common', '~> 0.0.2', path: '../common' |
| # gem 'locomotivecms_models', '~> 0.0.1', path: '../models' | |
| # gem 'locomotivecms_models', '0.0.1.pre.alpha' | |
| # gem 'locomotivecms-liquid', path: '/Users/didier/Documents/LocomotiveCMS/gems/liquid' | |
| - | # gem 'thin' |
| + | gem 'thin' |
| end | |
| group :test do | |
Gemfile.lock
+16
-4
| @@ | @@ -9,7 +9,7 @@ PATH |
| dragonfly (~> 1.0.7) | |
| haml (~> 4.0.6) | |
| httparty (~> 0.13.3) | |
| - | kaminari (~> 0.16.2) |
| + | kaminari (= 0.16.1) |
| kramdown (~> 1.5.0) | |
| locomotivecms-solid (~> 4.0.0.alpha2) | |
| locomotivecms_common (~> 0.0.2) | |
| @@ | @@ -22,6 +22,12 @@ PATH |
| sprockets (~> 2.12.3) | |
| sprockets-sass (~> 1.3.1) | |
| + | PATH |
| + | remote: ../common |
| + | specs: |
| + | locomotivecms_common (0.0.2) |
| + | colorize |
| + | |
| GEM | |
| remote: https://rubygems.org/ | |
| specs: | |
| @@ | @@ -79,6 +85,7 @@ GEM |
| simplecov (~> 0.9.1) | |
| term-ansicolor (~> 1.3) | |
| thor (~> 0.19.1) | |
| + | daemons (1.1.9) |
| debugger-linecache (1.2.0) | |
| diff-lcs (1.2.5) | |
| docile (1.1.5) | |
| @@ | @@ -87,6 +94,7 @@ GEM |
| multi_json (~> 1.0) | |
| rack | |
| erubis (2.7.0) | |
| + | eventmachine (1.0.4) |
| execjs (2.3.0) | |
| ffi (1.9.6) | |
| haml (4.0.6) | |
| @@ | @@ -104,15 +112,13 @@ GEM |
| json_spec (1.1.4) | |
| multi_json (~> 1.0) | |
| rspec (>= 2.0, < 4.0) | |
| - | kaminari (0.16.2) |
| + | kaminari (0.16.1) |
| actionpack (>= 3.0.0) | |
| activesupport (>= 3.0.0) | |
| kramdown (1.5.0) | |
| locomotivecms-liquid (4.0.0.alpha2) | |
| locomotivecms-solid (4.0.0.alpha2) | |
| locomotivecms-liquid (~> 4.0.0.alpha2) | |
| - | locomotivecms_common (0.0.2) |
| - | colorize |
| loofah (2.0.1) | |
| nokogiri (>= 1.5.9) | |
| method_source (0.8.2) | |
| @@ | @@ -185,6 +191,10 @@ GEM |
| tilt (~> 1.1) | |
| term-ansicolor (1.3.0) | |
| tins (~> 1.0) | |
| + | thin (1.6.3) |
| + | daemons (~> 1.0, >= 1.0.9) |
| + | eventmachine (~> 1.0) |
| + | rack (~> 1.0) |
| thor (0.19.1) | |
| thread_safe (0.3.4) | |
| tilt (1.4.1) | |
| @@ | @@ -201,7 +211,9 @@ DEPENDENCIES |
| coveralls | |
| i18n-spec (~> 0.6.0) | |
| json_spec (~> 1.1.4) | |
| + | locomotivecms_common (~> 0.0.2)! |
| locomotivecms_steam! | |
| pry-byebug | |
| rake (~> 10.4.2) | |
| rspec (~> 3.1.0) | |
| + | thin |
Rakefile
+5
-0
| @@ | @@ -15,4 +15,9 @@ require_relative 'lib/locomotive/steam' |
| require 'rspec/core/rake_task' | |
| RSpec::Core::RakeTask.new('spec') | |
| + | |
| + | RSpec::Core::RakeTask.new('spec:unit') do |spec| |
| + | spec.pattern = 'spec/unit/**/*_spec.rb' |
| + | end |
| + | |
| task default: :spec | |
example/server.rb
+21
-9
| @@ | @@ -6,26 +6,38 @@ require 'bundler/setup' |
| Bundler.require | |
| require 'thin' | |
| - | # require 'common' |
| - | require 'locomotive/common' |
| require_relative '../lib/locomotive/steam' | |
| require_relative '../lib/locomotive/steam/server' | |
| - | require_relative '../lib/locomotive/steam/initializers' |
| path = ENV['SITE_PATH'] || File.join(File.expand_path(File.dirname(__FILE__)), '../spec/fixtures/default') | |
| # reader = Locomotive::Mounter::Reader::FileSystem.instance | |
| # reader.run!(path: path) | |
| - | datastore = Locomotive::Steam::FileSystemDatastore.new(path: path) |
| + | # datastore = Locomotive::Steam::FileSystemDatastore.new(path: path) |
| - | app = Locomotive::Steam::Server.new(datastore, { |
| - | serve_assets: true |
| - | }) |
| + | # app = Locomotive::Steam::Server.new(datastore, { |
| + | # serve_assets: true |
| + | # }) |
| - | server = Thin::Server.new('localhost', '3333', app) |
| - | server.threaded = true |
| + | Locomotive::Steam.configure do |config| |
| + | config.mode = :test |
| + | end |
| + | |
| + | Locomotive::Common.reset |
| + | Locomotive::Common.configure do |config| |
| + | path = File.join(path, 'log/steam.log') |
| + | config.notifier = Locomotive::Common::Logger.setup(path) |
| + | end |
| + | |
| + | server = Locomotive::Steam::Server.new(path: path) |
| + | |
| + | # THIN |
| + | # server = Thin::Server.new('localhost', '3333', foo) |
| + | # server.threaded = true |
| + | |
| + | Rack::Handler::WEBrick.run server.to_app |
| Locomotive::Common::Logger.info 'Server started...' | |
| server.start | |
locomotive/steam.rb b/lib/locomotive/steam.rb
+7
-8
| @@ | @@ -1,5 +1,10 @@ |
| require 'locomotive/common' | |
| + | require 'active_support' |
| + | require 'active_support/concern' |
| + | require 'active_support/deprecation' |
| + | require 'active_support/core_ext' |
| + | |
| require_relative 'steam/core_ext' | |
| require_relative 'steam/exceptions' | |
| require_relative 'steam/configuration' | |
| @@ | @@ -11,19 +16,11 @@ require_relative 'steam/repositories' |
| require_relative 'steam/services' | |
| # TODO: move into a file named dependencies | |
| - | require 'sprockets' |
| - | require 'sprockets-sass' |
| require 'haml' | |
| require 'compass' | |
| require 'mimetype_fu' | |
| require 'mime-types' | |
| require 'rack/csrf' | |
| - | |
| - | require 'active_support' |
| - | require 'active_support/concern' |
| - | require 'active_support/deprecation' |
| - | require 'active_support/core_ext' |
| - | |
| require 'mime/types' | |
| module Locomotive | |
| @@ | @@ -45,6 +42,8 @@ module Locomotive |
| def self.configure | |
| yield(configuration) | |
| + | |
| + | require_relative 'steam/initializers' |
| end | |
| # FIXME: not sure it will be ever needed | |
locomotive/steam/core_ext/hash.rb b/lib/locomotive/steam/core_ext/hash.rb
+4
-0
| @@ | @@ -11,6 +11,10 @@ module HashConverter |
| convert(hash, :to_s) | |
| end | |
| + | def to_sym(hash) |
| + | convert(hash, :to_sym) |
| + | end |
| + | |
| # FIXME: not sure it will be ever needed | |
| # def to_camel_case hash | |
| # convert hash, :camelize, :lower | |
locomotive/steam/initializers.rb b/lib/locomotive/steam/initializers.rb
+3
-3
| @@ | @@ -2,6 +2,6 @@ require_relative 'initializers/sprockets.rb' |
| require_relative 'initializers/i18n.rb' | |
| require_relative 'initializers/dragonfly.rb' | |
| - | Locomotive::Common.configure do |config| |
| - | config.notifier = Locomotive::Common::Logger.setup |
| - | end |
| + | # Locomotive::Common.configure do |config| |
| + | # config.notifier = Locomotive::Common::Logger.setup |
| + | # end |
locomotive/steam/initializers/sprockets.rb b/lib/locomotive/steam/initializers/sprockets.rb
+4
-1
| @@ | @@ -1 +1,4 @@ |
| - | Sprockets::Sass.add_sass_functions = false |
| \ No newline at end of file | |
| + | require 'sprockets' |
| + | require 'sprockets-sass' |
| + | |
| + | Sprockets::Sass.add_sass_functions = false |
locomotive/steam/liquid/drops/i18n_base.rb b/lib/locomotive/steam/liquid/drops/i18n_base.rb
+3
-2
| @@ | @@ -5,7 +5,8 @@ module Locomotive |
| class I18nBase < Base | |
| def initialize(source, localized_attributes = []) | |
| - | decorated = Locomotive::Steam::Decorators::I18nDecorator.new(source, localized_attributes) |
| + | decorated = source if source.respond_to?(:__locale__) |
| + | decorated ||= Locomotive::Steam::Decorators::I18nDecorator.new(source, localized_attributes) |
| super(decorated) | |
| end | |
| @@ | @@ -14,7 +15,7 @@ module Locomotive |
| @_source.__locale__ = locale | |
| end | |
| - | @_source.__default_locale__ = context.registers[:site].default_locale |
| + | @_source.__default_locale__ = context.registers[:site].try(:default_locale) |
| super | |
| end | |
locomotive/steam/liquid/drops/site.rb b/lib/locomotive/steam/liquid/drops/site.rb
+1
-1
| @@ | @@ -2,7 +2,7 @@ module Locomotive |
| module Steam | |
| module Liquid | |
| module Drops | |
| - | class Site < Base |
| + | class Site < I18nBase |
| delegate :name, :domains, :seo_title, :meta_keywords, :meta_description, to: :@_source | |
locomotive/steam/liquid/tags/locale_switcher.rb b/lib/locomotive/steam/liquid/tags/locale_switcher.rb
+1
-0
| @@ | @@ -2,6 +2,7 @@ module Locomotive |
| module Steam | |
| module Liquid | |
| module Tags | |
| + | |
| # Display the links to change the locale of the current page | |
| # | |
| # Usage: | |
locomotive/steam/middlewares.rb b/lib/locomotive/steam/middlewares.rb
+18
-8
| @@ | @@ -1,15 +1,25 @@ |
| - | require_relative 'middlewares/base' |
| + | require_relative 'middlewares/threadsafe' |
| + | require_relative 'middlewares/helpers' |
| require_relative 'middlewares/favicon' | |
| - | require_relative 'middlewares/static_assets' |
| - | require_relative 'middlewares/dynamic_assets' |
| + | require_relative 'middlewares/site' |
| + | require_relative 'middlewares/default_env' |
| + | require_relative 'middlewares/locale' |
| + | require_relative 'middlewares/timezone' |
| require_relative 'middlewares/logging' | |
| - | require_relative 'middlewares/entry_submission' |
| require_relative 'middlewares/path' | |
| - | require_relative 'middlewares/locale' |
| require_relative 'middlewares/page' | |
| - | require_relative 'middlewares/timezone' |
| - | require_relative 'middlewares/templatized_page' |
| + | |
| + | # require_relative 'middlewares/static_assets' |
| + | # require_relative 'middlewares/dynamic_assets' |
| + | |
| + | # require_relative 'middlewares/entry_submission' |
| + | |
| + | |
| + | |
| + | |
| + | # require_relative 'middlewares/templatized_page' |
| + | # require_relative 'middlewares/site' |
| require_relative 'middlewares/renderer' | |
| - | require_relative 'middlewares/stack' |
| \ No newline at end of file | |
| + | require_relative 'middlewares/stack' |
locomotive/steam/middlewares/base.rb b/lib/locomotive/steam/middlewares/base.rb
+71
-65
| @@ | @@ -1,65 +1,71 @@ |
| - | module Locomotive::Steam |
| - | module Middlewares |
| - | |
| - | class Base |
| - | |
| - | attr_accessor :app, :request, :path |
| - | attr_accessor :liquid_assigns, :services |
| - | attr_accessor :site, :page, :content_entry, :locale |
| - | |
| - | def initialize(app = nil) |
| - | @app = app |
| - | end |
| - | |
| - | def call(env) |
| - | if Locomotive::Steam.mode == :test |
| - | _call(env) |
| - | else |
| - | dup._call(env) # thread-safe purpose |
| - | end |
| - | end |
| - | |
| - | def _call(env) |
| - | code, headers, response = @app.call(env) |
| - | self.set_accessors(env) |
| - | [code, headers, [response]] |
| - | end |
| - | |
| - | protected |
| - | |
| - | def set_accessors(env) |
| - | %w(path site request page content_entry services locale).each do |name| |
| - | self.send(:"#{name}=", env.fetch("steam.#{name}", nil)) |
| - | end |
| - | |
| - | env['steam.liquid_assigns'] ||= {} |
| - | self.liquid_assigns = env.fetch('steam.liquid_assigns') |
| - | end |
| - | |
| - | def params |
| - | self.request.params.deep_symbolize_keys |
| - | end |
| - | |
| - | def html? |
| - | ['text/html', 'application/x-www-form-urlencoded'].include?(self.request.media_type) && |
| - | !self.request.xhr? && |
| - | !self.json? |
| - | end |
| - | |
| - | def json? |
| - | self.request.content_type == 'application/json' || File.extname(self.request.path) == '.json' |
| - | end |
| - | |
| - | def redirect_to(location, type = 301) |
| - | self.log "Redirected to #{location}" |
| - | [type, { 'Content-Type' => 'text/html', 'Location' => location }, []] |
| - | end |
| - | |
| - | def log(msg) |
| - | Locomotive::Common::Logger.info msg |
| - | end |
| - | |
| - | end |
| - | |
| - | end |
| - | end |
| + | # module Locomotive::Steam |
| + | # module Middlewares |
| + | |
| + | # class Base |
| + | |
| + | # # attr_accessor :app, :request, :path |
| + | # # attr_accessor :liquid_assigns, :services |
| + | # # attr_accessor :site, :page, :content_entry, :locale |
| + | |
| + | # # def initialize(app = nil) |
| + | # # puts "...creating #{self.class.name}... #{app.nil?}" |
| + | # # @app = app |
| + | # # end |
| + | |
| + | # # def call(env) |
| + | # # dup._call(env) # thread-safe purpose |
| + | # # # _call(env) |
| + | # # # if Locomotive::Steam.configuration.mode == :test |
| + | # # # _call(env) |
| + | # # # else |
| + | # # # end |
| + | # # end |
| + | |
| + | # # def _call(env) |
| + | # # code, headers, response = @app.call(env) |
| + | # # # self.set_accessors(env) |
| + | # # [code, headers, [response]] |
| + | # # end |
| + | |
| + | # # protected |
| + | |
| + | # # # def path |
| + | # # # @path ||= @env.fetch('steam.path', nil) |
| + | # # # end |
| + | |
| + | # # # def set_accessors(env) |
| + | # # # %w(path site request page content_entry services locale).each do |name| |
| + | # # # self.send(:"#{name}=", env.fetch("steam.#{name}", nil)) |
| + | # # # end |
| + | |
| + | # # # env['steam.liquid_assigns'] ||= {} |
| + | # # # self.liquid_assigns = env.fetch('steam.liquid_assigns') |
| + | # # # end |
| + | |
| + | # # def params |
| + | # # self.request.params.deep_symbolize_keys |
| + | # # end |
| + | |
| + | # # def html? |
| + | # # ['text/html', 'application/x-www-form-urlencoded'].include?(self.request.media_type) && |
| + | # # !self.request.xhr? && |
| + | # # !self.json? |
| + | # # end |
| + | |
| + | # # def json? |
| + | # # self.request.content_type == 'application/json' || File.extname(self.request.path) == '.json' |
| + | # # end |
| + | |
| + | # # def redirect_to(location, type = 301) |
| + | # # self.log "Redirected to #{location}" |
| + | # # [type, { 'Content-Type' => 'text/html', 'Location' => location }, []] |
| + | # # end |
| + | |
| + | # # def log(msg) |
| + | # # Locomotive::Common::Logger.info msg |
| + | # # end |
| + | |
| + | # end |
| + | |
| + | # end |
| + | # end |
locomotive/steam/middlewares/default_env.rb b/lib/locomotive/steam/middlewares/default_env.rb
+22
-0
| @@ | @@ -0,0 +1,22 @@ |
| + | module Locomotive::Steam |
| + | module Middlewares |
| + | |
| + | class DefaultEnv < Struct.new(:app, :options) |
| + | |
| + | def call(env) |
| + | # time = Benchmark.realtime do |
| + | request = Rack::Request.new(env) |
| + | |
| + | env['steam.request'] = request |
| + | env['steam.services'] = Locomotive::Steam::Services.build_instance(request, options) |
| + | # end |
| + | |
| + | # puts "[Benchmark][DefaultEnv] Time elapsed #{time*1000} milliseconds" |
| + | |
| + | app.call(env) |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
locomotive/steam/middlewares/favicon.rb b/lib/locomotive/steam/middlewares/favicon.rb
+5
-2
| @@ | @@ -1,10 +1,13 @@ |
| module Locomotive::Steam | |
| module Middlewares | |
| - | class Favicon < Base |
| + | class Favicon < Struct.new(:app) |
| + | |
| + | include Helpers |
| def call(env) | |
| if env['PATH_INFO'] == '/favicon.ico' | |
| + | log 'Default and empty Favicon rendered' |
| [200, { 'Content-Type' => 'image/vnd.microsoft.icon' }, ['']] | |
| else | |
| app.call(env) | |
| @@ | @@ -14,4 +17,4 @@ module Locomotive::Steam |
| end | |
| end | |
| - | end |
| \ No newline at end of file | |
| + | end |
locomotive/steam/middlewares/helpers.rb b/lib/locomotive/steam/middlewares/helpers.rb
+28
-0
| @@ | @@ -0,0 +1,28 @@ |
| + | module Locomotive::Steam |
| + | module Middlewares |
| + | |
| + | module Helpers |
| + | |
| + | def html? |
| + | ['text/html', 'application/x-www-form-urlencoded'].include?(self.request.media_type) && |
| + | !self.request.xhr? && |
| + | !self.json? |
| + | end |
| + | |
| + | def json? |
| + | self.request.content_type == 'application/json' || File.extname(self.request.path) == '.json' |
| + | end |
| + | |
| + | def redirect_to(location, type = 301) |
| + | self.log "Redirected to #{location}" |
| + | [type, { 'Content-Type' => 'text/html', 'Location' => location }, []] |
| + | end |
| + | |
| + | def log(msg) |
| + | Locomotive::Common::Logger.info msg |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
locomotive/steam/middlewares/locale.rb b/lib/locomotive/steam/middlewares/locale.rb
+16
-16
| @@ | @@ -7,33 +7,33 @@ module Locomotive::Steam |
| # /fr/ => locale = :fr | |
| # /index => locale = :en (default one) | |
| # | |
| - | class Locale < Base |
| + | class Locale < ThreadSafe |
| - | def _call(env) |
| - | super |
| + | include Helpers |
| - | self.set_locale!(env) |
| - | |
| - | app.call(env) |
| + | def _call |
| + | set_locale |
| end | |
| protected | |
| - | def set_locale!(env) |
| - | locale = site.default_locale |
| + | def set_locale |
| + | _locale = site.default_locale |
| + | _path = path |
| - | if self.path =~ /^(#{self.site.locales.join('|')})+(\/|$)/ |
| - | locale = $1 |
| - | self.path = self.path.gsub($1 + $2, '') |
| - | self.path = 'index' if self.path.blank? |
| + | if _path =~ /^(#{site.locales.join('|')})+(\/|$)/ |
| + | _locale = $1 |
| + | _path = _path.gsub($1 + $2, '') |
| + | _path = 'index' if _path.blank? |
| end | |
| - | ::I18n.locale = locale |
| + | log "Detecting locale #{_locale.upcase}" |
| - | self.log "Detecting locale #{locale.upcase}" |
| + | services.current_locale = _locale |
| + | services.repositories.current_locale = _locale |
| - | env['steam.locale'] = locale |
| - | env['steam.path'] = self.path |
| + | env['steam.locale'] = _locale |
| + | env['steam.path'] = _path |
| end | |
| end | |
locomotive/steam/middlewares/logging.rb b/lib/locomotive/steam/middlewares/logging.rb
+4
-2
| @@ | @@ -3,7 +3,9 @@ module Locomotive::Steam |
| # Track the request into the current logger | |
| # | |
| - | class Logging < Base |
| + | class Logging < Struct.new(:app) |
| + | |
| + | include Helpers |
| def call(env) | |
| now = Time.now | |
| @@ | @@ -29,4 +31,4 @@ module Locomotive::Steam |
| end | |
| end | |
| - | end |
| \ No newline at end of file | |
| + | end |
locomotive/steam/middlewares/page.rb b/lib/locomotive/steam/middlewares/page.rb
+41
-43
| @@ | @@ -1,65 +1,63 @@ |
| module Locomotive::Steam | |
| module Middlewares | |
| - | # Sanitize the path from the previous middleware in order |
| - | # to make it work for the renderer. |
| + | # Retrieve a page from the path and the locale previously |
| + | # fetched from the request. |
| # | |
| - | class Page < Base |
| + | class Page < ThreadSafe |
| - | def _call(env) |
| - | super |
| - | set_page!(env) |
| - | app.call(env) |
| - | end |
| - | |
| - | protected |
| + | include Helpers |
| - | def set_page!(env) |
| - | page = fetch_page env['steam.locale'] |
| - | if page |
| + | def _call |
| + | if page = fetch_page |
| log "Found page \"#{page.title}\" [#{page.fullpath}]" | |
| end | |
| env['steam.page'] = page | |
| end | |
| - | def fetch_page locale |
| - | decorated(locale) do |
| - | Locomotive::Models[:pages].current_locale = locale |
| - | Locomotive::Models[:pages].matching_paths(path_combinations(path)).tap do |pages| |
| - | if pages.size > 1 |
| - | self.log "Found multiple pages: #{pages.all.collect(&:title).join(', ')}" |
| - | end |
| - | end.first |
| + | protected |
| + | |
| + | def fetch_page |
| + | if (pages = services.page_finder.find(path)).size > 1 |
| + | titles = pages.map { |p| p.attributes[:title][repository.current_locale] } |
| + | self.log "Found multiple pages: #{titles.join(', ')}" |
| end | |
| - | end |
| - | def decorated(locale) |
| - | entity = yield |
| - | unless entity.nil? |
| - | # Locomotive::Steam::Decorators::PageDecorator.new( |
| - | # Locomotive::Decorators::I18nDecorator.new(entity, locale)) |
| + | if page = pages.first |
| + | Locomotive::Steam::Decorators::I18nDecorator.new(page, page.localized_attributes, locale, default_locale) |
| + | else |
| + | nil |
| end | |
| - | end |
| - | def path_combinations(path) |
| - | self._path_combinations(path.split('/')) |
| + | # if page = services.page_finder.find(path) |
| + | # puts page.inspect |
| + | # Locomotive::Steam::Decorators::I18nDecorator.new(page, page.localized_attributes, locale, site.default_locale) |
| + | # else |
| + | # nil |
| + | # end |
| + | |
| + | # decorated(locale) do |
| + | # Locomotive::Models[:pages].current_locale = locale |
| + | # Locomotive::Models[:pages].matching_paths(path_combinations(path)).tap do |pages| |
| + | # if pages.size > 1 |
| + | # self.log "Found multiple pages: #{pages.all.collect(&:title).join(', ')}" |
| + | # end |
| + | # end.first |
| + | # end |
| end | |
| - | def _path_combinations(segments, can_include_template = true) |
| - | return nil if segments.empty? |
| - | segment = segments.shift |
| + | # def repository |
| + | # services.repositories.page |
| + | # end |
| - | (can_include_template ? [segment, '*'] : [segment]).map do |_segment| |
| - | if (_combinations = _path_combinations(segments.clone, can_include_template && _segment != '*')) |
| - | [*_combinations].map do |_combination| |
| - | File.join(_segment, _combination) |
| - | end |
| - | else |
| - | [_segment] |
| - | end |
| - | end.flatten |
| - | end |
| + | # def decorated(locale) |
| + | # entity = yield |
| + | # unless entity.nil? |
| + | # # Locomotive::Steam::Decorators::PageDecorator.new( |
| + | # # Locomotive::Decorators::I18nDecorator.new(entity, locale)) |
| + | # end |
| + | # end |
| end | |
locomotive/steam/middlewares/path.rb b/lib/locomotive/steam/middlewares/path.rb
+4
-7
| @@ | @@ -4,13 +4,10 @@ module Locomotive::Steam |
| # Sanitize the path from the previous middleware in order | |
| # to make it work for the renderer. | |
| # | |
| - | class Path < Base |
| - | |
| - | def _call(env) |
| - | super |
| - | |
| - | self.set_path!(env) |
| + | class Path < Struct.new(:app) |
| + | def call(env) |
| + | set_path!(env) |
| app.call(env) | |
| end | |
| @@ | @@ -31,4 +28,4 @@ module Locomotive::Steam |
| end | |
| end | |
| - | end |
| \ No newline at end of file | |
| + | end |
locomotive/steam/middlewares/renderer.rb b/lib/locomotive/steam/middlewares/renderer.rb
+28
-15
| @@ | @@ -1,25 +1,38 @@ |
| module Locomotive::Steam | |
| module Middlewares | |
| - | class Renderer < Base |
| + | class Renderer |
| - | def _call(env) |
| - | super |
| + | def call(env) |
| + | response = nil |
| - | if page |
| - | if page.redirect? |
| - | redirect_to(page.redirect_url, page.redirect_type) |
| - | else |
| - | type = page.response_type || 'text/html' |
| - | html = render_page |
| + | # time = Benchmark.realtime do |
| + | # puts "[Rendered] TODO" |
| + | # self.set_accessors(env) |
| + | response = [200, { 'Content-Type' => 'text/html' }, ['TODO']] |
| + | # end |
| - | log 'Rendered liquid page template' |
| + | # puts "[Benchmark][Renderer] Time elapsed #{time*1000} milliseconds" |
| + | response |
| - | [200, { 'Content-Type' => type }, [html]] |
| - | end |
| - | else |
| - | [404, { 'Content-Type' => 'text/html' }, [render_404]] |
| - | end |
| + | # if page |
| + | # if page.redirect? |
| + | # redirect_to(page.redirect_url, page.redirect_type) |
| + | # else |
| + | # type = page.response_type || 'text/html' |
| + | # html = render_page |
| + | |
| + | # log 'Rendered liquid page template' |
| + | |
| + | # [200, { 'Content-Type' => type }, [html]] |
| + | # end |
| + | # else |
| + | # [404, { 'Content-Type' => 'text/html' }, [render_404]] |
| + | # end |
| + | end |
| + | |
| + | def self.call(env) |
| + | raise 'TODO' |
| end | |
| protected | |
locomotive/steam/middlewares/site.rb b/lib/locomotive/steam/middlewares/site.rb
+16
-0
| @@ | @@ -0,0 +1,16 @@ |
| + | module Locomotive::Steam |
| + | module Middlewares |
| + | |
| + | # Fetch a site using the site_finder service |
| + | # |
| + | class Site < ThreadSafe |
| + | |
| + | def _call |
| + | site = services.site_finder.find |
| + | env['steam.site'] = services.repositories.current_site = site |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
locomotive/steam/middlewares/stack.rb b/lib/locomotive/steam/middlewares/stack.rb
+55
-33
| @@ | @@ -15,61 +15,83 @@ module Locomotive |
| def create | |
| options = @options | |
| + | # _self = self |
| Rack::Builder.new do | |
| use Rack::Lint | |
| - | use Middlewares::Favicon |
| + | use Steam::Middlewares::Favicon |
| - | if options[:serve_assets] |
| - | use Middlewares::StaticAssets, { |
| - | urls: ['/images', '/fonts', '/samples', '/media'] |
| - | } |
| - | use Middlewares::DynamicAssets |
| - | end |
| + | # if options[:serve_assets] |
| + | # use Steam::Middlewares::StaticAssets, { |
| + | # urls: ['/images', '/fonts', '/samples', '/media'] |
| + | # } |
| + | # use Steam::Middlewares::DynamicAssets |
| + | # end |
| - | use Rack::Csrf, |
| - | field: 'authenticity_token', |
| - | skip_if: -> (request) { |
| - | !(request.post? && request.params[:content_type_slug].present?) |
| - | } |
| + | # use Rack::Csrf, |
| + | # field: 'authenticity_token', |
| + | # skip_if: -> (request) { |
| + | # !(request.post? && request.params[:content_type_slug].present?) |
| + | # } |
| - | use ::Dragonfly::Middleware, :steam |
| + | # use ::Dragonfly::Middleware, :steam |
| - | use Rack::Session::Moneta, options[:moneta] |
| + | # use Rack::Session::Moneta, options[:moneta] |
| - | use_steam_middlewares(self) |
| + | # _self.send(:use_steam_middlewares, builder) |
| - | run Middlewares::Renderer.new |
| + | use Middlewares::Logging |
| + | use Middlewares::Path |
| + | |
| + | # foo = proc do |env| |
| + | # puts "[EndPoint] finishing here..." |
| + | # [ 200, {'Content-Type' => 'text/plain'}, ["b"] ] |
| + | # end |
| + | |
| + | # run foo |
| + | |
| + | run Steam::Middlewares::Renderer.new |
| end | |
| end | |
| protected | |
| def use_steam_middlewares(builder) | |
| - | builder.instance_eval do |
| - | use Middlewares::Logging |
| + | # builder.use Middlewares::Logging |
| + | # builder.use Middlewares::Site |
| + | # builder.use Middlewares::Path |
| - | use Middlewares::EntrySubmission |
| + | # builder.run Steam::Middlewares::Renderer.new |
| - | use Middlewares::Path |
| - | use Middlewares::Locale |
| - | use Middlewares::Timezone |
| + | # builder.instance_eval do |
| + | # use Middlewares::Logging |
| - | use Middlewares::Page |
| - | use Middlewares::TemplatizedPage |
| - | end |
| - | end |
| + | # use Middlewares::Site |
| + | |
| + | # # use Middlewares::EntrySubmission |
| - | def prepare_options(options) |
| - | { |
| - | serve_assets: false, |
| - | moneta: { |
| - | store: Moneta.new(:Memory, :expires => true) |
| - | } |
| - | }.merge(options) |
| + | # use Middlewares::Path |
| + | |
| + | # nil |
| + | # # use Middlewares::Locale |
| + | # # use Middlewares::Timezone |
| + | |
| + | # # use Middlewares::Page |
| + | # # use Middlewares::TemplatizedPage |
| + | # end |
| + | # nil |
| end | |
| + | # def prepare_options(options) |
| + | # { |
| + | # serve_assets: false, |
| + | # moneta: { |
| + | # store: Moneta.new(:Memory, expires: true) |
| + | # } |
| + | # }.merge(options) |
| + | # end |
| + | |
| end | |
| end | |
locomotive/steam/middlewares/threadsafe.rb b/lib/locomotive/steam/middlewares/threadsafe.rb
+57
-0
| @@ | @@ -0,0 +1,57 @@ |
| + | module Locomotive::Steam::Middlewares |
| + | |
| + | class ThreadSafe < Struct.new(:app) |
| + | |
| + | attr_accessor :env |
| + | |
| + | def call(env) |
| + | threadsafed = dup |
| + | threadsafed.env = env |
| + | |
| + | # time = Benchmark.realtime do |
| + | threadsafed._call # thread-safe purpose |
| + | # end |
| + | |
| + | # puts "[Benchmark][#{self.class.name}] Time elapsed #{time*1000} milliseconds" |
| + | |
| + | threadsafed.next |
| + | end |
| + | |
| + | def next |
| + | # avoid to be called twice |
| + | @next_response || (@next_response = app.call(env)) |
| + | end |
| + | |
| + | #= Shortcuts = |
| + | |
| + | def services |
| + | @services ||= env.fetch('steam.services') |
| + | end |
| + | |
| + | def request |
| + | @request ||= env.fetch('steam.request') |
| + | end |
| + | |
| + | def site |
| + | @site ||= env.fetch('steam.site') |
| + | end |
| + | |
| + | def path |
| + | @path ||= env.fetch('steam.path') |
| + | end |
| + | |
| + | def locale |
| + | @locale ||= env.fetch('steam.locale') |
| + | end |
| + | |
| + | def default_locale |
| + | site.default_locale |
| + | end |
| + | |
| + | def params |
| + | @params ||= self.request.params #.deep_symbolize_keys |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
locomotive/steam/middlewares/timezone.rb b/lib/locomotive/steam/middlewares/timezone.rb
+12
-7
| @@ | @@ -3,16 +3,21 @@ module Locomotive::Steam |
| # Set the timezone according to the settings of the site | |
| # | |
| - | class Timezone < Base |
| + | class Timezone < ThreadSafe |
| - | def _call(env) |
| - | super |
| + | include Helpers |
| - | Time.use_zone(site.try(:timezone) || 'UTC') do |
| - | app.call(env) |
| - | end |
| + | def _call |
| + | timezone = site.try(:timezone) || 'UTC' |
| + | |
| + | log "Timezone: #{timezone.inspect}" |
| + | |
| + | # DEBUG |
| + | # Time.use_zone(timezone) do |
| + | self.next |
| + | # end |
| end | |
| end | |
| end | |
| - | end |
| \ No newline at end of file | |
| + | end |
locomotive/steam/repositories.rb b/lib/locomotive/steam/repositories.rb
+12
-10
| @@ | @@ -1,3 +1,4 @@ |
| + | Dir[File.join(File.dirname(__FILE__), 'repositories', 'filesystem', '*.rb')].each { |lib| require lib } |
| Dir[File.join(File.dirname(__FILE__), 'repositories', '*.rb')].each { |lib| require lib } | |
| require 'morphine' | |
| @@ | @@ -6,40 +7,41 @@ module Locomotive |
| module Steam | |
| module Repositories | |
| - | def self.build_instance(site = nil) |
| - | Registered.new(site) |
| + | def self.build_instance(site = nil, current_locale = nil) |
| + | Instance.new(site, current_locale) |
| end | |
| - | class Registered < Struct.new(:current_site) |
| + | class Instance < Struct.new(:current_site, :current_locale) |
| include Morphine | |
| register :site do | |
| - | Repositories::Site.new |
| + | Steam::Repositories::Filesystem::Site.new |
| end | |
| register :page do | |
| - | Repositories::Page.new(current_site) |
| + | Steam::Repositories::Filesystem::Page.new(current_site, current_locale) |
| + | # Steam::Repositories::Page.new(current_site, current_locale) |
| end | |
| register :content_type do | |
| - | Repositories::ContentType.new(current_site) |
| + | Steam::Repositories::ContentType.new(current_site) |
| end | |
| register :content_entry do | |
| - | Repositories::ContentEntry.new(current_site) |
| + | Steam::Repositories::ContentEntry.new(current_site) |
| end | |
| register :snippet do | |
| - | Repositories::Snippet.new(current_site) |
| + | Steam::Repositories::Snippet.new(current_site) |
| end | |
| register :theme_asset do | |
| - | Repositories::ThemeAsset.new(current_site) |
| + | Steam::Repositories::ThemeAsset.new(current_site) |
| end | |
| register :translation do | |
| - | Repositories::Translation.new(current_site) |
| + | Steam::Repositories::Translation.new(current_site) |
| end | |
| end | |
locomotive/steam/repositories/filesystem/memory_adapter.rb b/lib/locomotive/steam/repositories/filesystem/memory_adapter.rb
+1
-0
| @@ | @@ -0,0 +1 @@ |
| + | Dir[File.join(File.dirname(__FILE__), 'memory_adapter', '*.rb')].each { |lib| require lib } |
locomotive/steam/repositories/filesystem/memory_adapter/condition.rb b/lib/locomotive/steam/repositories/filesystem/memory_adapter/condition.rb
+101
-0
| @@ | @@ -0,0 +1,101 @@ |
| + | module Locomotive |
| + | module Steam |
| + | module Repositories |
| + | module Filesystem |
| + | module MemoryAdapter |
| + | class Condition |
| + | |
| + | class UnsupportedOperator < StandardError; end |
| + | |
| + | OPERATORS = %i(== eq ne neq matches gt gte lt lte size all in nin).freeze |
| + | |
| + | attr_reader :field, :operator, :value |
| + | |
| + | def initialize(operator_and_field, value, locale) |
| + | @locale = locale.to_sym |
| + | @operator_and_field, @value = operator_and_field, value |
| + | @operator, @field = :==, nil |
| + | |
| + | decode_operator_and_field! |
| + | end |
| + | |
| + | def matches?(entry) |
| + | entry_value = entry_value(entry) |
| + | |
| + | adapt_operator!(entry_value) |
| + | case @operator |
| + | when :== then entry_value == @value |
| + | when :eq then entry_value == @value |
| + | when :ne then entry_value != @value |
| + | when :neq then entry_value != @value |
| + | when :matches then @value =~ entry_value |
| + | when :gt then entry_value > @value |
| + | when :gte then entry_value >= @value |
| + | when :lt then entry_value < @value |
| + | when :lte then entry_value <= @value |
| + | when :size then entry_value.size == @value |
| + | when :all then array_contains?([*@value], entry_value) |
| + | when :in, :nin then value_is_in_entry_value?(entry_value) |
| + | else |
| + | raise UnknownConditionInScope.new("#{@operator} is unknown or not implemented.") |
| + | end |
| + | end |
| + | |
| + | def to_s |
| + | "#{field} #{operator} #{@value.to_s}" |
| + | end |
| + | |
| + | protected |
| + | |
| + | def entry_value(entry) |
| + | case (value = entry.send(@field)) |
| + | when Hash |
| + | value.fetch(@locale) { nil } |
| + | else |
| + | value |
| + | end |
| + | end |
| + | |
| + | def decode_operator_and_field! |
| + | if match = @operator_and_field.match(/^(?<field>[a-z0-9_-]+)\.(?<operator>.*)$/) |
| + | @field = match[:field].to_sym |
| + | @operator = match[:operator].to_sym |
| + | check_operator! |
| + | end |
| + | |
| + | @operator = :matches if @value.is_a?(Regexp) |
| + | end |
| + | |
| + | def adapt_operator!(value) |
| + | case value |
| + | when Array |
| + | @operator = :in if @operator == :== |
| + | end |
| + | end |
| + | |
| + | def value_is_in_entry_value?(value) |
| + | _matches = if value.is_a?(Array) |
| + | array_contains?([*value], [*@value]) |
| + | else |
| + | [*@value].include?(value) |
| + | end |
| + | @operator == :in ? _matches : !_matches |
| + | end |
| + | |
| + | private |
| + | |
| + | def check_operator! |
| + | raise UnsupportedOperator.new unless OPERATORS.include?(@operator) |
| + | end |
| + | |
| + | def array_contains?(source, target) |
| + | source & target == target |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
| + | end |
| + | end |
locomotive/steam/repositories/filesystem/memory_adapter/query.rb b/lib/locomotive/steam/repositories/filesystem/memory_adapter/query.rb
+110
-0
| @@ | @@ -0,0 +1,110 @@ |
| + | require 'forwardable' |
| + | |
| + | module Locomotive |
| + | module Steam |
| + | module Repositories |
| + | module Filesystem |
| + | module MemoryAdapter |
| + | |
| + | class Query |
| + | |
| + | include Enumerable |
| + | extend Forwardable |
| + | |
| + | def_delegators :all, :each, :to_s, :to_a, :empty?, :size |
| + | |
| + | alias :length :size |
| + | alias :count :size |
| + | |
| + | attr_reader :conditions |
| + | |
| + | def initialize(dataset, locale=nil, &block) |
| + | @dataset = dataset |
| + | @conditions = [] |
| + | @sorting = nil |
| + | @limit = nil |
| + | @offset = 0 |
| + | @locale = locale |
| + | instance_eval(&block) if block_given? |
| + | end |
| + | |
| + | def where(conditions = {}) |
| + | @conditions += conditions.map { |name, value| Condition.new(name, value, @locale) } |
| + | self |
| + | end |
| + | |
| + | def +(query) |
| + | @conditions += query.conditions |
| + | self |
| + | end |
| + | |
| + | def order_by(order_string) |
| + | @sorting = order_string.downcase.split.map(&:to_sym) unless order_string.empty? |
| + | self |
| + | end |
| + | |
| + | def limit(num) |
| + | @limit = num |
| + | self |
| + | end |
| + | |
| + | def offset(num) |
| + | @offset = num |
| + | self |
| + | end |
| + | |
| + | def ==(other) |
| + | if other.kind_of? Array |
| + | all == other |
| + | else |
| + | super |
| + | end |
| + | end |
| + | |
| + | def all |
| + | limited sorted(filtered) |
| + | end |
| + | |
| + | def sorted(entries) |
| + | return entries if @sorting.nil? |
| + | |
| + | name, direction = @sorting.first, (@sorting.last || :asc) |
| + | if direction == :asc |
| + | entries.sort { |a, b| a.send(name) <=> b.send(name) } |
| + | else |
| + | entries.sort { |a, b| b.send(name) <=> a.send(name) } |
| + | end |
| + | end |
| + | |
| + | def limited(entries) |
| + | return [] if @limit == 0 |
| + | return entries if @offset == 0 && @limit.nil? |
| + | |
| + | subentries = entries.drop(@offset || 0) |
| + | if @limit.kind_of? Integer |
| + | subentries.take(@limit) |
| + | else |
| + | subentries |
| + | end |
| + | end |
| + | |
| + | def filtered |
| + | @dataset.to_a.dup.find_all do |entry| |
| + | accepted = true |
| + | |
| + | @conditions.each do |_condition| |
| + | unless _condition.matches?(entry) |
| + | accepted = false |
| + | break # no to go further |
| + | end |
| + | end |
| + | accepted |
| + | end |
| + | end # filtered |
| + | |
| + | end |
| + | end |
| + | end |
| + | end |
| + | end |
| + | end |
locomotive/steam/repositories/filesystem/memory_adapter/yaml_loader.rb b/lib/locomotive/steam/repositories/filesystem/memory_adapter/yaml_loader.rb
+93
-0
| @@ | @@ -0,0 +1,93 @@ |
| + | module Locomotive |
| + | module Steam |
| + | module Repositories |
| + | module Filesystem |
| + | module MemoryAdapter |
| + | |
| + | class YAMLLoader < Struct.new(:root_path) |
| + | |
| + | attr_accessor :default_locale |
| + | |
| + | TEMPLATE_EXTENSIONS = %w(liquid haml) |
| + | |
| + | @@cache = {} |
| + | |
| + | def self.instance(path = nil) |
| + | @@instance ||= self.new(path) |
| + | end |
| + | |
| + | def simple(path) |
| + | @@cache[path] || load(File.join(root_path, path)) |
| + | end |
| + | |
| + | def tree(path) |
| + | @@cache[path] || load_tree(File.join(root_path, path)).values |
| + | end |
| + | |
| + | private |
| + | |
| + | def load(path, frontmatter = false) |
| + | yaml = File.open(path).read.force_encoding('utf-8') |
| + | |
| + | if frontmatter |
| + | yaml =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)(.*)/m |
| + | yaml = $1 |
| + | end |
| + | |
| + | raw_data = YAML.load(yaml) |
| + | HashConverter.to_sym(raw_data) |
| + | end |
| + | |
| + | def load_tree(path) |
| + | {}.tap do |hash| |
| + | Dir.glob(File.join(path, '**', '*')).each do |filepath| |
| + | next unless filepath =~ /\.(#{TEMPLATE_EXTENSIONS.join('|')})$/ |
| + | |
| + | relative_path = filepath.gsub(path, '').gsub(/^\//, '') |
| + | |
| + | fullpath, locale = relative_path.split('.')[0..1] |
| + | locale = default_locale if TEMPLATE_EXTENSIONS.include?(locale) |
| + | |
| + | if leaf = hash[fullpath] |
| + | update_leaf(leaf, filepath, fullpath, locale.to_sym) |
| + | else |
| + | leaf = get_new_leaf(filepath, fullpath, locale.to_sym) |
| + | end |
| + | |
| + | hash[fullpath] = leaf |
| + | end |
| + | end |
| + | end |
| + | |
| + | def get_new_leaf(filepath, fullpath, locale) |
| + | slug = fullpath.split('/').last |
| + | attributes = load(filepath, true) |
| + | |
| + | { |
| + | title: { locale => attributes.delete(:title) || (default_locale == locale ? slug.humanize : nil) }, |
| + | slug: { locale => attributes.delete(:slug) || slug }, |
| + | editable_elements: { locale => attributes.delete(:editable_elements) }, |
| + | template_path: { locale => filepath }, |
| + | _fullpath: fullpath |
| + | }.merge(attributes) |
| + | end |
| + | |
| + | def update_leaf(leaf, filepath, fullpath, locale) |
| + | slug = fullpath.split('/').last |
| + | attributes = load(filepath, true) |
| + | |
| + | leaf[:title][locale] = attributes.delete(:title) || slug.humanize |
| + | leaf[:slug][locale] = attributes.delete(:slug) || slug |
| + | leaf[:editable_elements][locale] = attributes.delete(:editable_elements) |
| + | leaf[:template_path][locale] = filepath |
| + | |
| + | leaf.merge!(attributes) |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
| + | end |
| + | end |
locomotive/steam/repositories/filesystem/models/page.rb b/lib/locomotive/steam/repositories/filesystem/models/page.rb
+49
-0
| @@ | @@ -0,0 +1,49 @@ |
| + | module Locomotive |
| + | module Steam |
| + | module Repositories |
| + | module Filesystem |
| + | module Models |
| + | |
| + | class Page < Struct.new(:attributes) |
| + | |
| + | def initialize(attributes) |
| + | super({ |
| + | listed: true, |
| + | published: false, |
| + | fullpath: {}, |
| + | content_type: nil, |
| + | position: 100 |
| + | }.merge(attributes)) |
| + | end |
| + | |
| + | def method_missing(name, *args, &block) |
| + | if attributes.include?(name) |
| + | attributes[name.to_sym] # getter |
| + | else |
| + | super |
| + | end |
| + | end |
| + | |
| + | def templatized? |
| + | !!content_type |
| + | end |
| + | |
| + | def localized_attributes |
| + | self.class.localized_attributes |
| + | end |
| + | |
| + | def self.localized_attributes |
| + | [:title, :slug, :permalink, :template_path, :fullpath, :seo, :meta_description, :meta_keywords] |
| + | end |
| + | |
| + | def to_liquid |
| + | Steam::Liquids::Drops::Page.new(self, localized_attributes) |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
| + | end |
| + | end |
locomotive/steam/repositories/filesystem/models/site.rb b/lib/locomotive/steam/repositories/filesystem/models/site.rb
+41
-0
| @@ | @@ -0,0 +1,41 @@ |
| + | module Locomotive |
| + | module Steam |
| + | module Repositories |
| + | module Filesystem |
| + | module Models |
| + | |
| + | class Site < Struct.new(:attributes) |
| + | |
| + | attr_accessor :root_path |
| + | |
| + | def method_missing(name, *args, &block) |
| + | if attributes.include?(name) |
| + | attributes[name.to_sym] # getter |
| + | else |
| + | super |
| + | end |
| + | end |
| + | |
| + | def localized_attributes |
| + | [:seo, :meta_description, :meta_keywords] |
| + | end |
| + | |
| + | def default_locale |
| + | self.locales.try(:first) || :en |
| + | end |
| + | |
| + | def locales |
| + | attributes[:locales].map(&:to_sym) |
| + | end |
| + | |
| + | def to_liquid |
| + | Steam::Liquids::Drops::Site.new(self, localized_attributes) |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
| + | end |
| + | end |
locomotive/steam/repositories/filesystem/page.rb b/lib/locomotive/steam/repositories/filesystem/page.rb
+87
-0
| @@ | @@ -0,0 +1,87 @@ |
| + | require_relative 'models/page' |
| + | require_relative 'sanitizers/page' |
| + | |
| + | module Locomotive |
| + | module Steam |
| + | module Repositories |
| + | module Filesystem |
| + | |
| + | class Page < Struct.new(:site, :current_locale) |
| + | |
| + | def all(conditions = {}) |
| + | raise 'TODO' |
| + | # site.pages.ordered_pages(conditions) |
| + | end |
| + | |
| + | def by_handle(handle) |
| + | raise 'TODO' |
| + | # site.pages.where(handle: handle).first |
| + | end |
| + | |
| + | def by_fullpath(path) |
| + | MemoryAdapter::Query.new(collection, current_locale) do |
| + | where(fullpath: path) |
| + | end.first |
| + | end |
| + | |
| + | def matching_fullpath(list) |
| + | MemoryAdapter::Query.new(collection, current_locale) do |
| + | where('fullpath.in' => list) |
| + | end.all |
| + | end |
| + | |
| + | def template_for(entry, handle = nil) |
| + | # criteria = site.pages.where(target_klass_name: entry.class.to_s, templatized: true) |
| + | # criteria = criteria.where(handle: handle) if handle |
| + | # criteria.first.tap do |page| |
| + | # page.content_entry = entry if page |
| + | # end |
| + | end |
| + | |
| + | def root |
| + | # site.pages.root.first |
| + | end |
| + | |
| + | def parent_of(page) |
| + | # page.parent |
| + | end |
| + | |
| + | def ancestors_of(page) |
| + | # page.ancestors_and_self |
| + | end |
| + | |
| + | def children_of(page) |
| + | # page.children |
| + | end |
| + | |
| + | def editable_elements_of(page) |
| + | # page.editable_elements |
| + | end |
| + | |
| + | def editable_element_for(page, block, slug) |
| + | # page.editable_elements.where(block: block, slug: slug).first |
| + | end |
| + | |
| + | private |
| + | |
| + | def collection |
| + | return @collection if @collection |
| + | |
| + | loader = MemoryAdapter::YAMLLoader.instance |
| + | list = loader.tree('app/views/pages') |
| + | |
| + | @collection = list.map do |attributes| |
| + | Models::Page.new(attributes) |
| + | end |
| + | |
| + | Sanitizers::Page.new(@collection, site.locales).apply |
| + | |
| + | @collection |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
| + | end |
locomotive/steam/repositories/filesystem/sanitizers/page.rb b/lib/locomotive/steam/repositories/filesystem/sanitizers/page.rb
+88
-0
| @@ | @@ -0,0 +1,88 @@ |
| + | module Locomotive |
| + | module Steam |
| + | module Repositories |
| + | module Filesystem |
| + | module Sanitizers |
| + | |
| + | class Page < Struct.new(:collection, :locales) |
| + | |
| + | def initialize(collection, locales) |
| + | super |
| + | |
| + | @content_types = {} |
| + | @localized = {} |
| + | locales.each { |locale| @localized[locale] = {} } |
| + | end |
| + | |
| + | def apply |
| + | sorted_collection.each do |page| |
| + | locales.each do |locale| |
| + | modify_if_templatized(page, locale) |
| + | set_fullpath_for(page, locale) |
| + | end |
| + | end |
| + | end |
| + | |
| + | def modify_if_templatized(page, locale) |
| + | content_type = fetch_content_type(parent_fullpath(page)) |
| + | |
| + | if page.templatized? && content_type.nil? |
| + | # change the slug of a templatized page |
| + | page.attributes[:slug][locale] = 'content_type_template' |
| + | |
| + | # make sure its children will have its content type |
| + | set_content_type(page._fullpath, page.content_type) |
| + | else |
| + | page.attributes[:content_type] = content_type |
| + | end |
| + | end |
| + | |
| + | def set_fullpath_for(page, locale) |
| + | slug = fullpath = page.attributes[:slug][locale].try(:dasherize) |
| + | |
| + | return if slug.blank? |
| + | |
| + | if depth(page) > 1 |
| + | base = parent_fullpath(page) |
| + | fullpath = (fetch_localized_fullpath(base, locale) || base) + '/' + slug |
| + | end |
| + | |
| + | set_localized_fullpath(page._fullpath, fullpath, locale) |
| + | page.attributes[:fullpath][locale] = fullpath |
| + | end |
| + | |
| + | def depth(page) |
| + | page._fullpath.split('/').size |
| + | end |
| + | |
| + | def sorted_collection |
| + | collection.sort { |a, b| depth(a) <=> depth(b) } |
| + | end |
| + | |
| + | def parent_fullpath(page) |
| + | page._fullpath.split('/')[0..-2].join('/') |
| + | end |
| + | |
| + | def fetch_content_type(fullpath) |
| + | @content_types[fullpath] |
| + | end |
| + | |
| + | def set_content_type(fullpath, value) |
| + | @content_types[fullpath] = value |
| + | end |
| + | |
| + | def fetch_localized_fullpath(fullpath, locale) |
| + | @localized[locale][fullpath] |
| + | end |
| + | |
| + | def set_localized_fullpath(fullpath, value, locale) |
| + | @localized[locale][fullpath] = value |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
| + | end |
| + | end |
locomotive/steam/repositories/filesystem/site.rb b/lib/locomotive/steam/repositories/filesystem/site.rb
+24
-0
| @@ | @@ -0,0 +1,24 @@ |
| + | require_relative 'models/site' |
| + | |
| + | module Locomotive |
| + | module Steam |
| + | module Repositories |
| + | module Filesystem |
| + | |
| + | class Site |
| + | |
| + | def by_host(host, options = {}) |
| + | loader = MemoryAdapter::YAMLLoader.instance(options[:path]) |
| + | attributes = loader.simple('config/site.yml') |
| + | |
| + | Models::Site.new(attributes).tap do |site| |
| + | loader.default_locale = site.default_locale.to_sym |
| + | end |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
| + | end |
locomotive/steam/repositories/page.rb b/lib/locomotive/steam/repositories/page.rb
+1
-1
| @@ | @@ -2,7 +2,7 @@ module Locomotive |
| module Steam | |
| module Repositories | |
| - | class Page < Struct.new(:site) |
| + | class Page < Struct.new(:site, :locale) |
| def all(conditions = {}) | |
| site.pages.ordered_pages(conditions) | |
locomotive/steam/repositories/site.rb b/lib/locomotive/steam/repositories/site.rb
+10
-2
| @@ | @@ -4,14 +4,22 @@ module Locomotive |
| class Site | |
| - | def find_by_host(host) |
| - | raise 'TODO' |
| + | def by_host(host, options = {}) |
| + | raise "TODO (#{options.inspect})" |
| + | |
| + | Locomotive::Site.where(:domains.in => host).first |
| + | |
| + | # Locomotive::Site.first |
| # TODO multilocales | |
| # query(:en) do | |
| # where('domains.in' => host) | |
| # end.first | |
| end | |
| + | def by_handle(handle) |
| + | Locomotive::Site.where(handle: handle).first |
| + | end |
| + | |
| end | |
| end | |
locomotive/steam/server.rb b/lib/locomotive/steam/server.rb
+23
-35
| @@ | @@ -1,53 +1,41 @@ |
| - | require_relative 'core_ext' |
| - | require_relative 'monkey_patches' |
| - | |
| - | require_relative 'repositories' |
| - | require_relative 'services' |
| - | |
| - | require_relative 'liquid' |
| require_relative 'middlewares' | |
| module Locomotive::Steam | |
| class Server | |
| - | attr_reader :app, :options |
| + | attr_reader :options |
| def initialize(options = {}) | |
| - | @options = options |
| - | |
| - | stack = Middlewares::Stack.new(options) |
| - | @app = stack.create |
| - | end |
| - | |
| - | def call(env) |
| - | dup._call(env) # thread-safe purpose |
| + | @options = prepare_options(options) |
| end | |
| - | def _call(env) |
| - | set_request(env) |
| - | |
| - | register_services(env) |
| + | def to_app |
| + | server = self |
| - | # TODO: A middleware will take care of it. |
| - | # fetch_site(env) |
| + | Rack::Builder.new do |
| + | use Rack::Lint |
| - | @app.call(env) |
| - | end |
| + | use Middlewares::Favicon |
| - | protected |
| + | use Middlewares::DefaultEnv, server.options |
| + | use Middlewares::Logging |
| + | use Middlewares::Site |
| + | use Middlewares::Path |
| + | use Middlewares::Locale |
| + | use Middlewares::Timezone |
| + | use Middlewares::Page |
| - | def set_request(env) |
| - | env['steam.request'] = Rack::Request.new(env) |
| + | run Middlewares::Renderer.new |
| + | end |
| end | |
| - | # TODO: move it the right middleware |
| - | # def fetch_site(env) |
| - | # site = env['steam.services'].site_finder.find |
| - | # env['steam.site'] = env['steam.services'].repositories.current_site = site |
| - | # end |
| - | |
| - | def register_services(env) |
| - | env['steam.services'] = Locomotive::Steam::Services.build_instance(env['steam.request'], options) |
| + | def prepare_options(options) |
| + | { |
| + | serve_assets: false, |
| + | moneta: { |
| + | store: Moneta.new(:Memory, expires: true) |
| + | } |
| + | }.merge(options) |
| end | |
| end | |
locomotive/steam/services.rb b/lib/locomotive/steam/services.rb
+22
-14
| @@ | @@ -7,65 +7,73 @@ module Locomotive |
| module Services | |
| def self.build_instance(request = nil, options = {}) | |
| - | Registered.new(request, options) |
| + | Instance.new(request, options) |
| end | |
| - | class Registered < Struct.new(:request, :options) |
| + | class Instance < Struct.new(:request, :options) |
| include Morphine | |
| register :repositories do | |
| - | Repositories.build_instance |
| + | Steam::Repositories.build_instance |
| end | |
| register :site_finder do | |
| - | Services::SiteFinder.new(request, repositories.site, options) |
| + | Steam::Services::SiteFinder.new(repositories.site, request, options) |
| + | end |
| + | |
| + | register :page_finder do |
| + | Steam::Services::PageFinder.new(repositories.page) |
| end | |
| register :url_builder do | |
| - | Services::UrlBuilder.new(current_site, I18n.locale) |
| + | Steam::Services::UrlBuilder.new(current_site, current_locale) |
| end | |
| register :theme_asset_url do | |
| - | Services::ThemeAssetUrl.new(repositories.theme_asset, asset_host, configuration.theme_assets_checksum) |
| + | Steam::Services::ThemeAssetUrl.new(repositories.theme_asset, asset_host, configuration.theme_assets_checksum) |
| end | |
| register :asset_host do | |
| - | Services::AssetHost.new(request, current_site, configuration.asset_host) |
| + | Steam::Services::AssetHost.new(request, current_site, configuration.asset_host) |
| end | |
| register :image_resizer do | |
| - | Services::ImageResizer.new(::Dragonfly.app(:steam), configuration.assets_path) |
| + | Steam::Services::ImageResizer.new(::Dragonfly.app(:steam), configuration.assets_path) |
| end | |
| register :translator do | |
| - | Services::Translator.new(repositories.translation, I18n.locale) |
| + | Steam::Services::Translator.new(repositories.translation, current_locale) |
| end | |
| register :external_api do | |
| - | Services::ExternalAPI.new |
| + | Steam::Services::ExternalAPI.new |
| end | |
| register :csrf_protection do | |
| - | Services::CsrfProtection.new(configuration.csrf_protection, Rack::Csrf.field, Rack::Csrf.token(request.env)) |
| + | Steam::Services::CsrfProtection.new(configuration.csrf_protection, Rack::Csrf.field, Rack::Csrf.token(request.env)) |
| end | |
| register :cache do | |
| - | Services::NoCache.new |
| + | Steam::Services::NoCache.new |
| end | |
| register :markdown do | |
| - | Services::Markdown.new |
| + | Steam::Services::Markdown.new |
| end | |
| register :textile do | |
| - | Services::Textile.new |
| + | Steam::Services::Textile.new |
| end | |
| register :configuration do | |
| Locomotive::Steam.configuration | |
| end | |
| + | register :current_locale do |
| + | I18n.locale |
| + | end |
| + | |
| def current_site | |
| repositories.current_site | |
| end | |
locomotive/steam/services/page_finder.rb b/lib/locomotive/steam/services/page_finder.rb
+38
-0
| @@ | @@ -0,0 +1,38 @@ |
| + | module Locomotive |
| + | module Steam |
| + | module Services |
| + | |
| + | class PageFinder < Struct.new(:repository) |
| + | |
| + | WILDCARD = 'content-type-template' |
| + | |
| + | def find(path) |
| + | repository.matching_fullpath(path_combinations(path)) |
| + | end |
| + | |
| + | private |
| + | |
| + | def path_combinations(path) |
| + | _path_combinations(path.split('/')) |
| + | end |
| + | |
| + | def _path_combinations(segments, can_include_template = true) |
| + | return nil if segments.empty? |
| + | segment = segments.shift |
| + | |
| + | (can_include_template ? [segment, WILDCARD] : [segment]).map do |_segment| |
| + | if (_combinations = _path_combinations(segments.clone, can_include_template && _segment != WILDCARD)) |
| + | [*_combinations].map do |_combination| |
| + | File.join(_segment, _combination) |
| + | end |
| + | else |
| + | [_segment] |
| + | end |
| + | end.flatten |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
locomotive/steam/services/site_finder.rb b/lib/locomotive/steam/services/site_finder.rb
+1
-1
| @@ | @@ -5,7 +5,7 @@ module Locomotive |
| class SiteFinder < Struct.new(:repository, :request, :options) | |
| def find | |
| - | repository.find_by_host(request.host) |
| + | repository.by_host(request.host, options) |
| end | |
| end | |
locomotivecms_steam.gemspec
+1
-1
| @@ | @@ -34,7 +34,7 @@ Gem::Specification.new do |spec| |
| spec.add_dependency 'coffee-script', '~> 2.3.0' | |
| spec.add_dependency 'compass', '~> 1.0.3' | |
| - | spec.add_dependency 'kaminari', '~> 0.16.2' |
| + | spec.add_dependency 'kaminari', '0.16.1' |
| spec.add_dependency 'kramdown', '~> 1.5.0' | |
| spec.add_dependency 'RedCloth', '~> 4.2.9' | |
| spec.add_dependency 'haml', '~> 4.0.6' | |
spec/integration/server/basic_spec.rb
+118
-118
| @@ | @@ -1,169 +1,169 @@ |
| - | # require File.dirname(__FILE__) + '/../integration_helper' |
| - | |
| - | # describe Locomotive::Steam::Server do |
| - | |
| - | # include Rack::Test::Methods |
| + | require File.dirname(__FILE__) + '/../integration_helper' |
| + | |
| + | describe Locomotive::Steam::Server do |
| + | |
| + | include Rack::Test::Methods |
| - | # def app |
| - | # run_server |
| - | # end |
| + | def app |
| + | run_server |
| + | end |
| - | # it 'can render the index page', pending: true do |
| - | # get '/index' |
| - | # last_response.status.should eq(200) |
| - | # end |
| + | it 'can render the index page' do |
| + | get '/index' |
| + | expect(last_response.status).to eq(200) |
| + | end |
| - | # it 'shows the index page', pending: true do |
| - | # get '/index' |
| - | # last_response.body.should =~ /Upcoming events/ |
| - | # end |
| + | # it 'shows the index page' do |
| + | # get '/index' |
| + | # expect(last_response.body).to match(/Upcoming events/) |
| + | # end |
| - | # it 'shows the 404 page', pending: true do |
| - | # get '/void' |
| - | # last_response.status.should eq(404) |
| - | # last_response.body.should =~ /page not found/ |
| - | # end |
| + | # it 'shows the 404 page', pending: true do |
| + | # get '/void' |
| + | # last_response.status.should eq(404) |
| + | # last_response.body.should =~ /page not found/ |
| + | # end |
| - | # it 'shows the 404 page with 200 status code when its called explicitly', pending: true do |
| - | # get '/404' |
| - | # last_response.status.should eq(200) |
| - | # last_response.body.should =~ /page not found/ |
| - | # end |
| + | # it 'shows the 404 page with 200 status code when its called explicitly', pending: true do |
| + | # get '/404' |
| + | # last_response.status.should eq(200) |
| + | # last_response.body.should =~ /page not found/ |
| + | # end |
| - | # it 'shows content', pending: true do |
| - | # get '/about-us/jane-doe' |
| - | # last_response.body.should =~ /Lorem ipsum dolor sit amet/ |
| - | # end |
| + | # it 'shows content', pending: true do |
| + | # get '/about-us/jane-doe' |
| + | # last_response.body.should =~ /Lorem ipsum dolor sit amet/ |
| + | # end |
| - | # it 'shows a content type template', pending: true do |
| - | # get '/songs/song-number-1' |
| - | # last_response.body.should =~ /Song #1/ |
| - | # end |
| + | # it 'shows a content type template', pending: true do |
| + | # get '/songs/song-number-1' |
| + | # last_response.body.should =~ /Song #1/ |
| + | # end |
| - | # it 'renders a page under a templatized one', pending: true do |
| - | # get '/songs/song-number-1/band' |
| - | # last_response.body.should =~ /Song #1/ |
| - | # last_response.body.should =~ /Leader: Eddie/ |
| - | # end |
| + | # it 'renders a page under a templatized one', pending: true do |
| + | # get '/songs/song-number-1/band' |
| + | # last_response.body.should =~ /Song #1/ |
| + | # last_response.body.should =~ /Leader: Eddie/ |
| + | # end |
| - | # it 'translates strings', pending: true do |
| - | # get '/en' |
| - | # last_response.body.should =~ /Powered by/ |
| - | # get '/fr' |
| - | # last_response.body.should =~ /Propulsé par/ |
| - | # get '/nb' |
| - | # last_response.body.should_not =~ /Powered by/ |
| - | # end |
| + | # it 'translates strings', pending: true do |
| + | # get '/en' |
| + | # last_response.body.should =~ /Powered by/ |
| + | # get '/fr' |
| + | # last_response.body.should =~ /Propulsé par/ |
| + | # get '/nb' |
| + | # last_response.body.should_not =~ /Powered by/ |
| + | # end |
| - | # it 'provides translation in scopes', pending: true do |
| - | # get '/' |
| - | # last_response.body.should =~ /scoped_translation=.French./ |
| - | # end |
| + | # it 'provides translation in scopes', pending: true do |
| + | # get '/' |
| + | # last_response.body.should =~ /scoped_translation=.French./ |
| + | # end |
| - | # it 'translates a page with link_to tags inside', pending: true do |
| - | # get '/fr/notre-musique' |
| - | # last_response.body.should =~ /<h3><a href="\/fr\/songs\/song-number-8">Song #8<\/a><\/h3>/ |
| - | # last_response.body.should =~ /Propulsé par/ |
| - | # end |
| + | # it 'translates a page with link_to tags inside', pending: true do |
| + | # get '/fr/notre-musique' |
| + | # last_response.body.should =~ /<h3><a href="\/fr\/songs\/song-number-8">Song #8<\/a><\/h3>/ |
| + | # last_response.body.should =~ /Propulsé par/ |
| + | # end |
| - | # it 'returns all the pages', pending: true do |
| - | # get '/all' |
| - | # last_response.body.should =~ /Home page/ |
| - | # last_response.body.should =~ /<li>Home page<\/li>/ |
| - | # last_response.body.should =~ /<li>John-doe<\/li>/ |
| - | # last_response.body.should =~ /<li>Songs<\/li>/ |
| - | # last_response.body.should =~ /<li>A song template<\/li>/ |
| - | # end |
| + | # it 'returns all the pages', pending: true do |
| + | # get '/all' |
| + | # last_response.body.should =~ /Home page/ |
| + | # last_response.body.should =~ /<li>Home page<\/li>/ |
| + | # last_response.body.should =~ /<li>John-doe<\/li>/ |
| + | # last_response.body.should =~ /<li>Songs<\/li>/ |
| + | # last_response.body.should =~ /<li>A song template<\/li>/ |
| + | # end |
| - | # describe 'snippets', pending: true do |
| + | # describe 'snippets', pending: true do |
| - | # it 'includes a basic snippet' do |
| - | # get '/' |
| - | # last_response.body.should =~ /All photos are licensed under Creative Commons\./ |
| - | # end |
| + | # it 'includes a basic snippet' do |
| + | # get '/' |
| + | # last_response.body.should =~ /All photos are licensed under Creative Commons\./ |
| + | # end |
| - | # it 'includes a snippet whose name is composed of dash' do |
| - | # get '/' |
| - | # last_response.body.should =~ /<p>A complicated one name indeed.<\/p>/ |
| - | # end |
| + | # it 'includes a snippet whose name is composed of dash' do |
| + | # get '/' |
| + | # last_response.body.should =~ /<p>A complicated one name indeed.<\/p>/ |
| + | # end |
| - | # end |
| + | # end |
| - | # describe 'nav', pending: true do |
| + | # describe 'nav', pending: true do |
| - | # subject { get '/all'; last_response.body } |
| + | # subject { get '/all'; last_response.body } |
| - | # it { should_not match(/<nav id="nav">/) } |
| + | # it { should_not match(/<nav id="nav">/) } |
| - | # it { should match(/<li id="about-us-link" class="link first"><a href="\/about-us">About Us<\/a><\/li>/) } |
| + | # it { should match(/<li id="about-us-link" class="link first"><a href="\/about-us">About Us<\/a><\/li>/) } |
| - | # it { should match(/<li id="music-link" class="link"><a href="\/music">Music<\/a><\/li>/) } |
| + | # it { should match(/<li id="music-link" class="link"><a href="\/music">Music<\/a><\/li>/) } |
| - | # it { should match(/<li id="store-link" class="link"><a href="\/store">Store<\/a><\/li>/) } |
| + | # it { should match(/<li id="store-link" class="link"><a href="\/store">Store<\/a><\/li>/) } |
| - | # it { should match(/<li id="contact-link" class="link last"><a href="\/contact">Contact Us<\/a><\/li>/) } |
| + | # it { should match(/<li id="contact-link" class="link last"><a href="\/contact">Contact Us<\/a><\/li>/) } |
| - | # it { should_not match(/<li id="events-link" class="link"><a href="\/events">Events<\/a><\/li>/) } |
| + | # it { should_not match(/<li id="events-link" class="link"><a href="\/events">Events<\/a><\/li>/) } |
| - | # describe 'with wrapper' do |
| + | # describe 'with wrapper' do |
| - | # subject { get '/tags/nav'; last_response.body } |
| + | # subject { get '/tags/nav'; last_response.body } |
| - | # it { should match(/<nav id="nav">/) } |
| + | # it { should match(/<nav id="nav">/) } |
| - | # end |
| + | # end |
| - | # describe 'very deep' do |
| + | # describe 'very deep' do |
| - | # subject { get '/tags/nav_in_deep'; last_response.body } |
| + | # subject { get '/tags/nav_in_deep'; last_response.body } |
| - | # it { should match(/<li id=\"john-doe-link\" class=\"link first last\">/) } |
| + | # it { should match(/<li id=\"john-doe-link\" class=\"link first last\">/) } |
| - | # end |
| + | # end |
| - | # end |
| + | # end |
| - | # describe 'contents with_scope', pending: true do |
| - | # subject { get '/grunge_bands'; last_response.body } |
| + | # describe 'contents with_scope', pending: true do |
| + | # subject { get '/grunge_bands'; last_response.body } |
| - | # it { should match(/Layne/)} |
| - | # it { should_not match(/Peter/) } |
| - | # end |
| + | # it { should match(/Layne/)} |
| + | # it { should_not match(/Peter/) } |
| + | # end |
| - | # describe 'pages with_scope', pending: true do |
| - | # subject { get '/unlisted_pages'; last_response.body } |
| - | # it { subject.should match(/Page to test the nav tag/)} |
| - | # it { should_not match(/About Us/)} |
| - | # end |
| + | # describe 'pages with_scope', pending: true do |
| + | # subject { get '/unlisted_pages'; last_response.body } |
| + | # it { subject.should match(/Page to test the nav tag/)} |
| + | # it { should_not match(/About Us/)} |
| + | # end |
| - | # describe 'theme assets', pending: true do |
| + | # describe 'theme assets', pending: true do |
| - | # subject { get '/all'; last_response.body } |
| + | # subject { get '/all'; last_response.body } |
| - | # it { should match(/<link href="\/stylesheets\/application.css" media="screen" rel="stylesheet" type="text\/css" \/>/) } |
| + | # it { should match(/<link href="\/stylesheets\/application.css" media="screen" rel="stylesheet" type="text\/css" \/>/) } |
| - | # it { should match(/<script src="\/javascripts\/application.js" type='text\/javascript'><\/script>/) } |
| + | # it { should match(/<script src="\/javascripts\/application.js" type='text\/javascript'><\/script>/) } |
| - | # it { should match(/<link rel="alternate" type="application\/atom\+xml" title="A title" href="\/foo\/bar" \/>/) } |
| + | # it { should match(/<link rel="alternate" type="application\/atom\+xml" title="A title" href="\/foo\/bar" \/>/) } |
| - | # end |
| + | # end |
| - | # describe 'session', pending: true do |
| + | # describe 'session', pending: true do |
| - | # subject { get '/contest'; last_response.body } |
| + | # subject { get '/contest'; last_response.body } |
| - | # it { should match(/Your code is: HELLO WORLD/) } |
| - | # it { should_not match(/You've already participated to that contest ! Come back later./) } |
| + | # it { should match(/Your code is: HELLO WORLD/) } |
| + | # it { should_not match(/You've already participated to that contest ! Come back later./) } |
| - | # describe 'assign tag' do |
| + | # describe 'assign tag' do |
| - | # subject { 2.times { get '/contest' }; last_response.body } |
| + | # subject { 2.times { get '/contest' }; last_response.body } |
| - | # it { should_not match(/Your code is: HELLO WORLD/) } |
| - | # it { should match(/You've already participated to that contest ! Come back later./) } |
| + | # it { should_not match(/Your code is: HELLO WORLD/) } |
| + | # it { should match(/You've already participated to that contest ! Come back later./) } |
| - | # end |
| + | # end |
| - | # end |
| + | # end |
| - | # end |
| + | end |
spec/spec_helper.rb
+3
-2
| @@ | @@ -13,9 +13,10 @@ SimpleCov.start do |
| add_group "Liquid Filters", "lib/locomotive/steam/liquid/filters" | |
| add_group "Liquid Tags", "lib/locomotive/steam/liquid/tags" | |
| - | add_group "Liquid Drops", "lib/locomotive/steam/liquid/drops" |
| + | add_group "Liquid Drops", "lib/locomotive/steam/liquid/drops" |
| add_group "Repositories", "lib/locomotive/steam/repositories" | |
| add_group "Services", "lib/locomotive/steam/services" | |
| + | add_group "Middlewares", "lib/locomotive/steam/middlewares" |
| end | |
| require 'rubygems' | |
| @@ | @@ -38,7 +39,7 @@ RSpec.configure do |config| |
| config.filter_run focused: true | |
| config.run_all_when_everything_filtered = true | |
| - | config.before(:all) { remove_logs } |
| + | config.before(:all) { remove_logs; setup_common } |
| config.before { reset! } | |
| config.after { reset! } | |
| config.order = 'random' | |
spec/support/helpers.rb
+6
-8
| @@ | @@ -1,7 +1,4 @@ |
| require 'locomotive/common' | |
| - | # require 'locomotive/models' |
| - | # require 'locomotive/adapters/memory_adapter' |
| - | require_relative '../../lib/locomotive/steam/initializers' |
| module Spec | |
| module Helpers | |
| @@ | @@ -14,17 +11,18 @@ module Spec |
| FileUtils.rm_rf(File.expand_path('../../fixtures/default/log', __FILE__)) | |
| end | |
| - | def run_server |
| + | def setup_common(logger_output = nil) |
| Locomotive::Common.reset | |
| Locomotive::Common.configure do |config| | |
| - | path = File.join(default_fixture_site_path, 'log/locomotivecms.log') |
| - | config.notifier = Locomotive::Common::Logger.setup(path) |
| + | config.notifier = Locomotive::Common::Logger.setup(logger_output) |
| end | |
| + | end |
| - | bootstrap_site_content |
| + | def run_server |
| + | setup_common(File.join(default_fixture_site_path, 'log/steam.log')) |
| Locomotive::Common::Logger.info 'Server started...' | |
| - | Locomotive::Steam::Server.new(path: default_fixture_site_path) |
| + | Locomotive::Steam::Server.new(path: default_fixture_site_path).to_app |
| end | |
| def default_fixture_site_path | |