license_finder 0.5.0 → 0.6.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.
Files changed (68) hide show
  1. data/.travis.yml +22 -0
  2. data/README.markdown +56 -92
  3. data/Rakefile +1 -1
  4. data/bin/license_finder +1 -1
  5. data/features/approve_dependencies.feature +49 -0
  6. data/features/html_report.feature +48 -0
  7. data/features/license_finder.feature +36 -0
  8. data/features/license_finder_rake_task.feature +36 -0
  9. data/features/rails_rake.feature +9 -0
  10. data/features/step_definitions/steps.rb +78 -31
  11. data/features/text_report.feature +27 -0
  12. data/lib/{templates/Apache.txt → data/licenses/Apache2.txt} +0 -0
  13. data/lib/{templates → data/licenses}/BSD.txt +0 -0
  14. data/lib/{templates → data/licenses}/GPLv2.txt +0 -0
  15. data/lib/{templates → data/licenses}/ISC.txt +0 -0
  16. data/lib/{templates → data/licenses}/LGPL.txt +0 -0
  17. data/lib/{templates → data/licenses}/MIT.txt +0 -0
  18. data/lib/{templates → data/licenses}/NewBSD.txt +0 -0
  19. data/lib/{templates → data/licenses}/Ruby.txt +0 -0
  20. data/lib/{templates → data/licenses}/SimplifiedBSD.txt +0 -0
  21. data/lib/license_finder.rb +11 -32
  22. data/lib/license_finder/bundle.rb +33 -0
  23. data/lib/license_finder/bundled_gem.rb +20 -14
  24. data/lib/license_finder/cli.rb +4 -3
  25. data/lib/license_finder/configuration.rb +34 -0
  26. data/lib/license_finder/dependency.rb +27 -22
  27. data/lib/license_finder/dependency_list.rb +35 -13
  28. data/lib/license_finder/license.rb +11 -1
  29. data/lib/license_finder/license/apache2.rb +8 -0
  30. data/lib/license_finder/license/bsd.rb +2 -0
  31. data/lib/license_finder/license/gplv2.rb +2 -0
  32. data/lib/license_finder/license/isc.rb +1 -0
  33. data/lib/license_finder/license/lgpl.rb +1 -0
  34. data/lib/license_finder/license/mit.rb +4 -1
  35. data/lib/license_finder/license/new_bsd.rb +3 -0
  36. data/lib/license_finder/license/ruby.rb +2 -2
  37. data/lib/license_finder/license/simplified_bsd.rb +3 -0
  38. data/lib/license_finder/license_url.rb +10 -0
  39. data/lib/license_finder/possible_license_file.rb +2 -2
  40. data/lib/license_finder/railtie.rb +1 -3
  41. data/lib/license_finder/reporter.rb +51 -0
  42. data/lib/license_finder/viewable.rb +31 -0
  43. data/lib/tasks/license_finder.rake +3 -28
  44. data/lib/templates/dependency.html.erb +54 -0
  45. data/lib/templates/dependency_list.html.erb +38 -0
  46. data/license_finder.gemspec +12 -4
  47. data/spec/lib/license_finder/bundled_gem_spec.rb +5 -3
  48. data/spec/lib/license_finder/dependency_list_spec.rb +54 -9
  49. data/spec/lib/license_finder/dependency_spec.rb +93 -57
  50. data/spec/lib/license_finder/license/apache_spec.rb +2 -2
  51. data/spec/lib/license_finder/license/mit_spec.rb +1 -1
  52. data/spec/lib/license_finder/license_spec.rb +14 -0
  53. data/spec/lib/license_finder/license_url_spec.rb +20 -0
  54. data/spec/lib/license_finder/reporter_spec.rb +5 -0
  55. data/spec/lib/license_finder_spec.rb +2 -0
  56. data/spec/spec_helper.rb +0 -1
  57. data/spec/support/license_examples.rb +6 -0
  58. metadata +68 -33
  59. data/features/executables/license_finder.feature +0 -19
  60. data/features/rake_tasks/action_items.feature +0 -27
  61. data/features/rake_tasks/action_items_ok.feature +0 -23
  62. data/features/rake_tasks/generate_dependencies.feature +0 -62
  63. data/features/rake_tasks/init.feature +0 -26
  64. data/features/rake_tasks/regressions.feature +0 -18
  65. data/lib/license_finder/bundler_dependency_query.rb +0 -51
  66. data/lib/license_finder/finder.rb +0 -39
  67. data/lib/license_finder/license/apache.rb +0 -5
  68. data/spec/lib/license_finder/finder_spec.rb +0 -36
