codependency 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,28 +1,31 @@
1
1
  module Codependency
2
2
  class Graph
3
- def initialize( filenames )
4
- @nodes = Hash[ filenames.map { |f| [ f, Node.new( f ) ] } ]
3
+ def initialize( start, options={} )
4
+ @options = options
5
+ @nodes = Hash.new { |h, k| h[ k ] = Node.new( k, parser ) }
6
+ @start = @nodes[ start ]
5
7
  end
6
- attr_reader :nodes
7
8
 
8
9
  def files
9
- nodes.reduce( [ ] ) do |list, (filename, node)|
10
- resolve node, list
11
- list
12
- end
10
+ [ ].tap { |list| resolve @start, list }.reverse.map &:filename
13
11
  end
14
12
 
15
13
  protected
16
14
 
17
15
  def resolve( node, list )
18
- unless list.include? node.filename
19
- node.dependencies.each do |dep|
20
- # TODO need to check here to make sure
21
- # we actually have a node for this dependency
22
- resolve nodes[ dep ], list
16
+ list << node # TODO if the node were in the list here,
17
+ # would that indicate a circular dependency?
18
+ node.dependencies.map { |filename| @nodes[ filename ] }.each do |dep|
19
+ if list.include?( dep )
20
+ list << list.slice!( list.index( dep ) )
21
+ else
22
+ resolve dep, list
23
23
  end
24
- list << node.filename
25
24
  end
26
25
  end
26
+
27
+ def parser
28
+ @parser ||= Parser.new @options
29
+ end
27
30
  end
28
31
  end
@@ -2,11 +2,12 @@ require 'pathname'
2
2
 
3
3
  module Codependency
4
4
  class Node
5
- def initialize( filename )
6
- raise Errno::ENOENT unless File.exist?( filename )
5
+ def initialize( filename, parser )
6
+ raise Errno::ENOENT, filename unless File.exist?( filename )
7
7
  @filename = filename
8
+ @parser = parser
8
9
  end
9
- attr_reader :filename
10
+ attr_reader :filename, :parser
10
11
 
11
12
  def dependencies
12
13
  parser.parse( filename ).map { |f| dirname.join( "#{f}#{extname}" ).to_s }
@@ -25,9 +26,5 @@ module Codependency
25
26
  def path
26
27
  @path ||= Pathname.new filename
27
28
  end
28
-
29
- def parser
30
- @parser ||= Parser.new
31
- end
32
29
  end
33
30
  end
@@ -1,6 +1,11 @@
1
1
  module Codependency
2
2
  class Parser
3
3
 
4
+ def initialize( options={} )
5
+ @options = options
6
+ @comment = options.delete( :comment ) || '#'
7
+ end
8
+
4
9
  def parse( file )
5
10
  IO.readlines( file ).take_while do |line|
6
11
  line =~ pattern
@@ -10,7 +15,7 @@ module Codependency
10
15
  protected
11
16
 
12
17
  def pattern
13
- @pattern ||= /^# require (.+)$/
18
+ @pattern ||= /^#{@comment} require (.+)$/
14
19
  end
15
20
  end
16
21
  end
@@ -1,3 +1,3 @@
1
1
  module Codependency
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -1,16 +1,26 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Codependency::Graph do
4
- let( :path ){ File.join( File.dirname( __FILE__ ), '../fixtures' ) }
5
- subject { Codependency::Graph.new Dir[ File.join( path, '*.rb' ) ] }
4
+ context 'planets', :files => :planets do
5
+ subject { Codependency::Graph.new graph }
6
6
 
7
- its( :files ){ should eq(
8
- [
9
- "#{path}/body.rb",
10
- "#{path}/planet.rb",
11
- "#{path}/earth.rb",
12
- "#{path}/mars.rb",
13
- "#{path}/phobos.rb"
14
- ]
15
- ) }
7
+ context 'earth' do
8
+ let( :graph ){ 'earth.rb' }
9
+ its( :files ){ should eq( %w| body.rb planet.rb earth.rb | ) }
10
+ end
11
+
12
+ context 'phobos' do
13
+ let( :graph ){ 'phobos.rb' }
14
+ its( :files ){ should eq( %w| body.rb planet.rb mars.rb phobos.rb | ) }
15
+ end
16
+ end
17
+
18
+ context 'breakfasts', :files => :breakfasts do
19
+ subject { Codependency::Graph.new graph, :comment => '//' }
20
+
21
+ context 'sandwich' do
22
+ let( :graph ){ 'sandwich.js' }
23
+ its( :files ){ should eq( %w| butter.js toast.js egg.js sandwich.js | ) }
24
+ end
25
+ end
16
26
  end
