Refactor Dependency.expand

This commit is contained in:
Jack Nagel 2013-05-10 23:45:05 -05:00
parent 3be67f7252
commit 12f4ccd7f3
2 changed files with 85 additions and 18 deletions

View File

@ -54,29 +54,35 @@ class Dependency
tags << 'universal' if to_formula.build.has_option? 'universal'
end
# Expand the dependencies of dependent recursively, optionally yielding
# [dependent, dep] pairs to allow callers to apply arbitrary filters to
# the list.
# The default filter, which is applied when a block is not given, omits
# optionals and recommendeds based on what the dependent has asked for.
def self.expand(dependent, &block)
dependent.deps.map do |dep|
prune = catch(:prune) do
class << self
# Expand the dependencies of dependent recursively, optionally yielding
# [dependent, dep] pairs to allow callers to apply arbitrary filters to
# the list.
# The default filter, which is applied when a block is not given, omits
# optionals and recommendeds based on what the dependent has asked for.
def expand(dependent, &block)
dependent.deps.map do |dep|
if prune?(dependent, dep, &block)
next
else
expand(dep.to_formula, &block) << dep
end
end.flatten.compact.uniq
end
def prune?(dependent, dep, &block)
catch(:prune) do
if block_given?
yield dependent, dep
elsif dep.optional? || dep.recommended?
Dependency.prune unless dependent.build.with?(dep.name)
prune unless dependent.build.with?(dep.name)
end
end
end
next if prune
expand(dep.to_formula, &block) << dep
end.flatten.compact.uniq
end
# Used to prune dependencies when calling expand with a block.
def self.prune
throw(:prune, true)
# Used to prune dependencies when calling expand with a block.
def prune
throw(:prune, true)
end
end
end

View File

@ -0,0 +1,61 @@
require 'testing_env'
require 'dependency'
class DependencyExpansionTests < Test::Unit::TestCase
def build_dep(name, deps=[])
dep = Dependency.new(name)
dep.stubs(:to_formula).returns(stub(:deps => deps))
dep
end
def setup
@foo = build_dep(:foo)
@bar = build_dep(:bar)
@baz = build_dep(:baz)
@qux = build_dep(:qux)
@deps = [@foo, @bar, @baz, @qux]
@f = stub(:deps => @deps)
end
def test_expand_yields_dependent_and_dep_pairs
i = 0
Dependency.expand(@f) do |dependent, dep|
assert_equal @f, dependent
assert_equal dep, @deps[i]
i += 1
end
end
def test_expand_no_block
assert_equal @deps, Dependency.expand(@f)
end
def test_expand_prune_all
assert_empty Dependency.expand(@f) { Dependency.prune }
end
def test_expand_selective_pruning
deps = Dependency.expand(@f) do |_, dep|
Dependency.prune if dep.name == :foo
end
assert_equal [@bar, @baz, @qux], deps
end
def test_expand_preserves_dependency_order
@foo.stubs(:to_formula).returns(stub(:deps => [@qux, @baz]))
assert_equal [@qux, @baz, @foo, @bar], Dependency.expand(@f)
end
def test_expand_skips_optionals_by_default
@foo.expects(:optional?).returns(true)
@f = stub(:deps => @deps, :build => stub(:with? => false))
assert_equal [@bar, @baz, @qux], Dependency.expand(@f)
end
def test_expand_keeps_recommendeds_by_default
@foo.expects(:recommended?).returns(true)
@f = stub(:deps => @deps, :build => stub(:with? => true))
assert_equal @deps, Dependency.expand(@f)
end
end