diff --git a/lib/shanty/projects/static_project.rb b/lib/shanty/projects/static_project.rb index 173bd27..3fd1beb 100644 --- a/lib/shanty/projects/static_project.rb +++ b/lib/shanty/projects/static_project.rb @@ -6,7 +6,6 @@ class StaticProject < Project subscribe :build, :tar_project def tar_project - # FIXME: Create a tarball of the current project. system "tar -czvf #{artifact_paths.first} ." end diff --git a/lib/shanty/task_env.rb b/lib/shanty/task_env.rb index b14217a..ea5c42e 100644 --- a/lib/shanty/task_env.rb +++ b/lib/shanty/task_env.rb @@ -12,9 +12,7 @@ def graph private def construct_project_graph - project_templates = Dir.chdir(root) do - Discoverer.new(env).discover_all - end + project_templates = Discoverer.new(env).discover_all Graph.new(env, project_templates).tap do |graph| Mutator.new(env, graph).apply_mutations diff --git a/lib/shanty/task_set.rb b/lib/shanty/task_set.rb index 7d2e947..98d12d7 100644 --- a/lib/shanty/task_set.rb +++ b/lib/shanty/task_set.rb @@ -24,6 +24,7 @@ def self.tasks def self.partial_task @partial_task ||= { + klass: self, options: {}, params: {} } @@ -38,12 +39,12 @@ def self.param(name, options = {}) partial_task[:params][name] = options end - def self.option(name, options = {}) - partial_task[:options][name] = options + def self.option(name, attrs = {}) + partial_task[:options][name] = attrs end def self.method_added(name) - tasks[name] = partial_task.merge(klass: self) + tasks[name] = partial_task # Now reset the task definition. @partial_task = nil diff --git a/spec/lib/shanty/env_spec.rb b/spec/lib/shanty/env_spec.rb index 055881d..ed88234 100644 --- a/spec/lib/shanty/env_spec.rb +++ b/spec/lib/shanty/env_spec.rb @@ -60,6 +60,12 @@ module Shanty end end + describe('#logger') do + it('returns a logger object') do + expect(subject.logger).to be_a(Logger) + end + end + describe('#environment') do before do ENV.delete('SHANTY_ENV') diff --git a/spec/lib/shanty/graph_spec.rb b/spec/lib/shanty/graph_spec.rb index 98eeecd..ee54dce 100644 --- a/spec/lib/shanty/graph_spec.rb +++ b/spec/lib/shanty/graph_spec.rb @@ -7,89 +7,100 @@ module Shanty RSpec.describe(Graph) do include_context('graph') + subject { graph } + + describe('.new') do + let(:missing_parent) { 'foo-bar-does-not-exist' } + it('throws an exception if any of the projects have a dependency on a project that does not exist') do + project_templates[:shanty].parent(missing_parent) + + expect { subject }.to raise_error("Cannot find project at path #{File.join(root, missing_parent)}, which was "\ + 'specified as a dependency for Name: shanty, Type: Shanty::StaticProject') + end + end describe('enumerable methods') do it('returns projects linked together with parent relationships') do - expect(graph[0].parents.map(&:path)).to eql([]) - expect(graph[1].parents.map(&:path)).to eql([project_paths[:one]]) - expect(graph[2].parents.map(&:path)).to eql([project_paths[:two]]) + expect(subject[0].parents.map(&:path)).to eql([]) + expect(subject[1].parents.map(&:path)).to eql([project_paths[:one]]) + expect(subject[2].parents.map(&:path)).to eql([project_paths[:two]]) end it('returns projects linked together with child relationships') do - expect(graph[0].children.map(&:path)).to eql([project_paths[:two]]) - expect(graph[1].children.map(&:path)).to eql([project_paths[:three]]) - expect(graph[2].children.map(&:path)).to eql([]) + expect(subject[0].children.map(&:path)).to eql([project_paths[:two]]) + expect(subject[1].children.map(&:path)).to eql([project_paths[:three]]) + expect(subject[2].children.map(&:path)).to eql([]) end it("returns projects sorted using Tarjan's strongly connected components algorithm") do - expect(graph[0].path).to equal(project_paths[:one]) - expect(graph[1].path).to equal(project_paths[:two]) - expect(graph[2].path).to equal(project_paths[:three]) + expect(subject[0].path).to equal(project_paths[:one]) + expect(subject[1].path).to equal(project_paths[:two]) + expect(subject[2].path).to equal(project_paths[:three]) end end describe('#changed') do it('returns only projects where #changed? is true') do - graph.first.changed = true + subject.first.changed = true - expect(graph.changed).to contain_exactly(graph.first) + expect(subject.changed).to contain_exactly(subject.first) end end describe('#by_name') do it('returns nil when finding a name that does not exist') do - expect(graph.by_name('foobarlux')).to be_nil + expect(subject.by_name('foobarlux')).to be_nil end it('returns the correct project when finding a name that does exist') do - expect(graph.by_name(graph.first.name)).to equal(graph.first) + expect(subject.by_name(subject.first.name)).to equal(subject.first) end end describe('#all_of_type') do it('returns an empty array when no types are given') do - expect(graph.all_of_type).to be_empty + expect(subject.all_of_type).to be_empty end it('returns an empty array when no projects match the types given') do - expect(graph.all_of_type(Project)).to be_empty + expect(subject.all_of_type(Project)).to be_empty end it('returns the correct projects when matching types are given') do - expect(graph.all_of_type(StaticProject)).to match_array(graph) + expect(subject.all_of_type(StaticProject)).to match_array(subject) end end describe('#changed_of_type') do before do - graph.first.changed = true + subject.first.changed = true end it('returns an empty array when no types are given') do - expect(graph.changed_of_type).to be_empty + expect(subject.changed_of_type).to be_empty end it('returns an empty array when no projects match the types given') do - expect(graph.changed_of_type(Project)).to be_empty + expect(subject.changed_of_type(Project)).to be_empty end it('returns the correct projects when matching types are given') do - expect(graph.changed_of_type(StaticProject)).to contain_exactly(graph.first) + expect(subject.changed_of_type(StaticProject)).to contain_exactly(subject.first) end end describe('#owner_of_file') do it('returns nil if the given folder is outside of any project') do - expect(graph.owner_of_file('/tmp')).to be_nil + expect(subject.owner_of_file('/tmp')).to be_nil end it('returns the correct project that owns a given folder') do - expect(graph.owner_of_file(project_paths[:three]).path).to equal(project_paths[:three]) + expect(subject.owner_of_file(project_paths[:three]).path).to equal(project_paths[:three]) end end describe('#projects_within_path') do - let(:projects_within_path) { graph.projects_within_path(project_paths[:two]) } + let(:projects_within_path) { subject.projects_within_path(project_paths[:two]) } it('returns all the projects at or below the given path') do expect(projects_within_path.map(&:path)).to contain_exactly(project_paths[:two], project_paths[:three]) diff --git a/spec/lib/shanty/task_env_spec.rb b/spec/lib/shanty/task_env_spec.rb index e69de29..e9da68d 100644 --- a/spec/lib/shanty/task_env_spec.rb +++ b/spec/lib/shanty/task_env_spec.rb @@ -0,0 +1,50 @@ +require 'spec_helper' +require 'shanty/task_env' + +# All classes referenced belong to the shanty project +module Shanty + RSpec.describe(TaskEnv) do + include_context('graph') + subject { TaskEnv.new(env) } + + describe('#env') do + it('returns the env passed to the constructor') do + expect(subject.env).to eql(env) + end + end + + describe('#graph') do + let(:discoverer) { Discoverer.new(env) } + let(:mutator) { Mutator.new(env, graph) } + + it('discovers all the projects') do + expect(Discoverer).to receive(:new).with(env).and_return(discoverer) + expect(discoverer).to receive(:discover_all).and_return([]) + + subject.graph + end + + it('mutates all the projects in the graph') do + allow(Discoverer).to receive(:new).with(env).and_return(discoverer) + allow(discoverer).to receive(:discover_all).and_return([]) + + expect(Mutator).to receive(:new).with(env, instance_of(Graph)).and_return(mutator) + expect(mutator).to receive(:apply_mutations) + + subject.graph + end + + it('returns a graph') do + expect(subject.graph).to be_a(Graph) + end + end + + describe('delegations') do + it('delegates missing methods to the env') do + expect(env).to receive(:environment) + + subject.environment + end + end + end +end diff --git a/spec/lib/shanty/task_set_spec.rb b/spec/lib/shanty/task_set_spec.rb index e69de29..0642478 100644 --- a/spec/lib/shanty/task_set_spec.rb +++ b/spec/lib/shanty/task_set_spec.rb @@ -0,0 +1,84 @@ +require 'spec_helper' +require 'shanty/task_set' +require_fixture 'test_task_set' + +# All classes referenced belong to the shanty project +module Shanty + RSpec.describe(TaskSet) do + after do + TaskSet.instance_variable_set(:@partial_task, nil) + end + + describe('.inherited') do + let(:task_set) { Class.new(TestTaskSet) } + + it('adds the inheriting task set to the array of registered task sets') do + TaskSet.inherited(task_set) + + expect(TaskSet.instance_variable_get(:@task_sets)).to include(task_set) + end + end + + describe('.task_sets') do + it('returns the registered task sets') do + expect(TaskSet.task_sets).to include(TestTaskSet) + end + end + + describe('.tasks') do + it('returns the registered tasks') do + expect(TestTaskSet.tasks).to include(:foo) + end + end + + describe('.partial_task') do + it('returns a partial task') do + expect(TestTaskSet.partial_task).to eql(klass: TestTaskSet, options: {}, params: {}) + end + end + + describe('.desc') do + it('sets the syntax field of the current partial task') do + TaskSet.desc('foo', 'bar') + + expect(TaskSet.instance_variable_get(:@partial_task)).to include(syntax: 'foo') + end + + it('sets the desc field of the current partial task') do + TaskSet.desc('foo', 'bar') + + expect(TaskSet.instance_variable_get(:@partial_task)).to include(desc: 'bar') + end + end + + describe('.param') do + it('sets the given param with the given options in the current partial task') do + TaskSet.param('foo', bar: 'lux') + + expect(TaskSet.instance_variable_get(:@partial_task)[:params]).to include('foo' => { bar: 'lux' }) + end + end + + describe('.option') do + it('sets the given option with the given attrs in the current partial task') do + TaskSet.option('foo', bar: 'lux') + + expect(TaskSet.instance_variable_get(:@partial_task)[:options]).to include('foo' => { bar: 'lux' }) + end + end + + describe('.method_added') do + it('adds the partial task to the list of tasks with the name of the method that was added') do + TaskSet.method_added(:woowoo) + + expect(TaskSet.instance_variable_get(:@tasks)).to include(:woowoo) + end + + it('resets the partial task') do + TaskSet.method_added(:weewah) + + expect(TaskSet.instance_variable_get(:@partial_task)).to be_nil + end + end + end +end