exegesis 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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'
|