license_finder 0.7.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/.gitignore +4 -3
  2. data/.travis.yml +1 -8
  3. data/bin/license_finder +31 -1
  4. data/db/migrate/201303290935_create_dependencies.rb +14 -0
  5. data/db/migrate/201303291155_create_licenses.rb +13 -0
  6. data/db/migrate/201303291402_create_approvals.rb +13 -0
  7. data/db/migrate/201303291456_create_ancestries.rb +9 -0
  8. data/db/migrate/201303291519_create_bundler_groups.rb +13 -0
  9. data/db/migrate/201303291720_move_manual_from_approvals_to_licenses.rb +11 -0
  10. data/db/migrate/201303291753_allow_null_license_names.rb +7 -0
  11. data/db/migrate/201304011027_allow_null_dependency_version.rb +7 -0
  12. data/db/migrate/201304020947_change_table_name_licenses_to_license_aliases.rb +5 -0
  13. data/features/approve_dependencies.feature +0 -45
  14. data/features/html_report.feature +1 -11
  15. data/features/license_finder.feature +13 -27
  16. data/features/license_finder_rake_task.feature +2 -1
  17. data/features/set_license.feature +2 -4
  18. data/features/step_definitions/license_finder_steps.rb +25 -0
  19. data/features/step_definitions/steps.rb +40 -26
  20. data/features/text_report.feature +2 -2
  21. data/files/license_finder.yml +1 -1
  22. data/lib/license_finder.rb +14 -6
  23. data/lib/license_finder/bundle.rb +4 -17
  24. data/lib/license_finder/bundle_syncer.rb +2 -3
  25. data/lib/license_finder/bundled_gem.rb +4 -47
  26. data/lib/license_finder/cli.rb +9 -16
  27. data/lib/license_finder/configuration.rb +55 -3
  28. data/lib/license_finder/dependency_report.rb +1 -1
  29. data/lib/license_finder/gem_saver.rb +69 -0
  30. data/lib/license_finder/html_report.rb +2 -2
  31. data/lib/license_finder/license.rb +60 -58
  32. data/lib/license_finder/license_files.rb +36 -0
  33. data/lib/license_finder/license_url.rb +8 -6
  34. data/lib/license_finder/platform.rb +32 -0
  35. data/lib/license_finder/possible_license_file.rb +1 -1
  36. data/lib/license_finder/tables.rb +7 -0
  37. data/lib/license_finder/tables/approval.rb +4 -0
  38. data/lib/license_finder/tables/bundler_group.rb +4 -0
  39. data/lib/license_finder/tables/dependency.rb +31 -0
  40. data/lib/license_finder/tables/license_alias.rb +22 -0
  41. data/lib/license_finder/yml_to_sql.rb +127 -0
  42. data/lib/tasks/license_finder.rake +3 -0
  43. data/lib/templates/html_report.erb +50 -32
  44. data/lib/templates/text_report.erb +3 -2
  45. data/license_finder.gemspec +14 -5
  46. data/readme.md +10 -50
  47. data/spec/lib/license_finder/bundle_spec.rb +22 -19
  48. data/spec/lib/license_finder/bundle_syncer_spec.rb +4 -10
  49. data/spec/lib/license_finder/bundled_gem_spec.rb +40 -108
  50. data/spec/lib/license_finder/cli_spec.rb +3 -3
  51. data/spec/lib/license_finder/configuration_spec.rb +53 -21
  52. data/spec/lib/license_finder/gem_saver_spec.rb +155 -0
  53. data/spec/lib/license_finder/html_report_spec.rb +32 -15
  54. data/spec/lib/license_finder/license_files_spec.rb +50 -0
  55. data/spec/lib/license_finder/tables/dependency_spec.rb +102 -0
  56. data/spec/lib/license_finder/tables/license_alias_spec.rb +54 -0
  57. data/spec/lib/license_finder/text_report_spec.rb +6 -4
  58. data/spec/lib/license_finder/yml_to_sql_spec.rb +99 -0
  59. data/spec/lib/license_finder_spec.rb +5 -5
  60. data/spec/spec_helper.rb +17 -1
  61. metadata +79 -32
  62. data/lib/license_finder/dependency.rb +0 -50
  63. data/lib/license_finder/persistence.rb +0 -1
  64. data/lib/license_finder/persistence/yaml.rb +0 -7
  65. data/lib/license_finder/persistence/yaml/configuration.rb +0 -34
  66. data/lib/license_finder/persistence/yaml/dependency.rb +0 -127
  67. data/lib/license_finder/source_syncer.rb +0 -40
  68. data/lib/templates/dependency.html.erb +0 -54
  69. data/spec/lib/license_finder/dependency_spec.rb +0 -188
  70. data/spec/lib/license_finder/persistence/yaml/dependency_spec.rb +0 -5
  71. data/spec/lib/license_finder/source_syncer_spec.rb +0 -37
  72. data/spec/support/shared_examples/persistence/configuration.rb +0 -28
  73. data/spec/support/shared_examples/persistence/dependency.rb +0 -138