@@ -23,10 +23,20 @@ module LicenseFinder::License
23
23
 
24
24
  class Base
25
25
  class << self
26
+ attr_accessor :license_url, :alternative_names
27
+
26
28
  def inherited(descendant)
27
29
  LicenseFinder::License.all << descendant
28
30
  end
29
31
 
32
+ def names
33
+ [demodulized_name] + self.alternative_names
34
+ end
35
+
36
+ def alternative_names
37
+ @alternative_names ||= []
38
+ end
39
+
30
40
  def demodulized_name
31
41
  name.gsub(/^.*::/, '')
32
42
  end
@@ -41,7 +51,7 @@ module LicenseFinder::License
41
51
 
42
52
  def license_text
43
53
  unless defined?(@license_text)
44
- template = File.join(LicenseFinder::ROOT_PATH, "templates", "#{demodulized_name}.txt").to_s
54
+ template = File.join(LicenseFinder::ROOT_PATH, "data", "licenses", "#{demodulized_name}.txt").to_s
45
55
 
46
56
  @license_text = Text.new(File.read(template)).to_s if File.exists?(template)
47
57
  end
@@ -0,0 +1,8 @@
1
+ class LicenseFinder::License::Apache2 < LicenseFinder::License::Base
2
+ self.alternative_names = ["Apache 2.0", "Apache2"]
3
+ self.license_url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
4
+
5
+ def self.pretty_name
6
+ 'Apache 2.0'
7
+ end
8
+ end
@@ -1,2 +1,4 @@
1
1
  class LicenseFinder::License::BSD < LicenseFinder::License::Base
2
+ self.alternative_names = ["BSD4", "bsd-old", "4-clause BSD"]
3
+ self.license_url = "http://en.wikipedia.org/wiki/BSD_licenses#4-clause_license_.28original_.22BSD_License.22.29"
2
4
  end
@@ -1,2 +1,4 @@
1
1
  class LicenseFinder::License::GPLv2 < LicenseFinder::License::Base
2
+ self.license_url = 'http://www.gnu.org/licenses/gpl-2.0.txt'
3
+ self.alternative_names = ["GPL V2", "gpl-v2", "GNU GENERAL PUBLIC LICENSE Version 2"]
2
4
  end
@@ -1,2 +1,3 @@
1
1
  class LicenseFinder::License::ISC < LicenseFinder::License::Base
2
+ self.license_url = "http://en.wikipedia.org/wiki/ISC_license"
2
3
  end
@@ -1,2 +1,3 @@
1
1
  class LicenseFinder::License::LGPL < LicenseFinder::License::Base
2
+ self.license_url = "http://www.gnu.org/licenses/lgpl.txt"
2
3
  end
@@ -1,7 +1,10 @@
1
1
  class LicenseFinder::License::MIT < LicenseFinder::License::Base
2
+ self.license_url = "http://opensource.org/licenses/mit-license"
3
+ self.alternative_names = ["Expat"]
4
+
2
5
  HEADER_REGEX = /The MIT Licen[sc]e/
3
6
  ONE_LINER_REGEX = /is released under the MIT licen[sc]e/
