diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2903b6a..338cdac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,8 @@ on: jobs: build: # Named explicitly so that `experimental` stays out of the job name. - name: "build (${{ matrix.ruby }}, ${{ matrix.rails }})" + # The Vite-based build is the default, so only the classic one is named. + name: "build (Ruby ${{ matrix.ruby }}, Rails ${{ matrix.rails }}${{ matrix.ember != 'vite' && format(', {0}', matrix.ember) || '' }})" runs-on: "ubuntu-latest" # Jobs normally finish in about 3 minutes, so cap hung runs well short @@ -24,20 +25,41 @@ jobs: matrix: ruby: ["3.2", "3.3"] rails: ["7.0", "7.1", "7.2"] + # A key of the matrix itself, so that the classic builds below run alongside these rather than replacing them. + ember: ["vite"] include: - ruby: "3.3" rails: "8.0" + ember: "vite" - ruby: "3.4" rails: "8.0" + ember: "vite" + - ruby: "4.0" + rails: "7.2" + ember: "vite" + - ruby: "4.0" + rails: "8.0" + ember: "vite" - ruby: "4.0" rails: "8.1" + ember: "vite" - ruby: "3.4" rails: "main" + ember: "vite" experimental: true + # The classic build at both ends of the supported range: the oldest Ruby, Rails and Node, and the newest. + - ruby: "3.2" + rails: "7.0" + ember: "classic" + node: "20.x" + - ruby: "4.0" + rails: "8.1" + ember: "classic" env: RAILS_ENV: test RAILS_VERSION: "${{ matrix.rails }}" + EMBER_BUILD: "${{ matrix.ember }}" steps: - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 @@ -51,7 +73,7 @@ jobs: - name: Install NodeJS uses: actions/setup-node@7c12f8017d5436eb855f1ed4399f037a36fbd9e8 # v2.5.2 with: - node-version: "20.x" + node-version: "${{ matrix.node || '26.x' }}" - name: Setup Google Chrome uses: browser-actions/setup-chrome@latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a5dcbf..e3181fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +main +------ + +* Render what `ember-cli-rails` reports about a built application instead of deriving it here. This removes `EmberCli::Assets::Paths`, `EmberCli::Assets::Lookup`, `EmberCli::Assets::AssetMap`, `EmberCli::Assets::DirectoryAssetMap` and `EmberCli::Assets::Url`, and a missing or unresolvable asset now raises `EmberCli::BuildError` rather than `EmberCli::Assets::BuildError` +* Declare the dependency on `ember-cli-rails`, which the helpers have always needed at runtime. `ember-cli-rails` no longer depends on this gem, so an application that renders the helpers adds both to its `Gemfile` + 0.9.2 ------ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 35f28f8..02b882f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,6 +16,11 @@ After cloning the repository, execute the setup script: $ bin/setup +It builds the dummy Ember application from the Vite-based blueprint. +To build it with the classic (Broccoli-based) pipeline instead, remove `spec/dummy/my-app` if it exists and set `EMBER_BUILD`: + + $ EMBER_BUILD=classic bin/setup + Make sure the tests pass: $ bin/rake diff --git a/Gemfile b/Gemfile index a304e15..182309a 100644 --- a/Gemfile +++ b/Gemfile @@ -13,12 +13,6 @@ end gem "rails", rails_constraint gem "webrick" -group :development, :test do - # The specs verify doubles against the development-server API, - # which ships with 0.13.0. - gem "ember-cli-rails", ">= 0.13.0" -end - group :test do gem "cuprite" @@ -30,3 +24,9 @@ group :test do gem "rspec-rails" end end + +# The helpers render an API that ember-cli-rails has not released yet, so +# resolve it from the branch that adds it. +# Remove this once that release is published; the gemspec constraint takes +# over from there. +gem "ember-cli-rails", github: "tricknotes/ember-cli-rails", branch: "claude/intelligent-goodall-foai0r" diff --git a/README.md b/README.md index 5cde20e..4ef6643 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,9 @@ Then run `bundle install`: $ bundle install ``` +The helpers render what [`ember-cli-rails`][ember-cli-rails] reports about a +built application, so they require the release of it that reports that. + ## Setup To configure your project to use `ember-cli-rails`, follow the instructions diff --git a/app/helpers/ember_cli_rails_assets_helper.rb b/app/helpers/ember_cli_rails_assets_helper.rb index 8ba8bdd..dc8953d 100644 --- a/app/helpers/ember_cli_rails_assets_helper.rb +++ b/app/helpers/ember_cli_rails_assets_helper.rb @@ -1,33 +1,22 @@ require "ember_cli/assets/errors" -require "ember_cli/assets/lookup" -require "ember_cli/assets/paths" -require "ember_cli/assets/url" module EmberCliRailsAssetsHelper def include_ember_script_tags(name, prepend: "") - app = EmberCli[name] - app.build + embedding = build_ember_embedding(name) - if dev_server?(app) - dev_server_ember_script_tags(app) + if embedding.startup_tags? + safe_join(embedding.startup_tags(prepend: prepend).map(&:html_safe), "\n") else - paths = EmberCli::Assets::Paths.new(app) - - if paths.vite? - vite_ember_script_tags(paths, prepend) - else - classic_ember_script_tags(app, prepend) + tags_for(embedding.javascript_assets(prepend: prepend)) do |src| + %{} end end end def include_ember_stylesheet_tags(name, prepend: "") - app = EmberCli[name] - app.build - - paths = EmberCli::Assets::Paths.new(app) + embedding = build_ember_embedding(name) - if dev_server?(app) || paths.vite? + if embedding.startup_tags? raise EmberCli::Assets::NotSupportedError, <<~MSG `include_ember_stylesheet_tags` does not support Vite-based applications (`ember-cli >= 6.8`). @@ -37,80 +26,23 @@ def include_ember_stylesheet_tags(name, prepend: "") MSG end - assets = EmberCli::Assets::Lookup.new(app) - - assets.stylesheet_assets. - map { |src| mount_asset(src, prepend) }. - map { |src| %{}.html_safe }. - inject(&:+) + tags_for(embedding.stylesheet_assets(prepend: prepend)) do |href| + %{} + end end private - # Whether ember-cli-rails serves the application from Vite's development - # server. Older ember-cli-rails releases have no development server, so - # feature-detect the reader. - def dev_server?(app) - app.respond_to?(:dev_server?) && app.dev_server? - end + def build_ember_embedding(name) + app = EmberCli[name] + app.build - # The application is served by Vite's development server, so read - # `index.html` from the server instead of a build directory, and rewrite - # its root-relative URLs to absolute URLs on the server — the same way - # ember-cli-rails serves the document itself. `app.build` has already - # booted the server. - def dev_server_ember_script_tags(app) - vite_startup_tags(app.dev_server.index_html, prefix: app.dev_server.origin) + EmberCli::Embedding.new(app) end - # Classic builds ship a fixed set of scripts (vendor and app) resolved - # through the asset map, so emit a plain script tag per JavaScript asset - # with `prepend` joined onto each path. - def classic_ember_script_tags(app, prepend) - assets = EmberCli::Assets::Lookup.new(app) - - assets.javascript_assets. - map { |src| mount_asset(src, prepend) }. - map { |src| %{}.html_safe }. + def tags_for(assets) + assets. + map { |asset| yield(asset).html_safe }. inject(&:+) end - - # `prepend` mounts the build's assets onto a path (or another host), so it only applies to the URLs that point into the build. - # Assets hosted elsewhere (a CDN, a font service) are already absolute. - def mount_asset(src, prepend) - if EmberCli::Assets::Url.remote?(src) - src - else - [prepend, src].join - end - end - - # Vite builds boot from ES modules declared in dist/index.html, so extract - # the tags required for startup (including the config meta tag and - # stylesheets) and remap root-absolute paths onto the mount point. - def vite_ember_script_tags(paths, prepend) - vite_startup_tags(paths.index_html.read, prefix: prepend.to_s.chomp("/")) - end - - # Extracts the tags a Vite-based application needs to boot from an - # `index.html` document, with `prefix` joined onto every root-relative - # URL. Protocol-relative URLs (`//`) are left alone. - def vite_startup_tags(html, prefix:) - document = Nokogiri::HTML5(html) - - tags = document.css( - 'meta[name$="/config/environment"], link[rel="stylesheet"], link[rel="modulepreload"], script' - ).map do |tag| - %w(href src).each do |attribute| - value = tag[attribute] - - if value&.start_with?("/") && !value.start_with?("//") - tag[attribute] = "#{prefix}#{value}" - end - end - tag.to_html.html_safe - end - - safe_join(tags, "\n") - end end diff --git a/bin/setup b/bin/setup index 23da74a..4e79bb1 100755 --- a/bin/setup +++ b/bin/setup @@ -9,19 +9,34 @@ bundle check || bundle install # Add binstubs to PATH via export PATH=".git/safe/../../bin:$PATH" in ~/.zshenv mkdir -p .git/safe +# `vite` is pinned to the Vite-based blueprint that `ember-cli >= 6.8` generates, and `classic` to the last release built by Broccoli. +EMBER_BUILD="${EMBER_BUILD:-vite}" + if ! [ -d spec/dummy/my-app ]; then - # Pinned to the last release built by Broccoli: the feature suite - # exercises the classic build. The Vite path of - # `include_ember_script_tags` is exercised by ember-cli-rails' own suite. - git clone --branch v6.7.2 \ - https://github.com/kellyselden/ember-cli-output.git spec/dummy/my-app + case "$EMBER_BUILD" in + classic) + git clone --branch v6.7.2 \ + https://github.com/kellyselden/ember-cli-output.git spec/dummy/my-app + ;; + vite) + git clone --branch v7.0.0 \ + https://github.com/ember-cli/ember-new-output.git spec/dummy/my-app + ;; + *) + echo "Unsupported EMBER_BUILD '${EMBER_BUILD}'; use classic or vite" >&2 + exit 1 + ;; + esac bin/setup_ember fi root="$(pwd)" -cd ${root}/spec/dummy/my-app && - yarn add --dev ember-cli-rails-addon@rondale-sc/ember-cli-rails-addon +# `ember-cli-rails-addon` is incompatible with the Vite-based build. +if ! [ -f spec/dummy/my-app/vite.config.mjs ]; then + cd ${root}/spec/dummy/my-app && + yarn add --dev ember-cli-rails-addon@rondale-sc/ember-cli-rails-addon +fi cd ${root}/spec/dummy && bundle exec rake ember:install diff --git a/bin/setup_ember b/bin/setup_ember index 129c2d9..efc3ed6 100755 --- a/bin/setup_ember +++ b/bin/setup_ember @@ -6,6 +6,11 @@ set -e sed -i -e 's/history/hash/' spec/dummy/my-app/config/environment.js # add an image to a template -echo '' >> spec/dummy/my-app/app/templates/application.hbs +if [ -f spec/dummy/my-app/app/templates/application.gjs ]; then + sed -i -e 's|| \n|' \ + spec/dummy/my-app/app/templates/application.gjs +else + echo '' >> spec/dummy/my-app/app/templates/application.hbs +fi mkdir -p spec/dummy/my-app/public/assets cp spec/fixtures/logo.png spec/dummy/my-app/public/assets/ diff --git a/ember-cli-rails-assets.gemspec b/ember-cli-rails-assets.gemspec index e518aff..227d02d 100644 --- a/ember-cli-rails-assets.gemspec +++ b/ember-cli-rails-assets.gemspec @@ -16,5 +16,8 @@ Gem::Specification.new do |s| s.files = Dir["{app,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"] - s.add_dependency 'nokogiri' + # The helpers render what ember-cli-rails reports about a built application. + # Constrain this to the release that reports it once that release is + # published. + s.add_dependency "ember-cli-rails" end diff --git a/lib/ember-cli-rails-assets.rb b/lib/ember-cli-rails-assets.rb index 853c81a..5ca453c 100644 --- a/lib/ember-cli-rails-assets.rb +++ b/lib/ember-cli-rails-assets.rb @@ -1,3 +1,4 @@ +require "ember-cli-rails" require "ember_cli/assets/engine" module EmberCli diff --git a/lib/ember_cli/assets/asset_map.rb b/lib/ember_cli/assets/asset_map.rb deleted file mode 100644 index f1e8b5b..0000000 --- a/lib/ember_cli/assets/asset_map.rb +++ /dev/null @@ -1,87 +0,0 @@ -require 'nokogiri' -require "ember_cli/assets/errors" -require "ember_cli/assets/url" - -module EmberCli - module Assets - class AssetMap - def initialize(name:, asset_map:, index_html:) - @name = name - @asset_map = asset_map - @index_html = index_html - end - - def javascripts - assert_asset_map! - - document.css('script').filter_map { |script| asset_for(script['src']) } - end - - def stylesheets - assert_asset_map! - - document.css('link[rel="stylesheet"]').filter_map { |link| asset_for(link['href']) } - end - - private - - attr_reader :name, :asset_map, :index_html - - def document - @document ||= Nokogiri::HTML(index_html.read) - end - - # Assets hosted outside the build (a CDN, a font service) have no entry in the asset map, so their URL is emitted untouched. - # A tag without a URL (an inline ` - - - - - - - - - - HTML - dev_server = instance_double( - EmberCli::DevServer, - index_html: index_html, - origin: "http://127.0.0.1:4200", - ) - app = instance_double( - EmberCli::App, - build: true, - dev_server?: true, - dev_server: dev_server, + context "when the application boots from startup tags" do + it "emits the startup tags ember-cli-rails reads, mounted onto `prepend`" do + app, embedding = build_embedding( + startup_tags?: true, + startup_tags: [ + %{}, + %{}, + ], ) - allow(EmberCli).to receive(:[]).with(:frontend).and_return(app) - tags = helper.include_ember_script_tags(:frontend) + tags = helper.include_ember_script_tags(:frontend, prepend: "/admin") expect(app).to have_received(:build) - expect(tags).to include(%{src="http://127.0.0.1:4200/@vite/client"}) - expect(tags).to include(%{src="http://127.0.0.1:4200/@embroider/virtual/vendor.js"}) - expect(tags).to include(%{href="http://127.0.0.1:4200/@embroider/virtual/app.css"}) - expect(tags).to include(%{name="my-app/config/environment"}) - expect(tags).to include(%{src="https://cdn.example.com/analytics.js"}) - expect(tags).to include(%{src="//cdn.example.com/protocol-relative.js"}) + expect(embedding).to have_received(:startup_tags).with(prepend: "/admin") + expect(tags).to include(%{src="/admin/app.js"}) + expect(tags).to include(%{href="/admin/app.css"}) end end context "when the application is a classic build" do - it "mounts the build's scripts onto `prepend`, leaving the ones hosted elsewhere untouched" do - app = instance_double(EmberCli::App, build: true, dev_server?: false) - paths = instance_double(EmberCli::Assets::Paths, vite?: false) - lookup = instance_double( - EmberCli::Assets::Lookup, + it "emits the scripts as ember-cli-rails reports them, mounted onto `prepend`" do + app, embedding = build_embedding( javascript_assets: [ - "assets/vendor-abc123.js", + "http://example.com/assets/vendor-abc123.js", "https://cdn.example.com/analytics.js", "//cdn.example.com/protocol-relative.js", ], ) - allow(EmberCli).to receive(:[]).with(:frontend).and_return(app) - allow(EmberCli::Assets::Paths). - to receive(:new).with(app).and_return(paths) - allow(EmberCli::Assets::Lookup). - to receive(:new).with(app).and_return(lookup) tags = helper.include_ember_script_tags(:frontend, prepend: "http://example.com/") + expect(app).to have_received(:build) + expect(embedding).to have_received(:javascript_assets). + with(prepend: "http://example.com/") expect(tags).to include(%{src="http://example.com/assets/vendor-abc123.js"}) expect(tags).to include(%{src="https://cdn.example.com/analytics.js"}) expect(tags).to include(%{src="//cdn.example.com/protocol-relative.js"}) @@ -71,28 +44,9 @@ end describe "#include_ember_stylesheet_tags" do - context "when the application is served by Vite's development server" do - it "raises an error pointing at `include_ember_script_tags`" do - app = instance_double(EmberCli::App, build: true, dev_server?: true) - paths = instance_double(EmberCli::Assets::Paths) - allow(EmberCli).to receive(:[]).with(:frontend).and_return(app) - allow(EmberCli::Assets::Paths). - to receive(:new).with(app).and_return(paths) - - expect { helper.include_ember_stylesheet_tags(:frontend) }.to raise_error( - EmberCli::Assets::NotSupportedError, - /include_ember_script_tags/, - ) - end - end - - context "when the application is built with Vite" do + context "when the application boots from startup tags" do it "raises an error pointing at `include_ember_script_tags`" do - app = instance_double(EmberCli::App, build: true, dev_server?: false) - paths = instance_double(EmberCli::Assets::Paths, vite?: true) - allow(EmberCli).to receive(:[]).with(:frontend).and_return(app) - allow(EmberCli::Assets::Paths). - to receive(:new).with(app).and_return(paths) + build_embedding(startup_tags?: true) expect { helper.include_ember_stylesheet_tags(:frontend) }.to raise_error( EmberCli::Assets::NotSupportedError, @@ -102,29 +56,33 @@ end context "when the application is a classic build" do - it "mounts the build's stylesheets onto `prepend`, leaving the ones hosted elsewhere untouched" do - app = instance_double(EmberCli::App, build: true, dev_server?: false) - paths = instance_double(EmberCli::Assets::Paths, vite?: false) - lookup = instance_double( - EmberCli::Assets::Lookup, + it "emits the stylesheets as ember-cli-rails reports them, mounted onto `prepend`" do + app, embedding = build_embedding( stylesheet_assets: [ - "assets/vendor-abc123.css", + "http://example.com/assets/vendor-abc123.css", "https://fonts.example.com/css?family=Frontend", "//fonts.example.com/protocol-relative.css", ], ) - allow(EmberCli).to receive(:[]).with(:frontend).and_return(app) - allow(EmberCli::Assets::Paths). - to receive(:new).with(app).and_return(paths) - allow(EmberCli::Assets::Lookup). - to receive(:new).with(app).and_return(lookup) tags = helper.include_ember_stylesheet_tags(:frontend, prepend: "http://example.com/") + expect(app).to have_received(:build) + expect(embedding).to have_received(:stylesheet_assets). + with(prepend: "http://example.com/") expect(tags).to include(%{href="http://example.com/assets/vendor-abc123.css"}) expect(tags).to include(%{href="https://fonts.example.com/css?family=Frontend"}) expect(tags).to include(%{href="//fonts.example.com/protocol-relative.css"}) end end end + + def build_embedding(**stubs) + app = instance_double(EmberCli::App, build: true) + embedding = instance_double(EmberCli::Embedding, startup_tags?: false, **stubs) + allow(EmberCli).to receive(:[]).with(:frontend).and_return(app) + allow(EmberCli::Embedding).to receive(:new).with(app).and_return(embedding) + + [app, embedding] + end end diff --git a/spec/lib/ember_cli/assets/asset_map_spec.rb b/spec/lib/ember_cli/assets/asset_map_spec.rb deleted file mode 100644 index 5f7df1e..0000000 --- a/spec/lib/ember_cli/assets/asset_map_spec.rb +++ /dev/null @@ -1,235 +0,0 @@ -require "ember_cli/assets/asset_map" - -describe EmberCli::Assets::AssetMap do - describe "#javascripts" do - it "includes the most recent javascript build artifacts" do - asset_map = { - "assets" => { - "not-a-match" => nil, - "bar.js" => "bar-abc123.js", - "vendor.js" => "vendor-abc123.js", - }, - "prepend" => "foo/", - } - index_html = StringIO.new(<<~HTML) - - - - - - - HTML - assets = build_assets(name: "bar", asset_map: asset_map, index_html: index_html) - - javascripts = assets.javascripts - - expect(javascripts).to match_array([ - "foo/bar-abc123.js", - "foo/vendor-abc123.js", - ]) - end - - it "passes scripts hosted outside the build through untouched" do - asset_map = { - "assets" => { - "bar.js" => "bar-abc123.js", - }, - "prepend" => "foo/", - } - index_html = StringIO.new(<<~HTML) - - - - - - - - HTML - assets = build_assets(name: "bar", asset_map: asset_map, index_html: index_html) - - javascripts = assets.javascripts - - expect(javascripts).to match_array([ - "https://cdn.example.com/analytics.js", - "//cdn.example.com/protocol-relative.js", - "foo/bar-abc123.js", - ]) - end - - it "ignores scripts without a `src`" do - asset_map = { - "assets" => { - "bar.js" => "bar-abc123.js", - }, - "prepend" => "foo/", - } - index_html = StringIO.new(<<~HTML) - - - - - - - HTML - assets = build_assets(name: "bar", asset_map: asset_map, index_html: index_html) - - javascripts = assets.javascripts - - expect(javascripts).to match_array(["foo/bar-abc123.js"]) - end - - context "when the asset_map is empty" do - it "raises a BuildError" do - assets = build_assets(asset_map: {}, name: "bar", index_html: StringIO.new) - - expect { assets.javascripts }.to raise_build_error - end - end - end - - describe "#stylesheets" do - it "includes the most recent stylesheet build artifacts" do - asset_map = { - "assets" => { - "not-a-match" => nil, - "bar.css" => "bar-abc123.css", - "vendor.css" => "vendor-abc123.css", - }, - "prepend" => "foo/", - } - index_html = StringIO.new(<<~HTML) - - - - - - - HTML - assets = build_assets(name: "bar", asset_map: asset_map, index_html: index_html) - - stylesheets = assets.stylesheets - - expect(stylesheets).to match_array([ - "foo/bar-abc123.css", - "foo/vendor-abc123.css", - ]) - end - - it "passes stylesheets hosted outside the build through untouched" do - asset_map = { - "assets" => { - "bar.css" => "bar-abc123.css", - }, - "prepend" => "foo/", - } - index_html = StringIO.new(<<~HTML) - - - - - - - - HTML - assets = build_assets(name: "bar", asset_map: asset_map, index_html: index_html) - - stylesheets = assets.stylesheets - - expect(stylesheets).to match_array([ - "https://fonts.example.com/css?family=Bar", - "//fonts.example.com/protocol-relative.css", - "foo/bar-abc123.css", - ]) - end - - it "includes the stylesheets nested in the build" do - asset_map = { - "assets" => { - "bar.css" => "bar-abc123.css", - "font-awesome/css/font-awesome.min.css" => "font-awesome/css/font-awesome.min.css", - }, - "prepend" => "foo/", - } - index_html = StringIO.new(<<~HTML) - - - - - - - HTML - assets = build_assets(name: "bar", asset_map: asset_map, index_html: index_html) - - stylesheets = assets.stylesheets - - expect(stylesheets).to match_array([ - "foo/font-awesome/css/font-awesome.min.css", - "foo/bar-abc123.css", - ]) - end - - it "resolves the stylesheets referenced through a `rootURL`" do - asset_map = { - "assets" => { - "bar.css" => "bar-abc123.css", - "font-awesome/css/font-awesome.min.css" => "font-awesome/css/font-awesome.min.css", - }, - "prepend" => "foo/", - } - index_html = StringIO.new(<<~HTML) - - - - - - - HTML - assets = build_assets(name: "bar", asset_map: asset_map, index_html: index_html) - - stylesheets = assets.stylesheets - - expect(stylesheets).to match_array([ - "foo/font-awesome/css/font-awesome.min.css", - "foo/bar-abc123.css", - ]) - end - - it "prefers the asset whose path matches over one that only shares its basename" do - asset_map = { - "assets" => { - "app.css" => "app.css", - "font-awesome/css/app.css" => "font-awesome/css/app.css", - }, - "prepend" => "foo/", - } - index_html = StringIO.new(<<~HTML) - - - - - - HTML - assets = build_assets(name: "bar", asset_map: asset_map, index_html: index_html) - - stylesheets = assets.stylesheets - - expect(stylesheets).to eq(["foo/font-awesome/css/app.css"]) - end - - context "when the asset_map is empty" do - it "raises a BuildError" do - assets = build_assets(asset_map: {}, name: "bar", index_html: StringIO.new) - - expect { assets.stylesheets }.to raise_build_error - end - end - end -end - -def raise_build_error - raise_error(EmberCli::Assets::BuildError) -end - -def build_assets(asset_map: {}, **options) - EmberCli::Assets::AssetMap.new(**options.merge(asset_map: asset_map)) -end diff --git a/spec/lib/ember_cli/assets/directory_asset_map_spec.rb b/spec/lib/ember_cli/assets/directory_asset_map_spec.rb deleted file mode 100644 index 051e680..0000000 --- a/spec/lib/ember_cli/assets/directory_asset_map_spec.rb +++ /dev/null @@ -1,50 +0,0 @@ -require "tmpdir" -require "pathname" -require "fileutils" -require "ember_cli/assets/directory_asset_map" - -describe EmberCli::Assets::DirectoryAssetMap do - describe "#to_h" do - it "represents the directory" do - create_file("first") - create_file("second") - create_file("third") - - directory_manifest = build_directory_asset_map(directory).to_h - - expect(directory_manifest["prepend"]).to eq("assets/") - expect(directory_manifest["assets"]).to match a_hash_including( - "first" => "first", - "second" => "second", - "third" => "third", - ) - end - - it "represents the files nested in the directory by their path within it" do - create_file("font-awesome/css/font-awesome.min.css") - - directory_manifest = build_directory_asset_map(directory).to_h - - expect(directory_manifest["assets"]).to match a_hash_including( - "font-awesome/css/font-awesome.min.css" => "font-awesome/css/font-awesome.min.css", - ) - end - end - - def build_directory_asset_map(directory) - EmberCli::Assets::DirectoryAssetMap.new(directory) - end - - def create_file(name) - path = directory.join(name) - - FileUtils.mkdir_p(path.dirname) - FileUtils.touch(path) - - File.new(path) - end - - def directory - @directory ||= Pathname(Dir.mktmpdir) - end -end diff --git a/spec/lib/ember_cli/assets/paths_spec.rb b/spec/lib/ember_cli/assets/paths_spec.rb deleted file mode 100644 index fca8763..0000000 --- a/spec/lib/ember_cli/assets/paths_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -require "ember_cli/assets/paths" -require "fileutils" -require "pathname" -require "tmpdir" - -describe EmberCli::Assets::Paths do - describe "#package_json" do - it "is a child of EmberCli::App#root_path" do - app = build_app - paths = EmberCli::Assets::Paths.new(app) - - expect(paths.package_json).to eq app.root_path.join("package.json") - end - end - - describe "#assets" do - it "is a child of EmberCli::App#dist_path" do - app = build_app - paths = EmberCli::Assets::Paths.new(app) - - expect(paths.assets).to eq app.dist_path.join("assets") - end - end - - describe "#asset_map" do - it "globs the EmberCli::App#dist_path directory for an `asset_map.json`" do - app = build_app - paths = EmberCli::Assets::Paths.new(app) - asset_map = app.dist_path.join("assets", "assetMap-abc123.json") - create_file(asset_map) - - expect(paths.asset_map).to exist - expect(paths.asset_map).to eq(asset_map) - end - end - - def build_app - root_path = Pathname.new(Dir.mktmpdir) - - double( - root_path: root_path, - dist_path: root_path.join("dist").tap(&:mkpath), - ) - end - - def create_file(path) - path.parent.mkpath - - FileUtils.touch(path) - - path - end -end