data/readme.md CHANGED
@@ -7,10 +7,10 @@ With bundler it's easy for your project to depend on many gems. This decomposit
7
7
 
8
8
  ## Installation
9
9
 
10
- Add license_finder to your Rails project's Gemfile and `bundle`:
10
+ Add license_finder to your project's Gemfile and `bundle`:
11
11
 
12
12
  ```ruby
13
- gem 'license_finder', git: "https://github.com/pivotal/LicenseFinder.git"
13
+ gem 'license_finder'
14
14
  ```
15
15
 
16
16
  ## Usage
@@ -18,7 +18,7 @@ gem 'license_finder', git: "https://github.com/pivotal/LicenseFinder.git"
18
18
  License finder will generate reports of action items - i.e., dependencies that do not fall within your license "whitelist".
19
19
 
20
20
  ```sh
21
- $ bundle exec license_finder
21
+ $ license_finder
22
22
  ```
23
23
 
24
24
  The first time you run this, `license_finder` will create a default configuration file `./config/license_finder.yml`:
@@ -32,6 +32,7 @@ whitelist:
32
32
  ignore_groups:
33
33
  #- test
34
34
  #- development
35
+ dependencies_file_dir: './doc/'
35
36
  ```
36
37
 
37
38
  This allows you to configure bundler groups and add licenses to the whitelist.
@@ -51,7 +52,7 @@ rubyzip, 0.9.9, ruby
51
52
  xml-simple, 1.1.1, other
52
53
  ```
53
54
 
54
- The executable task will also write out a dependencies.yml, dependencies.txt, and dependencies.html file in the root of your project.
55
+ The executable task will also write out a dependencies.db, dependencies.txt, and dependencies.html file in the doc/ directory (by default).
55
56
 
56
57
  The latter two files are human readable reports that you could send to your non-technical business partners, lawyers, etc.
57
58
 
@@ -59,15 +60,9 @@ The latter two files are human readable reports that you could send to your non-
59
60
  unapproved dependencies. You could use this in a CI build, for example, to alert you whenever someone adds an
60
61
  unapproved dependency to the project.
61
62
 
62
- It will also merge in an existing dependencies.yml file, if one exists (i.e., you've previously run this command
63
- and then edited the resulting file).
64
-
65
63
  ### Manually recording licenses
66
64
 
67
- When you have dependencies marked as having an 'other' license, `license_finder` will output
68
- the license and readme file locations for the dependency, allowing you to manually research what the actual
69
- license is. Once this has been established, you can record this information with the `-l` option
70
- as such:
65
+ When you have dependencies marked as having an 'other' license, `license_finder` you should manually research what the actual license is. Once this has been established, you can record this information with the `-l` or `--license` option as such:
71
66
 
72
67
  ```sh
73
68
  $ license_finder -l MIT my_unknown_dependency
@@ -82,7 +77,7 @@ If your business decides that this is an acceptable risk, you can manually appro
82
77
  `--approve` option of the `license_finder` command.
83
78
 
84
79
  For example, lets assume you've only
85
- whitelisted the "MIT" license in your `config/license_finder.yml`. You then add the 'awesome_gpl_gem' to your Gemfile,
80
+ whitelisted the "MIT" license in your `config/license_finder.yml`. You then add the `awesome_gpl_gem` to your Gemfile,
86
81
  which we'll assume is licensed with the `GPL` license. You then run `license_finder` and see
87
82
  the gem listed in the output:
88
83
 
@@ -93,49 +88,14 @@ awesome_gpl_gem, 1.0.0, GPL
93
88
  Your business tells you that in this case, it's acceptable to use this gem. You now run:
94
89
 
95
90
  ```sh
