exegesis 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
- data/.rvmrc +2 -0
- data/.yardopts +5 -0
- data/CHANGELOG +10 -0
- data/Gemfile +20 -0
- data/LICENSE +22 -0
- data/NOTES.md +214 -0
- data/README.md +44 -0
- data/Rakefile +11 -0
- data/TODO.md +63 -0
- data/bin/exegesis +15 -0
- data/exegesis.gemspec +23 -0
- data/lib/exegesis/base_directory.rb +29 -0
- data/lib/exegesis/directory.rb +33 -0
- data/lib/exegesis/file_searcher.rb +48 -0
- data/lib/exegesis/file_system_entity.rb +52 -0
- data/lib/exegesis/flyweight.rb +130 -0
- data/lib/exegesis/registerable.rb +58 -0
- data/lib/exegesis/source_file.rb +45 -0
- data/lib/exegesis/version.rb +4 -0
- data/lib/exegesis.rb +48 -0
- data/spec/fake_project/AUTHORS +1 -0
- data/spec/fake_project/Rakefile +14 -0
- data/spec/fake_project/config.yml +6 -0
- data/spec/fake_project/src/grafton.c +25 -0
- data/spec/fake_project/src/node.c +23 -0
- data/spec/fake_project/src/node.h +19 -0
- data/spec/fake_project/test/example2_test.c +29 -0
- data/spec/fake_project/test/example_test.c +12 -0
- data/spec/fake_project/test/test_helper.h +19 -0
- data/spec/helpers/delegates.rb +49 -0
- data/spec/helpers/set_helpers.rb +27 -0
- data/spec/helpers/the.rb +15 -0
- data/spec/helpers/they.rb +15 -0
- data/spec/helpers/topic.rb +82 -0
- data/spec/integration/flyweight_registerable_spec.rb +78 -0
- data/spec/integration/visitor_spec.rb +86 -0
- data/spec/integration_spec_helper.rb +1 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/unit/base_directory_spec.rb +44 -0
- data/spec/unit/directory_spec.rb +44 -0
- data/spec/unit/file_searcher_spec.rb +82 -0
- data/spec/unit/flyweight_spec.rb +137 -0
- data/spec/unit/helpers_spec.rb +3 -0
- data/spec/unit/source_file_spec.rb +127 -0
- data/spec/unit_spec_helper.rb +1 -0
- metadata +158 -0
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'integration_spec_helper'
|
2
|
+
|
3
|
+
describe Flyweight, "mixin", "other objects" do
|
4
|
+
before do
|
5
|
+
class Example
|
6
|
+
include Registerable
|
7
|
+
def initialize(parent, name, *args)
|
8
|
+
@parent = parent
|
9
|
+
@name = name
|
10
|
+
@args = args
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :parent, :name
|
14
|
+
|
15
|
+
def self.build_path(parent, child)
|
16
|
+
[parent.path, child].join('/')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class ParentObject
|
21
|
+
def path
|
22
|
+
"the_parent_path"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:parent) { ParentObject.new }
|
28
|
+
|
29
|
+
after do
|
30
|
+
Object.send(:remove_const, :Example)
|
31
|
+
Object.send(:remove_const, :ParentObject)
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'api' do
|
35
|
+
context 'class' do
|
36
|
+
subject { Example }
|
37
|
+
it { should respond_to :create }
|
38
|
+
|
39
|
+
context 'required' do
|
40
|
+
it { should respond_to :build_path }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'instance' do
|
45
|
+
subject { Example.send(:new, parent, 'n') } # to test instance API
|
46
|
+
it { should respond_to :path }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'instantiation' do
|
51
|
+
it 'disallows instantiation via #new' do
|
52
|
+
expect { Example.new(parent, 'n') }.to raise_error NoMethodError
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'creating a new instance' do
|
57
|
+
subject { Example.create(parent, 'n') }
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'creating an instance that is already registered' do
|
61
|
+
let!(:existing_entry) { Example.create(parent, 'n') }
|
62
|
+
subject { Example.create(parent, 'n') }
|
63
|
+
|
64
|
+
it { should be existing_entry }
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'deleting an instance' do
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'retrieving an already created instance' do
|
71
|
+
context 'via #create' do
|
72
|
+
end
|
73
|
+
|
74
|
+
#find semantics, something like ['/foo/bar']
|
75
|
+
context 'via #[]' do
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'integration_spec_helper'
|
2
|
+
|
3
|
+
describe '#visit' do
|
4
|
+
let (:dir) { BaseDirectory.create('./spec/fake_project') }
|
5
|
+
|
6
|
+
context 'visitor with a proc' do
|
7
|
+
subject { proc { } }
|
8
|
+
|
9
|
+
before do
|
10
|
+
subject.stub(:call)
|
11
|
+
|
12
|
+
dir.visit(subject)
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
it { should have_received(:call).with(dir.class, dir) }
|
17
|
+
it { should_not have_received(:on_enter) }
|
18
|
+
it { should_not have_received(:on_exit) }
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'visitor with a class' do
|
22
|
+
let (:visitor) { double('visitor instance') }
|
23
|
+
subject { visitor }
|
24
|
+
|
25
|
+
before do
|
26
|
+
visitor.stub(:call)
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'a visitor class with no hooks defined' do
|
30
|
+
before do
|
31
|
+
visitor.stub(:respond_to?).with(:on_enter).and_return(false)
|
32
|
+
visitor.stub(:respond_to?).with(:on_exit).and_return(false)
|
33
|
+
|
34
|
+
dir.visit(visitor)
|
35
|
+
end
|
36
|
+
|
37
|
+
it { should have_received(:call).with(dir.class, dir) }
|
38
|
+
it { should_not have_received(:on_enter) }
|
39
|
+
it { should_not have_received(:on_exit) }
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'a visitor class with the #on_enter hook defined' do
|
43
|
+
before do
|
44
|
+
visitor.stub(:respond_to?).with(:on_enter).and_return(true)
|
45
|
+
visitor.stub(:respond_to?).with(:on_exit).and_return(false)
|
46
|
+
visitor.stub(:on_enter)
|
47
|
+
|
48
|
+
dir.visit(visitor)
|
49
|
+
end
|
50
|
+
|
51
|
+
it { should have_received(:call).with(dir.class, dir) }
|
52
|
+
it { should have_received(:on_enter) }
|
53
|
+
it { should_not have_received(:on_exit) }
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'a visitor class with the #on_exit hook defined' do
|
57
|
+
before do
|
58
|
+
visitor.stub(:respond_to?).with(:on_enter).and_return(false)
|
59
|
+
visitor.stub(:respond_to?).with(:on_exit).and_return(true)
|
60
|
+
visitor.stub(:on_exit)
|
61
|
+
|
62
|
+
dir.visit(visitor)
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
it { should have_received(:call).with(dir.class, dir) }
|
67
|
+
it { should_not have_received(:on_enter) }
|
68
|
+
it { should have_received(:on_exit) }
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'a visitor class with the both hooks defined' do
|
72
|
+
before do
|
73
|
+
visitor.stub(:respond_to?).with(:on_enter).and_return(true)
|
74
|
+
visitor.stub(:respond_to?).with(:on_exit).and_return(true)
|
75
|
+
visitor.stub(:on_enter)
|
76
|
+
visitor.stub(:on_exit)
|
77
|
+
|
78
|
+
dir.visit(visitor)
|
79
|
+
end
|
80
|
+
|
81
|
+
it { should have_received(:call).with(dir.class, dir) }
|
82
|
+
it { should have_received(:on_enter) }
|
83
|
+
it { should have_received(:on_exit) }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'spec_helper'
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
require 'exegesis'
|
6
|
+
|
7
|
+
require 'bahia'
|
8
|
+
|
9
|
+
require 'rspec-spies'
|
10
|
+
|
11
|
+
#include helpers
|
12
|
+
Dir["./spec/helpers/*.rb"].each { |file| require file }
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.before do
|
16
|
+
allow_message_expectations_on_nil
|
17
|
+
end
|
18
|
+
|
19
|
+
config.after do
|
20
|
+
SourceFile.clear_registry!
|
21
|
+
Directory.clear_registry!
|
22
|
+
end
|
23
|
+
|
24
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
25
|
+
|
26
|
+
config.include(Bahia)
|
27
|
+
|
28
|
+
config.extend(RSpec::Exegesis::DSL::Macros)
|
29
|
+
config.include(RSpec::Exegesis::DSL::Matchers)
|
30
|
+
end
|
31
|
+
|
32
|
+
class RSpec::Mocks::Mock
|
33
|
+
def inspect
|
34
|
+
"double(#{@name.inspect})"
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'unit_spec_helper'
|
2
|
+
|
3
|
+
describe BaseDirectory do
|
4
|
+
let (:root) { double('some path to a project directory').as_null_object }
|
5
|
+
let (:searcher) { double('directory searcher like FileSearcher') }
|
6
|
+
let (:dir) { double('fake directory') }
|
7
|
+
let (:file) { double('fake file') }
|
8
|
+
|
9
|
+
let (:project) { BaseDirectory.create(root, searcher) }
|
10
|
+
|
11
|
+
|
12
|
+
before do
|
13
|
+
searcher.stub(:[]).with(root + '*').and_return([dir, file])
|
14
|
+
searcher.stub(:new).and_return(searcher)
|
15
|
+
searcher.stub(:search).and_return(searcher)
|
16
|
+
end
|
17
|
+
|
18
|
+
context do
|
19
|
+
subject { project }
|
20
|
+
|
21
|
+
describe 'api' do
|
22
|
+
it { should be_a Directory }
|
23
|
+
it { should respond_to :root }
|
24
|
+
it { should respond_to :directories }
|
25
|
+
it { should respond_to :files }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#root' do
|
29
|
+
subject { project.root }
|
30
|
+
it { should == root }
|
31
|
+
end
|
32
|
+
|
33
|
+
it { should delegate(:files).to(searcher) }
|
34
|
+
it { should delegate(:directories).to(searcher) }
|
35
|
+
|
36
|
+
#it should also provide interface for
|
37
|
+
# * creating files/directories
|
38
|
+
# - something like `directories << Directory('foo')` ?
|
39
|
+
#
|
40
|
+
# *
|
41
|
+
#
|
42
|
+
#it should also have a #visit method, see the NOTES doc for details on that
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'unit_spec_helper'
|
2
|
+
|
3
|
+
describe Directory do
|
4
|
+
let (:parent) { double('parent directory') }
|
5
|
+
let (:parent_path) { 'parent/' }
|
6
|
+
let (:name) { 'subdir/' }
|
7
|
+
let (:searcher) { double('searcher') }
|
8
|
+
let (:directory) { Directory.create(parent, name, searcher) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
parent.stub(:is_a?).with(Directory).and_return(true)
|
12
|
+
parent.stub(:path).and_return(parent_path)
|
13
|
+
|
14
|
+
searcher.stub(:new).and_return(searcher)
|
15
|
+
end
|
16
|
+
|
17
|
+
subject { directory }
|
18
|
+
|
19
|
+
describe 'instantiation' do
|
20
|
+
it 'disallows instantiation via #new' do
|
21
|
+
expect { Directory.new(parent, name, searcher) }.to raise_error NoMethodError
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'api' do
|
26
|
+
it { should respond_to :directories }
|
27
|
+
it { should respond_to :parent }
|
28
|
+
it { should respond_to :files }
|
29
|
+
it { should respond_to :path }
|
30
|
+
it { should respond_to :children }
|
31
|
+
|
32
|
+
its(:class) { should respond_to :create }
|
33
|
+
end
|
34
|
+
|
35
|
+
it { should delegate(:files).to(searcher) }
|
36
|
+
it { should delegate(:directories).to(searcher) }
|
37
|
+
|
38
|
+
describe '#path' do
|
39
|
+
subject { directory.path }
|
40
|
+
|
41
|
+
it { should be_a String }
|
42
|
+
it { should == File.join(parent_path, name) }
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'unit_spec_helper'
|
2
|
+
|
3
|
+
describe FileSearcher do
|
4
|
+
let (:root) { double('a fake backend') }
|
5
|
+
let (:root_path) { double('a fake path') }
|
6
|
+
let (:globbed_path) { double('a fake glob of root_path with *') }
|
7
|
+
let (:file_searcher) { FileSearcher.new(root) }
|
8
|
+
let (:dir) { double('a fake directory') }
|
9
|
+
let (:file) { double('a fake file') }
|
10
|
+
let (:file_path) { double('the fake file path') }
|
11
|
+
let (:dir_path) { double('the directory file path') }
|
12
|
+
|
13
|
+
let (:fake_source_file_instance) { double('a fake SourceFile instance') }
|
14
|
+
let (:fake_directory_instance) { double('a fake Directory instance') }
|
15
|
+
|
16
|
+
before do
|
17
|
+
File.stub(:directory?).with(dir).and_return(true)
|
18
|
+
File.stub(:file?).with(dir).and_return(false)
|
19
|
+
File.stub(:basename).with(dir).and_return(dir)
|
20
|
+
|
21
|
+
File.stub(:directory?).with(file).and_return(false)
|
22
|
+
File.stub(:file?).with(file).and_return(true)
|
23
|
+
File.stub(:basename).with(file).and_return(file)
|
24
|
+
|
25
|
+
File.stub(:join).with(root_path, '*').and_return(globbed_path)
|
26
|
+
File.stub(:join).with(root_path, file).and_return(file_path)
|
27
|
+
File.stub(:join).with(root_path, dir).and_return(dir_path)
|
28
|
+
|
29
|
+
Directory.stub(:new).with(root, dir).and_return(fake_directory_instance)
|
30
|
+
SourceFile.stub(:new).with(root, file).and_return(fake_source_file_instance)
|
31
|
+
|
32
|
+
fake_source_file_instance.stub(:is_a?).with(SourceFile).and_return(true)
|
33
|
+
fake_directory_instance.stub(:is_a?).with(Directory).and_return(true)
|
34
|
+
|
35
|
+
root.stub(:path).and_return(root_path)
|
36
|
+
end
|
37
|
+
|
38
|
+
subject { file_searcher }
|
39
|
+
|
40
|
+
describe 'api' do
|
41
|
+
it { should respond_to :directories }
|
42
|
+
it { should respond_to :files }
|
43
|
+
it { should respond_to :content }
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#content' do
|
47
|
+
before do
|
48
|
+
Dir.stub(:[])
|
49
|
+
file_searcher.content
|
50
|
+
end
|
51
|
+
|
52
|
+
the(Dir) { should have_received(:[]).with(globbed_path) }
|
53
|
+
end
|
54
|
+
|
55
|
+
context do
|
56
|
+
before do
|
57
|
+
file_searcher.stub(:content).and_return([dir, file])
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#directories' do
|
61
|
+
let! (:directories) { file_searcher.directories }
|
62
|
+
subject { directories }
|
63
|
+
|
64
|
+
it { should contain(fake_directory_instance) }
|
65
|
+
it { should exclude(fake_source_file_instance) }
|
66
|
+
|
67
|
+
the_class(Directory) { should have_received(:new).with(root, dir) }
|
68
|
+
the_class(SourceFile) { should_not have_received(:new) }
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#files' do
|
72
|
+
let! (:files) { file_searcher.files }
|
73
|
+
subject { files }
|
74
|
+
|
75
|
+
it { should contain(fake_source_file_instance) }
|
76
|
+
it { should exclude(fake_directory_instance) }
|
77
|
+
|
78
|
+
the_class(Directory) { should_not have_received(:new) }
|
79
|
+
the_class(SourceFile) { should have_received(:new).with(root, file) }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'unit_spec_helper'
|
2
|
+
|
3
|
+
describe Flyweight do
|
4
|
+
let (:processor) { proc { instance_key } }
|
5
|
+
let (:flyweight) { Flyweight.new(&processor) }
|
6
|
+
let (:instance) { double('instance') }
|
7
|
+
let (:instance_key) { double('instance_key') }
|
8
|
+
|
9
|
+
subject { flyweight }
|
10
|
+
|
11
|
+
before do
|
12
|
+
processor.stub(:call).and_return(instance_key)
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'shared examples' do
|
16
|
+
shared_examples_for 'flyweight unregistration' do
|
17
|
+
before { flyweight.unregister!(key) }
|
18
|
+
|
19
|
+
it { should_not have_key instance_key }
|
20
|
+
it { should_not have_key instance }
|
21
|
+
|
22
|
+
describe 'unregistering an unused key' do
|
23
|
+
it 'raises an error' do
|
24
|
+
expect { flyweight.unregister!(key) }.to raise_error Flyweight::NoEntryError
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#unregister' do
|
28
|
+
it 'raises an error' do
|
29
|
+
expect { flyweight.unregister(key) }.to_not raise_error Flyweight::NoEntryError
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'api' do
|
37
|
+
it { should respond_to :register! }
|
38
|
+
it { should respond_to :unregister! }
|
39
|
+
it { should respond_to :[] }
|
40
|
+
|
41
|
+
it { should respond_to :has_key? }
|
42
|
+
|
43
|
+
it { should respond_to :clear! }
|
44
|
+
it { should respond_to :reset! }
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'implementation' do
|
48
|
+
before { flyweight.register!(instance) }
|
49
|
+
|
50
|
+
describe '#register! and #register' do
|
51
|
+
the(:processor) { should have_received(:call).with(instance) }
|
52
|
+
|
53
|
+
describe 'registering an instance with an already-used key' do
|
54
|
+
it 'raises an error' do
|
55
|
+
expect { flyweight.register!(instance) }.to raise_error Flyweight::AlreadyRegisteredError
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#register' do
|
59
|
+
it 'does not raise an error' do
|
60
|
+
expect { flyweight.register(instance) }.to_not raise_error Flyweight::AlreadyRegisteredError
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#has_key?' do
|
67
|
+
subject { flyweight }
|
68
|
+
|
69
|
+
context 'when it has an entry for the given value' do
|
70
|
+
before { flyweight.register(instance) }
|
71
|
+
|
72
|
+
context 'by key' do
|
73
|
+
it { should have_key instance_key }
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'by instance' do
|
77
|
+
it { should have_key instance }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when it has no entry for the given value' do
|
82
|
+
before { flyweight.clear! }
|
83
|
+
|
84
|
+
context 'by key' do
|
85
|
+
it { should_not have_key instance_key }
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'by instance' do
|
89
|
+
it { should_not have_key instance }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#[]' do
|
95
|
+
context 'by instance' do
|
96
|
+
subject { flyweight[instance] }
|
97
|
+
|
98
|
+
it { should be instance }
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'by key' do
|
102
|
+
subject { flyweight[instance_key] }
|
103
|
+
|
104
|
+
it { should be instance }
|
105
|
+
end
|
106
|
+
|
107
|
+
describe 'when flyweight does not have an entry for the value' do
|
108
|
+
before { flyweight.clear! }
|
109
|
+
|
110
|
+
context 'by instance' do
|
111
|
+
subject { flyweight[instance] }
|
112
|
+
|
113
|
+
it { should be_nil }
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'by key' do
|
117
|
+
subject { flyweight[instance_key] }
|
118
|
+
|
119
|
+
it { should be_nil }
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '#unregister!' do
|
126
|
+
context 'by key' do
|
127
|
+
let (:key) { instance_key }
|
128
|
+
it_behaves_like 'flyweight unregistration'
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'by instance' do
|
132
|
+
let (:key) { instance }
|
133
|
+
it_behaves_like 'flyweight unregistration'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'unit_spec_helper'
|
2
|
+
|
3
|
+
describe SourceFile do
|
4
|
+
let(:basename) { 'fake' }
|
5
|
+
let(:extension) { '.c' }
|
6
|
+
let(:name) { basename + extension }
|
7
|
+
let(:parent) { double('directory') }
|
8
|
+
|
9
|
+
let(:full_path) { File.join(parent.path, name) }
|
10
|
+
let(:content) { double('content') }
|
11
|
+
|
12
|
+
let(:source_file) { SourceFile.create(parent, name) }
|
13
|
+
|
14
|
+
subject { source_file }
|
15
|
+
|
16
|
+
before do
|
17
|
+
parent.stub(:path).and_return('/path/to/parent/')
|
18
|
+
parent.stub(:is_a?).with(Directory).and_return(true)
|
19
|
+
File.stub(:read).with(full_path).and_return(content)
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'instantiation' do
|
23
|
+
it 'disallows instantiation via #new' do
|
24
|
+
expect { SourceFile.new(parent, name) }.to raise_error NoMethodError
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'api' do
|
29
|
+
context 'basic interface' do
|
30
|
+
it { should respond_to :extension }
|
31
|
+
it { should respond_to :ext }
|
32
|
+
|
33
|
+
it { should respond_to :basename }
|
34
|
+
it { should respond_to :name }
|
35
|
+
|
36
|
+
it { should respond_to :path }
|
37
|
+
it { should respond_to :content }
|
38
|
+
|
39
|
+
it { should respond_to :parent }
|
40
|
+
it { should respond_to :container }
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'dependencies' do
|
44
|
+
it { should respond_to :dependencies }
|
45
|
+
it { should respond_to :depends_on }
|
46
|
+
end
|
47
|
+
|
48
|
+
pending 'language identification' do
|
49
|
+
it { should respond_to :language }
|
50
|
+
it { should respond_to :language? }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#path' do
|
55
|
+
subject { source_file.path }
|
56
|
+
|
57
|
+
it { should == full_path }
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#extension' do
|
61
|
+
subject { source_file.extension }
|
62
|
+
|
63
|
+
it { should == subject.ext }
|
64
|
+
it { should == extension }
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#basename' do
|
68
|
+
subject { source_file.basename }
|
69
|
+
|
70
|
+
it { should == basename }
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '#name' do
|
74
|
+
subject { source_file.name }
|
75
|
+
|
76
|
+
it { should == name }
|
77
|
+
it { should == source_file.basename + source_file.ext }
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#parent' do
|
81
|
+
subject { source_file.parent }
|
82
|
+
|
83
|
+
pending 'reimplementation' do
|
84
|
+
it 'raises an error if you try to give a parent that is not a Directory' do
|
85
|
+
expect { SourceFile.create(:not_a_dir, name) }.to raise_error ArgumentError
|
86
|
+
end
|
87
|
+
end
|
88
|
+
it { should == source_file.container }
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#content' do
|
92
|
+
before { source_file.content }
|
93
|
+
|
94
|
+
the_class(File) { should have_received(:read).with(full_path) }
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '#dependencies' do
|
98
|
+
let(:file) { double('another sourcefile') }
|
99
|
+
let(:not_a_file) { double('not a sourcefile') }
|
100
|
+
|
101
|
+
before { file.stub(:is_a?).with(SourceFile).and_return(:true) }
|
102
|
+
|
103
|
+
subject { source_file.dependencies }
|
104
|
+
|
105
|
+
it { should respond_to :each }
|
106
|
+
it { should be_empty }
|
107
|
+
|
108
|
+
describe '#depends_on' do
|
109
|
+
before { source_file.depends_on(file) }
|
110
|
+
|
111
|
+
it { should =~ [file] }
|
112
|
+
|
113
|
+
it 'raises unless the dependency is a file' do
|
114
|
+
expect {
|
115
|
+
source_file.depends_on(not_a_file)
|
116
|
+
}.to raise_error InvalidDependency
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
#this should be a shared pattern between directories, sourcefiles, etc.
|
122
|
+
describe 'flyweight nature' do
|
123
|
+
#it should not create two identical instances
|
124
|
+
end
|
125
|
+
|
126
|
+
#deleting a file should delete it's instance from the flyweight
|
127
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'spec_helper'
|