Skip to content

Commit e72b6cd

Browse files
authored
Merge pull request #21 from picoruby/feature/testing-ensure-compiled
Add Funicular::Testing.ensure_compiled! for the test environment
2 parents 998ef8f + 73fd6fa commit e72b6cd

2 files changed

Lines changed: 99 additions & 0 deletions

File tree

lib/funicular/testing.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,60 @@
11
# frozen_string_literal: true
22

33
require_relative "testing/node_runner"
4+
require_relative "plugin"
5+
require_relative "compiler"
46

57
module Funicular
68
module Testing
79
def self.run!(**options)
810
NodeRunner.new(**options).run
911
end
1012

13+
# One-call test-environment setup: syncs plugin assets and compiles
14+
# the client bundle when it is missing or older than any source or
15+
# plugin file. Development recompiles through the middleware and
16+
# production through assets:precompile, but the test environment
17+
# serves whatever app.mrb is lying around; call this once from
18+
# test_helper and rely on the mtime check to keep it cheap.
19+
#
20+
# Funicular::Testing.ensure_compiled! # Rails.root
21+
# Funicular::Testing.ensure_compiled!(force: true)
22+
#
23+
# Returns the path of the compiled bundle.
24+
def self.ensure_compiled!(root: nil, force: false, debug_mode: true)
25+
root = Pathname.new(root || default_root)
26+
registry = Funicular::Plugin::Registry.new(root)
27+
registry.validate!
28+
registry.sync_assets
29+
30+
source_dir = root.join("app", "funicular").to_s
31+
output_file = root.join("app", "assets", "builds", "app.mrb").to_s
32+
sources = registry.local_source_files + Funicular::Compiler.source_files(source_dir)
33+
34+
if force || stale?(output_file, sources)
35+
Funicular::Compiler.new(
36+
source_dir: source_dir,
37+
output_file: output_file,
38+
debug_mode: debug_mode,
39+
prepend_source_files: registry.local_source_files
40+
).compile
41+
end
42+
output_file
43+
end
44+
45+
# A bundle is stale when it does not exist or any source file was
46+
# modified after it was built.
47+
def self.stale?(output_file, source_files)
48+
return true unless File.exist?(output_file)
49+
build_time = File.mtime(output_file)
50+
source_files.any? { |f| File.exist?(f) && File.mtime(f) > build_time }
51+
end
52+
53+
def self.default_root
54+
raise ArgumentError, "root is required outside Rails" unless defined?(Rails) && Rails.respond_to?(:root)
55+
Rails.root
56+
end
57+
1158
def self.assert_picotests(test_case, result, print_summary: true)
1259
puts result.picotest_summary if print_summary
1360
test_case.assert result.success?, result.output
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# frozen_string_literal: true
2+
3+
require "fileutils"
4+
require "tmpdir"
5+
6+
require "test_helper"
7+
8+
# Covers the freshness decision behind Funicular::Testing.ensure_compiled!.
9+
# The actual compile (Node + vendored mrbc) is integration-only, matching
10+
# the compiler tests' scope.
11+
class TestingEnsureCompiledTest < Minitest::Test
12+
def test_stale_when_bundle_is_missing
13+
Dir.mktmpdir do |dir|
14+
assert Funicular::Testing.stale?(File.join(dir, "app.mrb"), [])
15+
end
16+
end
17+
18+
def test_fresh_when_bundle_is_newer_than_every_source
19+
Dir.mktmpdir do |dir|
20+
source = File.join(dir, "component.rb")
21+
output = File.join(dir, "app.mrb")
22+
File.write(source, "")
23+
File.write(output, "")
24+
File.utime(Time.now - 60, Time.now - 60, source)
25+
26+
refute Funicular::Testing.stale?(output, [ source ])
27+
end
28+
end
29+
30+
def test_stale_when_any_source_is_newer_than_the_bundle
31+
Dir.mktmpdir do |dir|
32+
old_source = File.join(dir, "old.rb")
33+
new_source = File.join(dir, "new.rb")
34+
output = File.join(dir, "app.mrb")
35+
[ old_source, new_source, output ].each { |f| File.write(f, "") }
36+
File.utime(Time.now - 60, Time.now - 60, old_source)
37+
File.utime(Time.now - 30, Time.now - 30, output)
38+
File.utime(Time.now, Time.now, new_source)
39+
40+
assert Funicular::Testing.stale?(output, [ old_source, new_source ])
41+
end
42+
end
43+
44+
def test_missing_sources_do_not_count
45+
Dir.mktmpdir do |dir|
46+
output = File.join(dir, "app.mrb")
47+
File.write(output, "")
48+
49+
refute Funicular::Testing.stale?(output, [ File.join(dir, "gone.rb") ])
50+
end
51+
end
52+
end

0 commit comments

Comments
 (0)