autoloaded 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/History.md +4 -0
  4. data/README.md +411 -60
  5. data/autoloaded.gemspec +19 -14
  6. data/lib/autoloaded.rb +104 -91
  7. data/lib/autoloaded/autoloader.rb +260 -0
  8. data/lib/autoloaded/compatibility/refine_and_using.rb +2 -0
  9. data/lib/autoloaded/constant.rb +5 -2
  10. data/lib/autoloaded/deprecation.rb +50 -0
  11. data/lib/autoloaded/inflection.rb +71 -0
  12. data/lib/autoloaded/load_pathed_directory.rb +112 -0
  13. data/lib/autoloaded/refine.rb +7 -1
  14. data/lib/autoloaded/refine/string.rb +7 -0
  15. data/lib/autoloaded/refine/string/to_source_filename.rb +12 -0
  16. data/lib/autoloaded/specification.rb +97 -0
  17. data/lib/autoloaded/specifications.rb +66 -0
  18. data/lib/autoloaded/version.rb +3 -1
  19. data/lib/autoloaded/warning.rb +125 -0
  20. data/spec/autoloaded/autoloader_spec.rb +469 -0
  21. data/spec/autoloaded/constant_spec.rb +0 -2
  22. data/spec/autoloaded/deprecation_spec.rb +23 -0
  23. data/spec/autoloaded/inflection_spec.rb +30 -0
  24. data/spec/autoloaded/load_pathed_directory_spec.rb +120 -0
  25. data/spec/autoloaded/refine/string/to_source_filename_spec.rb +0 -2
  26. data/spec/autoloaded/specification_spec.rb +98 -0
  27. data/spec/autoloaded/specifications_spec.rb +191 -0
  28. data/spec/autoloaded/version_spec.rb +0 -2
  29. data/spec/autoloaded/warning_spec.rb +115 -0
  30. data/spec/autoloaded_macro_sharedspec.rb +24 -0
  31. data/spec/autoloaded_spec.rb +277 -95
  32. data/spec/fixtures/autoloaded_with_conventional_filename.rb +3 -1
  33. data/spec/fixtures/autoloaded_with_conventional_filename/nested.rb +12 -1
  34. data/spec/fixtures/autoloaded_with_conventional_filename/nested/doubly_nested.rb +9 -0
  35. data/spec/fixtures/autoloaded_with_unconventional_filename.rb +12 -0
  36. data/spec/fixtures/autoloaded_with_unconventional_filename/N-est-ed.rb +7 -0
  37. data/spec/fixtures/autoloaded_with_unconventional_filename/nest_ed.rb +1 -0
  38. data/spec/fixtures/autoloaded_with_unconventional_filename/old_school_autoload.rb +5 -0
  39. data/spec/fixtures/not_autoloaded/nested.rb +1 -0
  40. data/spec/fixtures/old_api/autoloaded_with_conventional_filename.rb +10 -0
  41. data/spec/fixtures/old_api/autoloaded_with_conventional_filename/N-est-ed.rb +1 -0
  42. data/spec/fixtures/old_api/autoloaded_with_conventional_filename/nest_ed.rb +1 -0
  43. data/spec/fixtures/old_api/autoloaded_with_conventional_filename/nested.rb +5 -0
  44. data/spec/fixtures/old_api/autoloaded_with_conventional_filename/old_school_autoload.rb +5 -0
  45. data/spec/fixtures/{autoloaded_with_conventional_filename_only.rb → old_api/autoloaded_with_conventional_filename_only.rb} +1 -1
  46. data/spec/fixtures/{autoloaded_with_conventional_filename_only → old_api/autoloaded_with_conventional_filename_only}/nested.rb +0 -0
  47. data/spec/fixtures/{autoloaded_with_conventional_filename_only → old_api/autoloaded_with_conventional_filename_only}/old_school_autoload.rb +0 -0
  48. data/spec/fixtures/{autoloaded_with_unconventional_filenames.rb → old_api/autoloaded_with_unconventional_filenames.rb} +1 -1
  49. data/spec/fixtures/{autoloaded_with_unconventional_filenames → old_api/autoloaded_with_unconventional_filenames}/N-est-ed.rb +0 -0
  50. data/spec/fixtures/{autoloaded_with_unconventional_filenames → old_api/autoloaded_with_unconventional_filenames}/nest_ed.rb +0 -0
  51. data/spec/fixtures/{autoloaded_with_unconventional_filenames → old_api/autoloaded_with_unconventional_filenames}/old_school_autoload.rb +0 -0
  52. data/spec/fixtures/old_api/not_autoloaded.rb +6 -0
  53. data/spec/fixtures/old_api/not_autoloaded/nested.rb +1 -0
  54. data/spec/fixtures/old_api/not_autoloaded/old_school_autoload.rb +5 -0
  55. data/spec/matchers.rb +4 -33
  56. data/spec/spec_helper.rb +2 -0
  57. metadata +95 -41
