Skip to content

Commit

Permalink
Assets specs
Browse files Browse the repository at this point in the history
  • Loading branch information
bryanp committed Feb 25, 2018
1 parent 26a8a38 commit fadd2f0
Show file tree
Hide file tree
Showing 60 changed files with 1,153 additions and 63 deletions.
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ gem "pronto-rubocop", ">= 0.9", require: false
gem "pry", ">= 0.11"
gem "rubocop", ">= 0.51"

gem "babel-transpiler"
gem "sass"

group :test do
gem "simplecov", ">= 0.15", require: false
gem "simplecov-console", ">= 0.4"
Expand Down
1 change: 1 addition & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ GEMS = %i[
core
data
presenter
assets
mailer
rake
test
Expand Down
2 changes: 2 additions & 0 deletions pakyow-assets/.rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--require ../spec/spec_config
--require spec_helper
4 changes: 3 additions & 1 deletion pakyow-assets/lib/pakyow/assets.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require "pakyow"
require "pakyow/core"
require "pakyow/support"
require "pakyow/presenter"

require "pakyow/assets/framework"
69 changes: 28 additions & 41 deletions pakyow-assets/lib/pakyow/assets/asset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ class Asset
using Support::Refinements::String::Normalization

extend Support::ClassState
class_state :types, default: []
class_state :extensions, default: [], inheritable: true
class_state :processable, default: false, inheritable: true
class_state :minifiable, default: false, inheritable: true
class_state :__types, default: []
class_state :__emits, default: nil
class_state :__extensions, default: [], inheritable: true
class_state :__minifiable, default: false, inheritable: true

class << self
def new_from_path(path, config:, source_location: "")
type = @types.find { |type|
type._extensions.include?(File.extname(path))
asset_class = @__types.find { |type|
type.__extensions.include?(File.extname(path))
} || self

type.load; type.new(
asset_class.load; asset_class.new(
local_path: path,
source_location: source_location,
config: config
Expand All @@ -46,42 +46,21 @@ def load

# @api private
def inherited(asset_class)
@types << asset_class
@__types << asset_class
super
end

# @api private
def _extensions
@extensions
end

# @api private
def _emits
@emits
end

# @api private
def processable?
@processable == true
end

# @api private
def update_path_for_emitted_type(path)
if @emits
path.sub(File.extname(path), @emits)
if @__emits
path.sub(File.extname(path), @__emits)
else
path
end
end

private

# Marks the asset as being processable.
#
def processable
@processable = true
end

# Registers +extension+ for this asset.
#
def extension(extension)
Expand All @@ -92,14 +71,14 @@ def extension(extension)
#
def extensions(*extensions)
extensions.each do |extension|
@extensions << ".#{extension}"
@__extensions << ".#{extension}"
end
end

# Defines the emitted asset type (e.g. +sass+ emits +css+).
#
def emits(type)
@emits = ".#{type}"
@__emits = ".#{type}"
end
end

Expand Down Expand Up @@ -140,19 +119,27 @@ def initialize(local_path:, config:, dependencies: [], source_location: "")
else
nil
end
else
@minifier = nil
end
end

def each(&block)
if self.class.processable? || minify?
ensure_content do |content|
content = process(content) if self.class.processable?
content = minify(content) if minify?
StringIO.new(content).each(&block)
ensure_content do |content|
content = process(content)

if minify?
content = minify(content)
end
else
File.open(@local_path, "r") do |file|
file.each_line(&block)

StringIO.new(content).each(&block)
end
end

def read
String.new.tap do |asset|
each do |content|
asset << content
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions pakyow-assets/lib/pakyow/assets/behavior/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ module Config
end

setting :frontend_asset_packs_path do
File.join(config.presenter.path, "assets", "packs")
File.join(config.assets.frontend_assets_path, "packs")
end

setting :compiliation_path do
setting :compilation_path do
config.assets.public_path
end

Expand Down
16 changes: 11 additions & 5 deletions pakyow-assets/lib/pakyow/assets/behavior/packs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@ module Packs

apply_extension do
after :initialize do
Pathname.glob(File.join(config.assets.frontend_asset_packs_path, "*.*")) do |asset_pack_path|
if config.assets.extensions.include?(File.extname(asset_pack_path))
asset_pack = Pack.new(File.basename(asset_pack_path, File.extname(asset_pack_path)).to_sym, config.assets)
asset_pack << Asset.new_from_path(asset_pack_path, config: config.assets)
self.pack << asset_pack.finalize
Pathname.glob(File.join(config.assets.frontend_asset_packs_path, "*.*")).group_by { |path|
File.join(File.dirname(path), File.basename(path, File.extname(path)))
}.each do |pack_path, pack_asset_paths|
asset_pack = Pack.new(File.basename(pack_path).to_sym, config.assets)

pack_asset_paths.each do |pack_asset_path|
if config.assets.extensions.include?(File.extname(pack_asset_path))
asset_pack << Asset.new_from_path(pack_asset_path, config: config.assets)
end
end

self.pack << asset_pack.finalize
end
end
end
Expand Down
10 changes: 5 additions & 5 deletions pakyow-assets/lib/pakyow/assets/behavior/rendering.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ module Rendering
next unless head = @presenter.view.object.find_significant_nodes(:head)[0]

(@connection.app.config.assets.autoloaded_packs + @presenter.view.info(:packs).to_a).uniq.each do |pack_name|
if pack = @connection.app.state_for(:pack).find { |pack| pack.name == pack_name.to_sym }
if pack.javascripts?
head.append("<script src=\"#{pack.public_path}.js\"></script>\n")
if pack_with_name = @connection.app.state_for(:pack).find { |pack| pack.name == pack_name.to_sym }
if pack_with_name.javascripts?
head.append("<script src=\"#{pack_with_name.public_path}.js\"></script>\n")
end

if pack.stylesheets?
head.append("<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"#{pack.public_path}.css\">\n")
if pack_with_name.stylesheets?
head.append("<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"#{pack_with_name.public_path}.css\">\n")
end
else
@connection.logger.warn "Could not find pack `#{pack_name}'"
Expand Down
2 changes: 2 additions & 0 deletions pakyow-assets/lib/pakyow/assets/framework.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require "pakyow/core/framework"

require "pakyow/assets/asset"
require "pakyow/assets/pack"

Expand Down
8 changes: 8 additions & 0 deletions pakyow-assets/lib/pakyow/assets/pack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ def each(&block)
asset.each(&block)
end
end

def read
String.new.tap do |packed_asset|
@assets.each do |asset|
packed_asset << asset.read
end
end
end
end
end
end
10 changes: 5 additions & 5 deletions pakyow-assets/lib/pakyow/assets/precompiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ def precompile!
end

def precompile_asset!(asset)
compiliation_path = File.join(@app.config.assets.compiliation_path, asset.public_path)
FileUtils.mkdir_p(File.dirname(compiliation_path))
compilation_path = File.join(@app.config.assets.compilation_path, asset.public_path)
FileUtils.mkdir_p(File.dirname(compilation_path))

asset_content = String.new
asset.each do |content|
asset_content << content
end

@app.state_for(:asset).each do |asset|
asset_content.gsub!(asset.logical_path, asset.public_path)
@app.state_for(:asset).each do |asset_state|
asset_content.gsub!(asset_state.logical_path, asset_state.public_path)
end

File.open(compiliation_path, "w+") do |file|
File.open(compilation_path, "w+") do |file|
file.write(asset_content)
end
end
Expand Down
1 change: 0 additions & 1 deletion pakyow-assets/lib/pakyow/assets/types/es6.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ def load
end
end

processable
extension :es6
emits :js

Expand Down
1 change: 0 additions & 1 deletion pakyow-assets/lib/pakyow/assets/types/sass.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ def load
end
end

processable
extension :sass
emits :css

Expand Down
3 changes: 1 addition & 2 deletions pakyow-assets/lib/pakyow/assets/types/scss.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
module Pakyow
module Assets
module Types
class Sass < Asset
class Scss < Asset
class << self
def load
require "sass"
Expand All @@ -18,7 +18,6 @@ def load
end
end

processable
extension :scss
emits :css

Expand Down
4 changes: 4 additions & 0 deletions pakyow-assets/pakyow-assets.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,9 @@ Gem::Specification.new do |spec|
spec.files = Dir["CHANGELOG.md", "README.md", "LICENSE", "lib/**/*"]
spec.require_path = "lib"

spec.add_dependency "pakyow-core", Pakyow::VERSION
spec.add_dependency "pakyow-support", Pakyow::VERSION
spec.add_dependency "pakyow-presenter", Pakyow::VERSION

spec.add_dependency "yui-compressor", "~> 0.12"
end
69 changes: 69 additions & 0 deletions pakyow-assets/spec/features/cache_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
RSpec.describe "setting cache headers" do
include_context "testable app"

context "cache is enabled" do
let :app_definition do
Proc.new do
instance_exec(&$assets_app_boilerplate)
config.assets.cache = true
end
end

context "requested file is public, but not an asset" do
it "responds 200" do
expect(call("/robots.txt")[0]).to eq(200)
end

it "does not respond with cache headers" do
expect(call("/robots.txt")[1]).to eq("Content-Type" => "text/plain")
end
end

context "requested file is public, and is an asset" do
it "responds 200" do
expect(call("/assets/cache/default.css")[0]).to eq(200)
end

it "responds with cache headers" do
headers = call("/assets/cache/default.css")[1]
expect(headers["Cache-Control"]).to eq("public, max-age=31536000")
expect(headers["Vary"]).to eq("Accept-Encoding")
expect(headers["Last-Modified"]).to_not be_nil
expect(headers["Age"]).to_not be_nil
end
end
end

context "cache is disabled" do
let :app_definition do
Proc.new do
instance_exec(&$assets_app_boilerplate)
config.assets.cache = false
end
end

context "requested file is public, but not an asset" do
it "responds 200" do
expect(call("/robots.txt")[0]).to eq(200)
end

it "does not respond with cache headers" do
expect(call("/robots.txt")[1]).to eq("Content-Type" => "text/plain")
end
end

context "requested file is public, and is an asset" do
it "responds 200" do
expect(call("/assets/cache/default.css")[0]).to eq(200)
end

it "does not respond with cache headers" do
headers = call("/assets/cache/default.css")[1]
expect(headers["Cache-Control"]).to be_nil
expect(headers["Vary"]).to be_nil
expect(headers["Last-Modified"]).to be_nil
expect(headers["Age"]).to be_nil
end
end
end
end
2 changes: 2 additions & 0 deletions pakyow-assets/spec/features/failures/load_errors_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# TODO: test that load errors generated by types are handled
# maybe abstract this so that types don't have to implement themselves
18 changes: 18 additions & 0 deletions pakyow-assets/spec/features/failures/missing_pack_warning_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
RSpec.describe "missing asset pack warning" do
include_context "testable app"

let :app_definition do
Proc.new do
instance_exec(&$assets_app_boilerplate)
config.assets.autoloaded_packs = [:nonexistent]
end
end

it "logs a warning" do
expect_any_instance_of(Pakyow::Logger::RequestLogger).to receive(:warn) do |_, message|
expect(message).to eq("Could not find pack `nonexistent'")
end

call("/packs/autoload")
end
end
Loading

0 comments on commit fadd2f0

Please sign in to comment.