4
- URL_REGEX = %r{MIT Licen[sc]e.*http://www.opensource.org/licenses/mit-license}
7
+ URL_REGEX = %r{MIT Licen[sc]e.*http://(?:www.)?opensource.org/licenses/mit-license}
5
8
 
6
9
  def matches?
7
10
  super || matches_url? || matches_header?
@@ -1,4 +1,7 @@
1
1
  class LicenseFinder::License::NewBSD < LicenseFinder::License::Base
2
+ self.license_url = "http://opensource.org/licenses/BSD-3-Clause"
3
+ self.alternative_names = ["Modified BSD", "BSD3", "BSD-3", "3-clause BSD"]
4
+
2
5
  def self.pretty_name
3
6
  'New BSD'
4
7
  end
@@ -1,11 +1,11 @@
1
1
  class LicenseFinder::License::Ruby < LicenseFinder::License::Base
2
- URL_REGEX = %r{http://www.ruby-lang.org/en/LICENSE.txt}
2
+ self.license_url = "http://www.ruby-lang.org/en/LICENSE.txt"
3
3
 
4
4
  def self.pretty_name
5
5
  'ruby'
6
6
  end
7
7
 
8
8
  def matches?
9
- super || !!(text =~ URL_REGEX)
9
+ super || !!(text =~ /#{self.class.license_url}/)
10
10
  end
11
11
  end
@@ -1,4 +1,7 @@
1
1
  class LicenseFinder::License::SimplifiedBSD < LicenseFinder::License::Base
2
+ self.license_url = "http://opensource.org/licenses/bsd-license"
3
+ self.alternative_names = ["Simplified BSD", "FreeBSD", "2-clause BSD"]
4
+
2
5
  def self.pretty_name
3
6
  'Simplified BSD'
4
7
  end
@@ -0,0 +1,10 @@
1
+ module LicenseFinder::LicenseUrl
2
+ extend self
3
+
4
+ def find_by_name(name)
5
+ return unless name.respond_to?(:downcase)
6
+
7
+ license = LicenseFinder::License.all.detect {|l| l.names.map(&:downcase).include? name.downcase }
8
+ license.license_url if license
9
+ end
10
+ end
@@ -10,7 +10,7 @@ module LicenseFinder
10
10
  end
11
11
 
12
12
  def full_file_path
13
- @file_path.realpath.to_s
13
+ Pathname.new(@file_path).realpath.to_s
14
14
  end
15
15
 
16
16
  def file_name
@@ -26,7 +26,7 @@ module LicenseFinder
26
26
  klass.new(text).matches?
27
27
  end
28
28
 
29
- license && license.pretty_name
29
+ license.pretty_name if license
30
30
  end
31
31
  end
32
32
  end
@@ -1,9 +1,7 @@
1
- require 'license_finder'
2
- require 'rails'
3
1
  module LicenseFinder
4
2
  class Railtie < Rails::Railtie
5
3
  rake_tasks do
6
4
  load "tasks/license_finder.rake"
7
5
  end
8
6
  end
9
- end
7
+ end
@@ -0,0 +1,51 @@
1
+ module LicenseFinder
2
+ class Reporter
3
+ def self.create_default_configuration
4
+ unless File.exists?(LicenseFinder.config.config_file_path)
5
+ FileUtils.mkdir_p(File.join('.', 'config'))
6
+ FileUtils.cp(
7
+ File.join(File.dirname(__FILE__), '..', '..', 'files', 'license_finder.yml'),
8
+ LicenseFinder.config.config_file_path
9
+ )
10
+ end
11
+ end
12
+
13
+ def initialize
14
+ self.class.create_default_configuration
15
+ @dependency_list = generate_list
16
+ save_reports
17
+ end
18
+
19
+ def action_items
20
+ dependency_list.action_items
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :dependency_list
26
+
27
+ def save_reports
28
+ write_file LicenseFinder.config.dependencies_yaml, dependency_list.to_yaml
29
+ write_file LicenseFinder.config.dependencies_text, dependency_list.to_s
30
+ write_file LicenseFinder.config.dependencies_html, dependency_list.to_html
31
+ end
32
+
33
+ def write_file(file_path, content)
34
+ File.open(file_path, 'w+') do |f|
35
+ f.puts content
36
+ end
37
+ end
38
+
39
+ def generate_list
40
+ bundler_list = DependencyList.from_bundler
41
+
42
+ if File.exists?(LicenseFinder.config.dependencies_yaml)
43
+ yml = File.open(LicenseFinder.config.dependencies_yaml).readlines.join
44
+ existing_list = DependencyList.from_yaml(yml)
45
+ existing_list.merge(bundler_list)
46
+ else
47
+ bundler_list
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,31 @@
1
+ module LicenseFinder
2
+ module Viewable
3
+ def self.included(base)
4
+ base.class_eval do
5
+ extend ClassMethods
6
+ end
7
+ end
8
+
9
+ module ClassMethods
10
+ def underscored_name
11
+ @underscored_name ||= begin
12
+ str = name.dup
13
+ str.sub!(/.*::/, '')
14
+ str.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
15
+ str.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
16
+ str.downcase!
17
+ end
18
+ end
19
+ end
20
+
21
+ def to_yaml
22
+ as_yaml.to_yaml
23
+ end
24
+
25
+ def to_html
26
+ filename = File.join(File.dirname(__FILE__), '..', 'templates', "#{self.class.underscored_name}.html.erb")
27
+ template = ERB.new(File.read(filename))
28
+ template.result(binding)
29
+ end
30
+ end
31
+ end
@@ -1,29 +1,4 @@
1
- namespace :license do
2
- desc 'write out example config file'
3
- task :init do
4
- `mkdir -p ./config`
5
- FileUtils.cp(File.join(File.dirname(__FILE__), '..', '..', 'files', 'license_finder.yml'), './config/license_finder.yml')
6
- end
7
-
8
- desc 'generate a list of dependency licenses'
9
- task :generate_dependencies do
10
- LicenseFinder::Finder.new.write_files
11
- end
12
-
13
- desc 'action items'
14
- task :action_items => :generate_dependencies do
15
- LicenseFinder::CLI.new.check_for_action_items
16
- end
17
-
18
- desc 'return a failure status code for unapproved dependencies'
19
- task 'action_items:ok' => :generate_dependencies do
20
- puts "rake license:action_items:ok is deprecated and will be removed in version 1.0. Use rake license:action_items instead."
21
-
22
- found = LicenseFinder::Finder.new.action_items
23
- if found.size == 0
24
- puts "All gems are approved for use"
25
- else
26
- exit 1
27
- end
28
- end
1
+ desc 'Audit your Gemfile for software licenses. This is the same as running `license_finder` in the terminal.'
2
+ task :license_finder do
3
+ LicenseFinder::CLI.check_for_action_items
29
4
  end
@@ -0,0 +1,54 @@
1
+ <div id="<%= name %>" class="<%= approved ? "approved" : "unapproved" %>">
2
+ <h2>
3
+ <% if homepage && !homepage.empty? %>
4
+ <a href="<%= homepage %>"><%= name %></a>
5
+ <% else %>
6
+ <%= name %>
7
+ <% end %>
8
+ v<%= version %>
9
+ <% if bundler_groups.any? %>
10
+ (<%= bundler_groups.join(", ") %>)
11
+ <% end %>
12
+ </h2>
13
+ <table class="table table-striped table-bordered">
14
+ <thead>
15
+ <tr>
16
+ <th>Summary</th>
17
+ <th>Description</th>
18
+ <th>License</th>
19
+ </tr>
20
+ </thead>
21
+ <tbody>
22
+ <tr>
23
+ <td><%= summary %></td>
24
+ <td><%= description %></td>
25
+ <td>
26
+ <% if license_url && !license_url.empty? %>
27
+ <a href="<%= license_url %>"><%= license %></a>
28
+ <% else %>
29
+ <%= license %>
30
+ <% end %>
31
+ </td>
32
+ </td>
33
+ </tr>
34
+ </tbody>
35
+ </table>
36
+
37
+ <% if parents.any? %>
38
+ <dl>
39
+ <dt>Parents</dt>
40
+ <% parents.each do |parent| %>
41
+ <dd><%= parent.name %></dd>
42
+ <% end %>
43
+ </dl>
44
+ <% end %>
45
+
46
+ <% if children.any? %>
47
+ <dl>
48
+ <dt>Children</dt>
49
+ <% children.each do |child| %>
50
+ <dd><%= child.name %></dd>
51
+ <% end %>
52
+ </dl>
53
+ <% end %>
54
+ </div>
@@ -0,0 +1,38 @@
1
+ <html>
2
+ <head>
3
+ <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap.min.css" rel="stylesheet">
4
+ <style type="text/css">
5
+ body {
6
+ margin: 50px;
7
+ }
8
+
9
+ .unapproved h2, .unapproved h2 a {
10
+ color: red;
11
+ }
12
+ </style>
13
+ </head>
14
+ <body>
15
+ <div class="container">
16
+ <div class="summary hero-unit">
17
+ <h1>Dependencies</h1>
18
+
19
+ <h4>
20
+ <%= dependencies.size %> total
21
+
22
+ <% if unapproved_dependencies.any? %>
23
+ <span class="badge badge-important"><%= unapproved_dependencies.size %> unapproved</span>
24
+ <% end %>
25
+ </h4>
26
+
27
+ <ul>
28
+ <% grouped_dependencies.each do |license, group| %>
29
+ <li><%= group.size %> <%= license %></li>
30
+ <% end %>
31
+ </ul>
32
+ </div>
33
+ <div class="dependencies">
34
+ <%= sorted_dependencies.map(&:to_html).join("\n") %>
35
+ </div>
36
+ </div>
37
+ </body>
38
+ </html>
@@ -1,16 +1,24 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "license_finder"
3
- s.version = "0.5.0"
3
+ s.version = "0.6.0"
4
4
  s.authors = ["Jacob Maine", "Matthew Kane Parker", "Ian Lesperance", "David Edwards", "Paul Meskers"]
5
5
  s.email = ["brent@pivotalabs.com"]
6
6
  s.homepage = "https://github.com/pivotal/LicenseFinder"
7
- s.summary = "Know your dependencies - and the licenses they are binding your application to."
8
- s.description = "Find and display licenses of a project's gem dependencies, so that you know what your limitations are when distributing your application."
7
+ s.summary = "Audit the OSS licenses of your application's dependencies."
8
+
9
+ s.description = <<-DESCRIPTION
10
+ Do you know the licenses of all your application's dependencies? What open source software licenses will your business accept?
11
+
12
+ LicenseFinder culls your Gemfile, detects the licenses of the gems in it, and gives you a report that you can act on. If you already know
13
+ what licenses your business is comfortable with, you can whitelist them, leaving you with an action report of only those dependencies that have
14
+ licenses that fall outside of the whitelist.
15
+ DESCRIPTION
16
+
9
17
  s.license = "MIT"
10
18
 
11
19
  s.add_dependency "bundler"
12
20
  s.add_development_dependency "rails", ">=3"
13
- %w(rspec rr rake cucumber rails pry).each do |gem|
21
+ %w(rspec rr rake cucumber rails pry capybara).each do |gem|
14
22
  s.add_development_dependency gem
15
23
  end
16
24
 
@@ -9,11 +9,12 @@ describe LicenseFinder::BundledGem do
9
9
  s.version = '2.1.3'
10
10
  s.summary = 'summary'
11
11
  s.description = 'description'
12
+ s.homepage = 'homepage'
12
13
  end
13
14
  end
14
15
 
15
16
  def fixture_path(fixture)
16
- File.realpath(File.join(File.dirname(__FILE__), '..', '..', '..', 'spec', 'fixtures', fixture))
17
+ Pathname.new(File.join(File.dirname(__FILE__), '..', '..', '..', 'spec', 'fixtures', fixture)).realpath.to_s
17
18
  end
18
19
 
19
20
  its(:name) { should == 'spec_name 2.1.3' }
@@ -108,14 +109,15 @@ describe LicenseFinder::BundledGem do
108
109
  end
109
110
  end
110
111
 
111
- describe '#dependency' do
112
- subject { LicenseFinder::BundledGem.new(gemspec).dependency }
112
+ describe '#to_dependency' do
113
+ subject { LicenseFinder::BundledGem.new(gemspec).to_dependency }
113
114
 
114
115
  its(:name) { should == 'spec_name' }
115
116
  its(:version) { should == '2.1.3' }
116
117
  its(:summary) { should == 'summary' }
117
118
  its(:source) { should == 'bundle' }
118
119
  its(:description) { should == 'description' }
120
+ its(:homepage) { should == 'homepage' }
119
121
 
120
122
  describe 'with a known license' do
121
123
  before do
@@ -1,12 +1,16 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe LicenseFinder::DependencyList do
4
- def build_gemspec(name, version)
4
+ def build_gemspec(name, version, dependency=nil)
5
5
  Gem::Specification.new do |s|
6
6
  s.name = name
7
7
  s.version = version
8
8
  s.summary = 'summary'
9
9
  s.description = 'description'
10
+
11
+ if dependency
12
+ s.add_dependency dependency
13
+ end
10
14
  end
11
15
  end
12
16
 
@@ -37,6 +41,24 @@ describe LicenseFinder::DependencyList do
37
41
  subject.dependencies[1].name.should == 'gem2'
38
42
  subject.dependencies[1].version.should == '0.4.2'
39
43
  end
44
+
45
+ context "when initialized with a parent and child gem" do
46
+ subject do
47
+ bundle = stub(Bundler::Definition).build.stub!
48
+ bundle.dependencies { [] }
49
+ bundle.groups { [] }
50
+ bundle.specs_for { [build_gemspec('gem1', '1.2.3', 'gem2'), build_gemspec('gem2', '0.4.2')] }
51
+
52
+ LicenseFinder::DependencyList.from_bundler
53
+ end
54
+
55
+ it "should update the child dependency with its parent data" do
56
+ gem1 = subject.dependencies.first
57
+ gem2 = subject.dependencies.last
58
+
59
+ gem2.parents.should == [gem1]
60
+ end
61
+ end
40
62
  end
41
63
 
42
64
  describe '#from_yaml' do
@@ -74,7 +96,8 @@ describe LicenseFinder::DependencyList do
74
96
  'license' => 'MIT',
75
97
  'approved' => false,
76
98
  'source' => nil,
77
- 'license_url' => '',
99
+ 'homepage' => nil,
100
+ 'license_url' => LicenseFinder::License::MIT.license_url,
78
101
  'notes' => '',
79
102
  'license_files' => nil,
80
103
  'readme_files' => nil
@@ -85,7 +108,8 @@ describe LicenseFinder::DependencyList do
85
108
  'license' => 'MIT',
86
109
  'approved' => false,
87
110
  'source' => 'bundle',
88
- 'license_url' => '',
111
+ 'homepage' => nil,
112
+ 'license_url' => LicenseFinder::License::MIT.license_url,
89
113
  'notes' => '',
90
114
  'license_files' => nil,
91
115
  'readme_files' => nil
@@ -175,24 +199,45 @@ describe LicenseFinder::DependencyList do
175
199
  describe "#to_s" do
176
200
  it "should return a human readable list of dependencies" do
177
201
 
178
- gem1 = Struct.new(:name, :to_s).new("a", "a string ")
202
+ gem1 = Struct.new(:name, :to_s).new("a", "a string")
179
203
  gem2 = Struct.new(:name, :to_s).new("b", "b string")
180
204
 
181
205
  list = LicenseFinder::DependencyList.new([gem2, gem1])
182
206
 
183
- list.to_s.should == "a string b string"
207
+ list.to_s.should == "a string\nb string"
184
208
  end
185
209
  end
186
210
 
187
211
  describe '#action_items' do
188
212
  it "should return all unapproved dependencies" do
189
- gem1 = Struct.new(:name, :to_s, :approved).new("a", "a string ", true)
190
- gem2 = Struct.new(:name, :to_s, :approved).new("b", "b string ", false)
191
- gem3 = Struct.new(:name, :to_s, :approved).new("c", "c string", false)
213
+ gem1 = LicenseFinder::Dependency.new('name' => 'a', 'approved' => true)
214
+ stub(gem1).to_s { 'a string' }
215
+
216
+ gem2 = LicenseFinder::Dependency.new('name' => 'b', 'approved' => false)
217
+ stub(gem2).to_s { 'b string' }
218
+
219
+ gem3 = LicenseFinder::Dependency.new('name' => 'c', 'approved' => false)
220
+ stub(gem3).to_s { 'c string' }
192
221
 
193
222
  list = LicenseFinder::DependencyList.new([gem1, gem2, gem3])
194
223
 
195
- list.action_items.should == "b string c string"
224
+ list.action_items.should == "b string\nc string"
225
+ end
226
+ end
227
+
228
+ describe '#to_html' do
229
+ it "should concatenate the results of the each dependency's #to_html and plop it into a proper HTML document" do
230
+ gem1 = LicenseFinder::Dependency.new('name' => 'a')
231
+ stub(gem1).to_html { 'A' }
232
+
233
+ gem2 = LicenseFinder::Dependency.new('name' => 'b')
234
+ stub(gem2).to_html { 'B' }
235
+
236
+ list = LicenseFinder::DependencyList.new([gem1, gem2])
237
+
238
+ html = list.to_html
239
+ html.should include "A"
240
+ html.should include "B"
196
241
  end
197
242
  end
198
243
  end