@@ -1,5 +1,3 @@
1
- require 'autoloaded/constant'
2
-
3
1
  RSpec.describe Autoloaded::Constant do
4
2
  let(:constant_class) { described_class }
5
3
 
@@ -0,0 +1,23 @@
1
+ require 'stringio'
2
+
3
+ RSpec.describe Autoloaded::Deprecation do
4
+ before :each do
5
+ deprecation_module.io = io
6
+ end
7
+
8
+ let(:deprecation_module) { described_class }
9
+
10
+ let(:io) { StringIO.new }
11
+
12
+ describe '.deprecate' do
13
+ before :each do
14
+ deprecation_module.deprecate deprecated_usage: 'foo',
15
+ sanctioned_usage: 'bar',
16
+ source_filename: 'baz.rb'
17
+ end
18
+
19
+ specify('writes the expected message to .io') {
20
+ expect(io.string).to eq(%Q(\e[33m*** \e[7m DEPRECATED \e[0m \e[4mfoo\e[0m -- use \e[4mbar\e[0m instead in baz.rb\n))
21
+ }
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ RSpec.describe Autoloaded::Inflection do
2
+ subject(:inflection_module) { described_class }
3
+
4
+ def self.make_source_filename(source_basename)
5
+ "path/to/#{source_basename}.rb"
6
+ end
7
+
8
+ {'x' => :X,
9
+ 'foo_bar' => :FooBar,
10
+ 'foo__bar' => :FooBar,
11
+ '__foo_bar' => :FooBar,
12
+ 'foo-bar' => :FooBar,
13
+ 'foo--bar' => :FooBar,
14
+ '--foo-bar' => :FooBar,
15
+ 'FooBar' => :FooBar,
16
+ 'FOO_BAR' => :FOO_BAR,
17
+ 'FOO-BAR' => :FOO_BAR,
18
+ 'FOO--BAR' => :FOO_BAR,
19
+ 'foo7bar' => :Foo7bar}.each do |source_basename, expected_constant_name|
20
+ describe %Q{for #{make_source_filename(source_basename).inspect}"} do
21
+ describe '#to_constant_name' do
22
+ specify {
23
+ source_filename = self.class.make_source_filename(source_basename)
24
+ constant_name = inflection_module.to_constant_name(source_filename)
25
+ expect(constant_name).to eq(expected_constant_name)
26
+ }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,120 @@
1
+ RSpec.describe Autoloaded::LoadPathedDirectory do
2
+ before :each do
3
+ allow(directory_class).to receive(:ruby_load_paths).
4
+ and_return(ruby_load_paths)
5
+ end
6
+
7
+ subject(:directory) { directory_class.new path }
8
+
9
+ let(:directory_class) { described_class }
10
+
11
+ let(:ruby_load_paths) { [Dir.pwd] }
12
+
13
+ describe '.new' do
14
+ describe 'with a nil argument' do
15
+ specify {
16
+ expect { directory_class.new nil }.to raise_error(ArgumentError,
17
+ "can't be nil")
18
+ }
19
+ end
20
+
21
+ describe 'with a relative-path argument' do
22
+ specify {
23
+ expect { directory_class.new 'foo' }.to raise_error(ArgumentError,
24
+ "can't be relative")
25
+ }
26
+ end
27
+ end
28
+
29
+ describe 'with an absolute #path' do
30
+ let(:path) { File.expand_path 'spec/fixtures/filenames' }
31
+
32
+ let(:expected_relative_source_filenames) {
33
+ %w(a-file-name
34
+ a-filename
35
+ a_file_name
36
+ a_filename
37
+ afile-name
38
+ afile_name
39
+ AFilename)
40
+ }
41
+
42
+ describe '#path' do
43
+ subject { directory.path }
44
+
45
+ specify { is_expected.to eq(path) }
46
+ end
47
+
48
+ describe '#each_source_filename' do
49
+ subject(:yielded_arguments) {
50
+ result = []
51
+ directory.each_source_filename do |source_filename|
52
+ result << source_filename
53
+ end
54
+ result
55
+ }
56
+
57
+ describe 'where #path does not match a Ruby load path' do
58
+ let(:ruby_load_paths) { [] }
59
+
60
+ let(:expected_source_filenames) {
61
+ expected_relative_source_filenames.collect do |f|
62
+ File.expand_path f, 'spec/fixtures/filenames'
63
+ end
64
+ }
65
+
66
+ describe 'yielded arguments' do
67
+ specify('should be absolute paths to the expected source filenames') {
68
+ is_expected.to match_array(expected_source_filenames)
69
+ }
70
+ end
71
+ end
72
+
73
+ describe 'where #path partially matches one Ruby load path' do
74
+ let(:expected_source_filenames) {
75
+ expected_relative_source_filenames.collect do |f|
76
+ File.join 'spec/fixtures/filenames', f
77
+ end
78
+ }
79
+
80
+ describe 'yielded arguments' do
81
+ specify('should be partial paths to the expected source filenames') {
82
+ is_expected.to match_array(expected_source_filenames)
83
+ }
84
+ end
85
+ end
86
+
87
+ describe 'where #path partially matches multiple Ruby load paths' do
88
+ let(:ruby_load_paths) {
89
+ [Dir.pwd,
90
+ File.join(Dir.pwd, 'spec/fixtures'),
91
+ File.join(Dir.pwd, 'spec')]
92
+ }
93
+
94
+ let(:expected_source_filenames) {
95
+ expected_relative_source_filenames.collect do |f|
96
+ File.join 'filenames', f
97
+ end
98
+ }
99
+
100
+ describe 'yielded arguments' do
101
+ specify('should be partial paths to the expected source filenames') {
102
+ is_expected.to match_array(expected_source_filenames)
103
+ }
104
+ end
105
+ end
106
+
107
+ describe 'where #path exactly matches a Ruby load path' do
108
+ let(:ruby_load_paths) { [File.join(Dir.pwd, 'spec/fixtures/filenames')] }
109
+
110
+ let(:expected_source_filenames) { expected_relative_source_filenames }
111
+
112
+ describe 'yielded arguments' do
113
+ specify('should be the expected source filenames') {
114
+ is_expected.to match_array(expected_source_filenames)
115
+ }
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -1,5 +1,3 @@
1
- require 'autoloaded/refine/string/to_source_filename'
2
-
3
1
  using Autoloaded::Refine::String::ToSourceFilename
4
2
 
5
3
  RSpec.describe Autoloaded::Refine::String::ToSourceFilename do
@@ -0,0 +1,98 @@
1
+ RSpec.describe Autoloaded::Specification do
2
+ before :each do
3
+ allow(inflector_class).to receive(:to_constant_name).
4
+ and_return(:FromInflection1,
5
+ :FromInflection2,
6
+ :FromInflection3)
7
+ end
8
+
9
+ subject(:specification) { specification_class.new(*elements) }
10
+
11
+ let(:specification_class) { described_class }
12
+
13
+ let(:inflector_class) { Autoloaded::Inflection }
14
+
15
+ specify("equals equivalent #{described_class.name}") {
16
+ expect(specification_class.new('foo')).to eq(specification_class.new('foo'))
17
+ }
18
+
19
+ specify("doesn't equal #{Object.name}") {
20
+ expect(specification_class.new('foo')).not_to eq(Object.new)
21
+ }
22
+
23
+ specify("doesn't equal #{described_class.name} with different #elements") {
24
+ expect(specification_class.new('foo')).not_to eq(specification_class.new('bar'))
25
+ }
26
+
27
+ describe 'with no elements' do
28
+ let(:elements) { [] }
29
+
30
+ specify { expect(specification.match('foo/bar')).to be_nil }
31
+ end
32
+
33
+ describe 'with one nonmatching element' do
34
+ let(:elements) { ['foo/bar'] }
35
+
36
+ specify { expect(specification.match('foo/baz')).to be_nil }
37
+ end
38
+
39
+ describe 'with one matching string element' do
40
+ let(:elements) { ['FOO/BAR'] }
41
+
42
+ specify { expect(specification.match('foo/bar')).to eq(:FromInflection1) }
43
+ end
44
+
45
+ describe 'with one matching symbol element' do
46
+ let(:elements) { [:FROMINFLECTION1] }
47
+
48
+ specify { expect(specification.match('foo/bar')).to eq(:FROMINFLECTION1) }
49
+ end
50
+
51
+ describe 'with two string elements, the second of which is matching' do
52
+ let(:elements) { %w(foo/bar baz/qux) }
53
+
54
+ specify { expect(specification.match('baz/qux')).to eq(:FromInflection1) }
55
+ end
56
+
57
+ describe 'with two symbol elements, the second of which is matching' do
58
+ let(:elements) { %i(Foo FromInflection2) }
59
+
60
+ specify { expect(specification.match('baz/qux')).to eq(:FromInflection2) }
61
+ end
62
+
63
+ describe 'with a nonmatching hash element' do
64
+ let(:elements) { [{Foo: 'bar/baz'}] }
65
+
66
+ specify { expect(specification.match('bar/qux')).to be_nil }
67
+ end
68
+
69
+ describe 'with a hash element in which a key matches' do
70
+ let(:elements) { [{FromInflection1: 'bar/baz'}] }
71
+
72
+ specify { expect(specification.match('foo')).to eq('bar/baz') }
73
+ end
74
+
75
+ describe 'with a hash element in which a value matches' do
76
+ let(:elements) { [{Foo: 'bar/baz'}] }
77
+
78
+ specify { expect(specification.match('bar/baz')).to eq(:Foo) }
79
+ end
80
+
81
+ describe 'with a hash element in which an array key has a match' do
82
+ let(:elements) { [{%i(Foo FromInflection2) => 'bar/baz'}] }
83
+
84
+ specify { expect(specification.match('qux')).to eq('bar/baz') }
85
+ end
86
+
87
+ describe 'with a hash element in which a an array value has a match' do
88
+ let(:elements) { [{Foo: %w(bar/baz qux/quux)}] }
89
+
90
+ specify { expect(specification.match('qux/quux')).to eq(:Foo) }
91
+ end
92
+
93
+ describe 'with a nonmatching string and a hash element in which an array key has a match' do
94
+ let(:elements) { ['foo', {%i(Bar FromInflection2) => 'baz/qux'}] }
95
+
96
+ specify { expect(specification.match('quux')).to eq('baz/qux') }
97
+ end
98
+ end
@@ -0,0 +1,191 @@
1
+ RSpec.describe Autoloaded::Specifications do
2
+ subject(:specifications) { specifications_class.new }
3
+
4
+ let(:specifications_class) { described_class }
5
+
6
+ describe 'empty' do
7
+ describe '#except' do
8
+ subject(:except) { specifications.except }
9
+
10
+ specify { is_expected.to be_empty }
11
+ end
12
+
13
+ describe '#only' do
14
+ subject(:only) { specifications.only }
15
+
16
+ specify { is_expected.to be_empty }
17
+ end
18
+
19
+ describe '#with' do
20
+ subject(:with) { specifications.with }
21
+
22
+ specify { is_expected.to be_empty }
23
+ end
24
+
25
+ describe '#validate! :except' do
26
+ specify { expect { specifications.validate! :except }.not_to raise_error }
27
+ end
28
+
29
+ describe '#validate! :only' do
30
+ specify { expect { specifications.validate! :only }.not_to raise_error }
31
+ end
32
+
33
+ describe '#validate! :with' do
34
+ specify { expect { specifications.validate! :with }.not_to raise_error }
35
+ end
36
+ end
37
+
38
+ describe 'with #except' do
39
+ before :each do
40
+ specifications.except << :foo
41
+ end
42
+
43
+ describe '#except' do
44
+ subject(:except) { specifications.except }
45
+
46
+ specify { is_expected.to contain_exactly(:foo) }
47
+ end
48
+
49
+ describe '#only' do
50
+ subject(:only) { specifications.only }
51
+
52
+ specify { is_expected.to be_empty }
53
+ end
54
+
55
+ describe '#with' do
56
+ subject(:with) { specifications.with }
57
+
58
+ specify { is_expected.to be_empty }
59
+ end
60
+
61
+ describe '#validate! :except' do
62
+ specify { expect { specifications.validate! :except }.not_to raise_error }
63
+ end
64
+
65
+ describe '#validate! :only' do
66
+ specify { expect { specifications.validate! :only }.not_to raise_error }
67
+ end
68
+
69
+ describe '#validate! :with' do
70
+ specify { expect { specifications.validate! :with }.not_to raise_error }
71
+ end
72
+
73
+ describe 'and #only' do
74
+ before :each do
75
+ specifications.only << :bar
76
+ end
77
+
78
+ describe '#except' do
79
+ subject(:except) { specifications.except }
80
+
81
+ specify { is_expected.to contain_exactly(:foo) }
82
+ end
83
+
84
+ describe '#only' do
85
+ subject(:only) { specifications.only }
86
+
87
+ specify { is_expected.to contain_exactly(:bar) }
88
+ end
89
+
90
+ describe '#with' do
91
+ subject(:with) { specifications.with }
92
+
93
+ specify { is_expected.to be_empty }
94
+ end
95
+
96
+ describe '#validate! :except' do
97
+ specify {
98
+ expect {
99
+ specifications.validate! :except
100
+ }.to raise_error(RuntimeError,
101
+ "can't specify `except' when `only' is already specified")
102
+ }
103
+ end
104
+
105
+ describe '#validate! :only' do
106
+ specify {
107
+ expect {
108
+ specifications.validate! :only
109
+ }.to raise_error(RuntimeError,
110
+ "can't specify `only' when `except' is already specified")
111
+ }
112
+ end
113
+
114
+ describe '#validate! :with' do
115
+ specify { expect { specifications.validate! :with }.not_to raise_error }
116
+ end
117
+ end
118
+ end
119
+
120
+ describe 'with #only' do
121
+ before :each do
122
+ specifications.only << :foo
123
+ end
124
+
125
+ describe '#except' do
126
+ subject(:except) { specifications.except }
127
+
128
+ specify { is_expected.to be_empty }
129
+ end
130
+
131
+ describe '#only' do
132
+ subject(:only) { specifications.only }
133
+
134
+ specify { is_expected.to contain_exactly(:foo) }
135
+ end
136
+
137
+ describe '#with' do
138
+ subject(:with) { specifications.with }
139
+
140
+ specify { is_expected.to be_empty }
141
+ end
142
+
143
+ describe '#validate! :except' do
144
+ specify { expect { specifications.validate! :except }.not_to raise_error }
145
+ end
146
+
147
+ describe '#validate! :only' do
148
+ specify { expect { specifications.validate! :only }.not_to raise_error }
149
+ end
150
+
151
+ describe '#validate! :with' do
152
+ specify { expect { specifications.validate! :with }.not_to raise_error }
153
+ end
154
+ end
155
+
156
+ describe 'with #with' do
157
+ before :each do
158
+ specifications.with << :foo
159
+ end
160
+
161
+ describe '#except' do
162
+ subject(:except) { specifications.except }
163
+
164
+ specify { is_expected.to be_empty }
165
+ end
166
+
167
+ describe '#only' do
168
+ subject(:only) { specifications.only }
169
+
170
+ specify { is_expected.to be_empty }
171
+ end
172
+
173
+ describe '#with' do
174
+ subject(:with) { specifications.with }
175
+
176
+ specify { is_expected.to contain_exactly(:foo) }
177
+ end
178
+
179
+ describe '#validate! :except' do
180
+ specify { expect { specifications.validate! :except }.not_to raise_error }
181
+ end
182
+
183
+ describe '#validate! :only' do
184
+ specify { expect { specifications.validate! :only }.not_to raise_error }
185
+ end
186
+
187
+ describe '#validate! :with' do
188
+ specify { expect { specifications.validate! :with }.not_to raise_error }
189
+ end
190
+ end
191
+ end