@@ -1,19 +1,18 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Codependency::Node do
4
- let( :path ){ File.join( File.dirname( __FILE__ ), '../fixtures' ) }
4
+ let( :parser ){ double 'Parser', :parse => [ 'body' ] }
5
5
 
6
- context 'when the file exists' do
7
- subject { Codependency::Node.new "#{path}/planet.rb" }
8
-
9
- its( :dependencies ){ should eq( [ "#{path}/body.rb" ] ) }
6
+ context 'when the file exists', :files => :planets do
7
+ subject { Codependency::Node.new 'planet.rb', parser }
8
+ its( :dependencies ){ should eq( [ 'body.rb' ] ) }
10
9
  end
11
10
 
12
11
  context 'when the file does not exist' do
13
12
  it 'should raise an error' do
14
13
  expect {
15
- Codependency::Node.new "#{path}/pluto.rb"
16
- }.to raise_error( Errno::ENOENT )
14
+ Codependency::Node.new 'pluto.rb', parser
15
+ }.to raise_error( Errno::ENOENT, 'No such file or directory - pluto.rb' )
17
16
  end
18
17
  end
19
18
  end
@@ -1,31 +1,49 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Codependency::Parser do
4
- let( :path ){ File.join( File.dirname( __FILE__ ), '../fixtures' ) }
5
- let( :parser ){ Codependency::Parser.new }
4
+ context 'planets', :files => :planets do
5
+ let( :parser ){ Codependency::Parser.new }
6
6
 
7
- context 'body' do
8
- subject { parser.parse( "#{path}/body.rb" ) }
9
- it { should eq( [ ] ) }
7
+ context 'body' do
8
+ subject { parser.parse( 'body.rb' ) }
9
+ it { should eq( [ ] ) }
10
+ end
11
+ context 'earth' do
12
+ subject { parser.parse( 'earth.rb' ) }
13
+ it { should eq( [ 'planet' ] ) }
14
+ end
15
+ context 'mars' do
16
+ subject { parser.parse( 'mars.rb' ) }
17
+ it { should eq( [ 'planet' ] ) }
18
+ end
19
+ context 'phobos' do
20
+ subject { parser.parse( 'phobos.rb' ) }
21
+ it { should eq( [ 'body', 'mars' ] ) }
22
+ end
23
+ context 'planet' do
24
+ subject { parser.parse( 'planet.rb' ) }
25
+ it { should eq( [ 'body' ] ) }
26
+ end
10
27
  end
11
28
 
12
- context 'earth' do
13
- subject { parser.parse( "#{path}/earth.rb" ) }
14
- it { should eq( [ 'planet' ] ) }
15
- end
16
-
17
- context 'mars' do
18
- subject { parser.parse( "#{path}/mars.rb" ) }
19
- it { should eq( [ 'planet' ] ) }
20
- end
21
-
22
- context 'phobos' do
23
- subject { parser.parse( "#{path}/phobos.rb" ) }
24
- it { should eq( [ 'body', 'mars' ] ) }
25
- end
29
+ context 'breakfasts', :files => :breakfasts do
30
+ let( :parser ){ Codependency::Parser.new :comment => '//' }
26
31
 
27
- context 'planet' do
28
- subject { parser.parse( "#{path}/planet.rb" ) }
29
- it { should eq( [ 'body' ] ) }
32
+ context 'butter' do
33
+ subject { parser.parse( 'butter.js' ) }
34
+ it { should eq( [ ] ) }
35
+ end
36
+ context 'egg' do
37
+ subject { parser.parse( 'egg.js' ) }
38
+ it { should eq( [ 'butter' ] ) }
39
+ end
40
+ context 'toast' do
41
+ subject { parser.parse( 'toast.js' ) }
42
+ it { should eq( [ 'butter' ] ) }
43
+ end
44
+ context 'sandwich' do
45
+ subject { parser.parse( 'sandwich.js' ) }
46
+ it { should eq( [ 'egg', 'toast' ] ) }
47
+ end
30
48
  end