96
- $ bundle exec license_finder -a awesome_gpl_gem
91
+ $ license_finder -a awesome_gpl_gem
97
92
  ```
98
93
 
99
94
  If you rerun `license_finder`, you should no longer see `awesome_gpl_gem` in the output.
100
95
 
96
+ ## Compatibility
101
97
 
102
- ## Manually managing Javascript Dependencies
103
-
104
- License Finder currently has no method for automatically detecting third-party javascript libraries in your application
105
- and alerting you to license violations. However, you can manually add javascript dependencies to your `dependencies.yml`
106
- file:
107
-
108
- ```yaml
109
- - name: "my_javascript_library"
110
- version: "0.0.0"
111
- license: "GPL"
112
- approved: false
113
- ```
114
-
115
- You could then update the "approved" attribute to true once you have signoff from your business. License Finder will
116
- remember any manually added licenses between successive runs.
117
-
118
-
119
- ## Usage with Rake
120
-
121
- First, add license finder to your project's Gemfile:
122
-
123
- ```ruby
124
- gem "license_finder"
125
- ```
126
-
127
- Next, update your project's Rakefile with the license finder rake task:
128
-
129
- ```ruby
130
- require 'bundler/setup'
131
- require 'license_finder'
132
- LicenseFinder.load_rake_tasks
133
- ```
134
-
135
- You can now run `bundle exec rake license_finder`. This is the equivalent of running `bundle exec license_finder`.
136
-
137
- This could be handy if you have a build for CI that you want to break when you have unapproved dependencies. The
138
- rake task will `exit 1` immediately if there are unapproved dependencies, stopping your build dead in its tracks!
98
+ license_finder is compatible with ruby 1.9, and ruby 2.0. There is also experimental support for jruby.
139
99
 
140
100
  ## A note to gem authors / maintainers
141
101
 
@@ -2,6 +2,17 @@ require "spec_helper"
2
2
 
3
3
  module LicenseFinder
4
4
  describe Bundle do
5
+ let(:definition) do
6
+ double('definition', {
7
+ :dependencies => [],
8
+ :groups => [],
9
+ :specs_for => [
10
+ build_gemspec('gem1', '1.2.3'),
11
+ build_gemspec('gem2', '0.4.2')
12
+ ]
13
+ })
14
+ end
15
+
5
16
  def build_gemspec(name, version, dependency=nil)
6
17
  Gem::Specification.new do |s|
7
18
  s.name = name
@@ -15,28 +26,20 @@ module LicenseFinder
15
26
  end
16
27
  end
17
28
 
18
- describe '.from_bundler(bundle)' do
19
- let(:definition) do
20
- double('definition', {
21
- :dependencies => [],
22
- :groups => [],
23
- :specs_for => [
24
- build_gemspec('gem1', '1.2.3'),
25
- build_gemspec('gem2', '0.4.2')
26
- ]
27
- })
28
- end
29
-
29
+ describe '.current_gem_dependencies' do
30
30
  subject do
31
- Bundle.new(definition).gems.map(&:to_dependency)
31
+ Bundle.current_gem_dependencies(definition)
32
32
  end
33
33
 
34
- its(:count) { should == 2 }
35
-
36
34
  it "should have 2 dependencies" do
37
35
  subject.size.should == 2
38
36
  end
39
37
 
38
+ it "returns persisted dependencies" do
39
+ subject.first.id.should be
40
+ subject.last.id.should be
41
+ end
42
+
40
43
  context "when initialized with a parent and child gem" do
41
44
  before do
42
45
  definition.stub(:specs_for).and_return([
@@ -46,11 +49,11 @@ module LicenseFinder
46
49
  end
47
50
 
48
51
  it "should update the child dependency with its parent data" do
49
- gem1 = subject.first
50
- gem2 = subject.last
52
+ gem1 = subject.first.reload
53
+ gem2 = subject.last.reload
51
54
 
52
- gem2.parents.should == [gem1.name]
53
- gem1.children.should == [gem2.name]
55
+ gem2.parents.should == [gem1]
56
+ gem1.children.should == [gem2]
54
57
  end
55
58
  end
56
59
  end
@@ -3,16 +3,10 @@ require "spec_helper"
3
3
  module LicenseFinder
4
4
  describe BundleSyncer do
5
5
  describe "#sync!" do
6
- it "should delegate the bundled dependencies and the persisted bundled dependencies to the source syncer" do
7
- gem = double :gem, :to_dependency => double(:gem_dependency)
8
- bundled_dep = double :bundled_dep, source: "bundle"
9
- manual_dep = double :manual_dep, source: nil
10
- syncer = double :source_syncer
11
-
12
- Bundle.stub_chain(:new, :gems).and_return [gem]
13
- Dependency.stub(:all).and_return [bundled_dep, manual_dep]
14
- SourceSyncer.should_receive(:new).with([gem.to_dependency], [bundled_dep]).and_return syncer
15
- syncer.should_receive(:sync!)
6
+ it "saves new, updates old, and destroys obsolete gems" do
7
+ current_dependencies = stub
8
+ Bundle.stub(:current_gem_dependencies).and_return { current_dependencies }
9
+ Dependency.should_receive(:destroy_obsolete).with(current_dependencies)
16
10
 
17
11
  BundleSyncer.sync!
18
12
  end
@@ -1,129 +1,61 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe LicenseFinder::BundledGem do
4
- subject { LicenseFinder::BundledGem.new(gemspec) }
5
-
6
- let(:gemspec) do
7
- Gem::Specification.new do |s|
8
- s.name = 'spec_name'
9
- s.version = '2.1.3'
10
- s.summary = 'summary'
11
- s.description = 'description'
12
- s.homepage = 'homepage'
13
-
14
- s.add_dependency 'foo'
15
- end
16
- end
17
-
18
- def fixture_path(fixture)
19
- Pathname.new(File.join(File.dirname(__FILE__), '..', '..', '..', 'spec', 'fixtures', fixture)).realpath.to_s
20
- end
21
-
22
- its(:name) { should == 'spec_name 2.1.3' }
23
- its(:dependency_name) { should == 'spec_name' }
24
- its(:dependency_version) { should == '2.1.3' }
25
- its(:install_path) { should == gemspec.full_gem_path }
26
-
27
- describe "#determine_license" do
28
- subject do
29
- details = LicenseFinder::BundledGem.new(gemspec)
30
- details.stub(:license_files).and_return([license_file])
31
- details
32
- end
33
-
34
- let(:license_file) { LicenseFinder::PossibleLicenseFile.new('gem', 'gem/license/path') }
35
-
36
- it "returns the license from the gemspec if provided" do
37
- gemspec.stub(:license).and_return('Some License')
38
-
39
- subject.determine_license.should == "Some License"
40
- end
41
-
42
- it "returns the matched license if detected" do
43
- license_file.stub(:license).and_return('Detected License')
44
-
45
- subject.determine_license.should == "Detected License"
46
- end
47
-
48
- it "returns 'other' otherwise" do
49
- license_file.stub(:license).and_return(nil)
50
-
51
- subject.determine_license.should == "other"
52
- end
53
- end
54
-
55
- describe "#license_files" do
56
- it "is empty if there aren't any license files" do
57
- subject.license_files.should == []
58
- end
59
-
60
- it "includes files with names like LICENSE, License or COPYING" do
61
- gemspec.stub(:full_gem_path).and_return(fixture_path('license_names'))
62
-
63
- subject.license_files.map(&:file_name).should =~
64
- %w[COPYING.txt LICENSE Mit-License README.rdoc Licence.rdoc]
3
+ module LicenseFinder
4
+ describe BundledGem do
5
+ subject { described_class.new(gemspec) }
6
+
7
+ let(:gemspec) do
8
+ Gem::Specification.new do |s|
9
+ s.name = 'spec_name'
10
+ s.version = '2.1.3'
11
+ s.summary = 'summary'
12
+ s.description = 'description'
13
+ s.homepage = 'homepage'
14
+
15
+ s.add_dependency 'foo'
16
+ end
65
17
  end
66
18
 
67
- it "includes files deep in the hierarchy" do
68
- gemspec.stub(:full_gem_path).and_return(fixture_path('nested_gem'))
69
-
70
- subject.license_files.map { |f| [f.file_name, f.file_path] }.should =~ [
71
- %w[LICENSE vendor/LICENSE]
72
- ]
19
+ def fixture_path(fixture)
20
+ Pathname.new(File.join(File.dirname(__FILE__), '..', '..', '..', 'spec', 'fixtures', fixture)).realpath.to_s
73
21
  end
74
22
 
75
- it "includes both files nested inside LICENSE directory and top level files" do
76
- gemspec.stub(:full_gem_path).and_return(fixture_path('license_directory'))
77
- found_license_files = subject.license_files
23
+ its(:name) { should == 'spec_name 2.1.3' }
24
+ its(:dependency_name) { should == 'spec_name' }
25
+ its(:dependency_version) { should == '2.1.3' }
78
26
 
79
- found_license_files.map { |f| [f.file_name, f.file_path] }.should =~ [
80
- %w[BSD-2-Clause.txt LICENSE/BSD-2-Clause.txt],
81
- %w[GPL-2.0.txt LICENSE/GPL-2.0.txt],
82
- %w[MIT.txt LICENSE/MIT.txt],
83
- %w[RUBY.txt LICENSE/RUBY.txt],
84
- %w[COPYING COPYING],
85
- %w[LICENSE LICENSE/LICENSE]
86
- ]
87
- end
88
- end
27
+ describe "#determine_license" do
28
+ subject do
29
+ details = BundledGem.new(gemspec)
30
+ details.stub(:license_files).and_return([license_file])
31
+ details
32
+ end
89
33
 
90
- describe '#to_dependency' do
91
- subject { LicenseFinder::BundledGem.new(gemspec).to_dependency }
34
+ let(:license_file) { PossibleLicenseFile.new('gem', 'gem/license/path') }
92
35
 
93
- its(:name) { should == 'spec_name' }
94
- its(:version) { should == '2.1.3' }
95
- its(:summary) { should == 'summary' }
96
- its(:source) { should == 'bundle' }
97
- its(:description) { should == 'description' }
98
- its(:homepage) { should == 'homepage' }
99
- its(:children) { should == ['foo']}
36
+ it "returns the license from the gemspec if provided" do
37
+ gemspec.stub(:license).and_return('Some License')
100
38
 
101
- describe 'with a known license' do
102
- before do
103
- gemspec.stub(:full_gem_path).and_return(fixture_path('mit_licensed_gem'))
104
- LicenseFinder::PossibleLicenseFile.any_instance.stub(:license).and_return('Detected License')
39
+ subject.determine_license.should == "Some License"
105
40
  end
106
41
 
107
- its(:license) { should == 'Detected License' }
108
- its(:license_files) { should == ["LICENSE"] }
109
- end
42
+ it "returns the matched license if detected" do
43
+ license_file.stub(:license).and_return('Detected License')
110
44
 
111
- describe 'with an unknown license' do
112
- before do
113
- gemspec.stub(:full_gem_path).and_return(fixture_path('other_licensed_gem'))
114
- LicenseFinder::PossibleLicenseFile.any_instance.stub(:license).and_return(nil)
45
+ subject.determine_license.should == "Detected License"
115
46
  end
116
47
 
117
- its(:license) { should == 'other' }
118
- end
48
+ it "returns 'other' otherwise" do
49
+ license_file.stub(:license).and_return(nil)
119
50
 
120
- describe 'with UTF8 file License' do
121
- before do
122
- gemspec.stub(:full_gem_path).and_return(fixture_path('utf8_gem'))
51
+ subject.determine_license.should == "other"
123
52
  end
53
+ end
124
54
 
125
- it "handles non UTF8 encodings" do
126
- expect { subject }.not_to raise_error ArgumentError, "invalid byte sequence in UTF-8"
55
+ describe "#license_files" do
56
+ it "delegates to the license files helper" do
57
+ LicenseFiles.should_receive(:new).with(gemspec.full_gem_path) { stub(files: [] )}
58
+ subject.license_files
127
59
  end
128
60
  end
129
61
  end
@@ -10,7 +10,7 @@ module LicenseFinder
10
10
  dependency = double('dependency', :name => nil)
11
11
  dependency.should_receive(:approve!)
12
12
 
13
- Dependency.stub(:find_by_name).with('foo').and_return(dependency)
13
+ Dependency.stub(:first).with(name: 'foo').and_return(dependency)
14
14
 
15
15
  CLI.execute! approve: true, dependency: 'foo'
16
16
  end
@@ -19,9 +19,9 @@ module LicenseFinder
19
19
  context "when the -l (--license) switch is provided" do
20
20
  it "should update the license on the requested gem" do
21
21
  dependency = double :dependency, :name => nil
22
- dependency.should_receive(:update_attributes).with(:license => "foo")
22
+ dependency.should_receive(:set_license_manually).with("foo")
23
23
 
24
- Dependency.stub(:find_by_name).with("foo_gem").and_return dependency
24
+ Dependency.stub(:first).with(name: "foo_gem").and_return dependency
25
25
 
26
26
  CLI.execute! license: "foo", dependency: 'foo_gem'
27
27
  end
@@ -1,38 +1,70 @@
1
1
  require "spec_helper"
2
2
 
3
- describe LicenseFinder::Configuration do
4
- it_behaves_like "a persistable configuration"
3
+ module LicenseFinder
4
+ describe Configuration do
5
+ let(:config) { described_class.new }
5
6
 
6
- let(:config) { LicenseFinder::Configuration.new }
7
+ let(:klass) { described_class }
7
8
 
8
- describe "whitelisted?" do
9
- context "canonical name whitelisted" do
10
- before { config.whitelist = [LicenseFinder::License::Apache2.names[rand(LicenseFinder::License::Apache2.names.count)]]}
9
+ describe '.new' do
10
+ let(:attributes) do
11
+ {
12
+ "whitelist" => ["FooLicense", "BarLicense"],
13
+ "ignore_groups" => [:test, :development],
14
+ "dependencies_file_dir" => "."
15
+ }
16
+ end
11
17
 
12
- let(:possible_license_names) { LicenseFinder::License::Apache2.names }
18
+ subject { klass.new(attributes) }
13
19
 
14
- it "should return true if if the license is the canonical name, pretty name, or alternative name of the license" do
15
- possible_license_names.each do |name|
16
- config.whitelisted?(name).should be_true, "expected #{name} to be whitelisted, but wasn't."
20
+ context "with known attributes" do
21
+ it "should set the all of the attributes on the instance" do
22
+ subject.whitelist.should == attributes['whitelist']
23
+ subject.ignore_groups.should == attributes['ignore_groups']
24
+ subject.dependencies_dir.should == attributes['dependencies_file_dir']
17
25
  end
18
26
  end
19
27
 
20
- it "should be case-insensitive" do
21
- possible_license_names.map(&:downcase).each do |name|
22
- config.whitelisted?(name).should be_true, "expected #{name} to be whitelisted, but wasn't"
23
- end
28
+ it "uses absolute path in database_path" do
29
+ subject.database_path.should_not start_with(".")
24
30
  end
25
31
  end
26
- end
27
32
 
28
- describe "#ignore_groups" do
29
- it "should default to an empty array" do
30
- config.ignore_groups.should == []
33
+ describe "#whitelist" do
34
+ it "should default to an empty array" do
35
+ klass.new.whitelist.should == []
36
+ end
31
37
  end
32
38
 
33
- it "should always return symbolized versions of the ignore groups" do
34
- config.ignore_groups = %w[test development]
35
- config.ignore_groups.should == [:test, :development]
39
+ describe "whitelisted?" do
40
+ context "canonical name whitelisted" do
41
+ before { config.whitelist = [License::Apache2.names[rand(License::Apache2.names.count)]]}
42
+
43
+ let(:possible_license_names) { License::Apache2.names }
44
+
45
+ it "should return true if if the license is the canonical name, pretty name, or alternative name of the license" do
46
+ possible_license_names.each do |name|
47
+ config.whitelisted?(name).should be_true, "expected #{name} to be whitelisted, but wasn't."
48
+ end
49
+ end
50
+
51
+ it "should be case-insensitive" do
52
+ possible_license_names.map(&:downcase).each do |name|
53
+ config.whitelisted?(name).should be_true, "expected #{name} to be whitelisted, but wasn't"
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ describe "#ignore_groups" do
60
+ it "should default to an empty array" do
61
+ config.ignore_groups.should == []
62
+ end
63
+
64
+ it "should always return symbolized versions of the ignore groups" do
65
+ config.ignore_groups = %w[test development]
66
+ config.ignore_groups.should == [:test, :development]
67
+ end
36
68
  end
37
69
  end
38
70
  end