codependency 0.1.0 → 0.2.0

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.
@@ -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