31
49
  end
@@ -1,6 +1,10 @@
1
1
  require 'codependency'
2
2
 
3
+ Dir[ './spec/support/*.rb' ].each { |f| require f }
4
+
3
5
  RSpec.configure do |config|
4
6
  config.color_enabled = true
5
7
  config.formatter = :documentation
8
+
9
+ config.include FileSystemStubs
6
10
  end
@@ -0,0 +1,24 @@
1
+ shared_context 'breakfast foods', :files => :breakfasts do
2
+
3
+ before do
4
+ file 'butter.js', <<-EOS
5
+ var Butter = { }
6
+ EOS
7
+
8
+ file 'egg.js', <<-EOS
9
+ // require butter
10
+ var Egg = { }
11
+ EOS
12
+
13
+ file 'toast.js', <<-EOS
14
+ // require butter
15
+ var Toast = { }
16
+ EOS
17
+
18
+ file 'sandwich.js', <<-EOS
19
+ // require egg
20
+ // require toast
21
+ var Sandwich = { }
22
+ EOS
23
+ end
24
+ end
@@ -0,0 +1,10 @@
1
+ module FileSystemStubs
2
+
3
+ ##
4
+ # stubs the filesystem methods that codependency
5
+ # uses to retrieve file contents
6
+ def file( filename, contents )
7
+ File.stub( :exist? ).with( filename ){ true }
8
+ IO.stub( :readlines ).with( filename ){ contents.strip.split( /^\s+/ ) }
9
+ end
10
+ end
@@ -0,0 +1,38 @@
1
+ shared_context 'solar system', :files => :planets do
2
+
3
+ before do
4
+ file 'body.rb', <<-EOS
5
+ class Body
6
+ end
7
+ EOS
8
+
9
+ file 'earth.rb', <<-EOS
10
+ # require planet
11
+
12
+ class Earth
13
+ end
14
+ EOS
15
+
16
+ file 'mars.rb', <<-EOS
17
+ # require planet
18
+
19
+ class Mars
20
+ end
21
+ EOS
22
+
23
+ file 'phobos.rb', <<-EOS
24
+ # require body
25
+ # require mars
26
+
27
+ class Phobos
28
+ end
29
+ EOS
30
+
31
+ file 'planet.rb', <<-EOS
32
+ # require body
33
+
34
+ class Planet
35
+ end
36
+ EOS
37
+ end
38
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codependency
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-09 00:00:00.000000000Z
12
+ date: 2012-07-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -48,12 +48,10 @@ files:
48
48
  - spec/codependency/graph_spec.rb
49
49
  - spec/codependency/node_spec.rb
50
50
  - spec/codependency/parser_spec.rb
51
- - spec/fixtures/body.rb
52
- - spec/fixtures/earth.rb
53
- - spec/fixtures/mars.rb
54
- - spec/fixtures/phobos.rb
55
- - spec/fixtures/planet.rb
56
51
  - spec/spec_helper.rb
52
+ - spec/support/breakfasts_context.rb
53
+ - spec/support/file_system_stubs.rb
54
+ - spec/support/planets_context.rb
57
55
  homepage: ''
58
56
  licenses: []
59
57
  post_install_message:
@@ -82,9 +80,7 @@ test_files:
82
80
  - spec/codependency/graph_spec.rb
83
81
  - spec/codependency/node_spec.rb
84
82
  - spec/codependency/parser_spec.rb
85
- - spec/fixtures/body.rb
86
- - spec/fixtures/earth.rb
87
- - spec/fixtures/mars.rb
88
- - spec/fixtures/phobos.rb
89
- - spec/fixtures/planet.rb
90
83
  - spec/spec_helper.rb
84
+ - spec/support/breakfasts_context.rb
85
+ - spec/support/file_system_stubs.rb
86
+ - spec/support/planets_context.rb
@@ -1,2 +0,0 @@
1
- class Body
2
- end
@@ -1,4 +0,0 @@
1
- # require planet
2
-
3
- class Earth
4
- end
@@ -1,4 +0,0 @@
1
- # require planet
2
-
3
- class Mars
4
- end
@@ -1,5 +0,0 @@
1
- # require body
2
- # require mars
3
-
4
- class Phobos
5
- end
@@ -1,4 +0,0 @@
1
- # require body
2
-
3
- class Planet
4
- end