autoloaded 1.0.0 → 1.1.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.
- checksums.yaml +4 -4
- data/.yardopts +1 -1
- data/History.md +25 -0
- data/License.md +1 -1
- data/README.md +25 -6
- data/autoloaded.gemspec +1 -1
- data/lib/autoloaded.rb +101 -4
- data/lib/autoloaded/constant.rb +22 -2
- data/lib/autoloaded/refine.rb +1 -0
- data/lib/autoloaded/version.rb +2 -1
- data/spec/autoloaded/constant_spec.rb +13 -5
- data/spec/autoloaded_spec.rb +107 -23
- data/spec/fixtures/autoloaded_with_conventional_filename.rb +10 -0
- data/spec/fixtures/{namespace_that_is_autoloaded_conventionally → autoloaded_with_conventional_filename}/N-est-ed.rb +0 -0
- data/spec/fixtures/{namespace_that_is_autoloaded_conventionally → autoloaded_with_conventional_filename}/nest_ed.rb +0 -0
- data/spec/fixtures/autoloaded_with_conventional_filename/nested.rb +5 -0
- data/spec/fixtures/autoloaded_with_conventional_filename/old_school_autoload.rb +5 -0
- data/spec/fixtures/autoloaded_with_conventional_filename_only.rb +10 -0
- data/spec/fixtures/autoloaded_with_conventional_filename_only/nested.rb +5 -0
- data/spec/fixtures/autoloaded_with_conventional_filename_only/old_school_autoload.rb +5 -0
- data/spec/fixtures/autoloaded_with_unconventional_filenames.rb +10 -0
- data/spec/fixtures/autoloaded_with_unconventional_filenames/N-est-ed.rb +5 -0
- data/spec/fixtures/{namespace_that_is_autoloaded_unconventionally → autoloaded_with_unconventional_filenames}/nest_ed.rb +0 -0
- data/spec/fixtures/autoloaded_with_unconventional_filenames/old_school_autoload.rb +5 -0
- data/spec/fixtures/not_autoloaded.rb +5 -0
- data/spec/fixtures/not_autoloaded/old_school_autoload.rb +5 -0
- data/spec/matchers.rb +79 -37
- data/spec/support/util.rb +43 -0
- data/spec/support/without_side_effects.rb +1 -1
- metadata +34 -22
- data/History.markdown +0 -9
- data/spec/fixtures/namespace_that_is_autoloaded_conventionally.rb +0 -7
- data/spec/fixtures/namespace_that_is_autoloaded_conventionally/nested.rb +0 -5
- data/spec/fixtures/namespace_that_is_autoloaded_unconventionally.rb +0 -7
- data/spec/fixtures/namespace_that_is_autoloaded_unconventionally/N-est-ed.rb +0 -5
- data/spec/fixtures/namespace_that_is_not_autoloaded.rb +0 -1
- data/spec/fixtures/namespace_that_is_not_autoloaded/nested.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7221b689c0211923b999e3da078512a464179c5
|
4
|
+
data.tar.gz: f15a23ea558e0064748939779f3d4c3891bfc455
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9d88de3898d6351c0367c76cde73ed73661b8753ed17b60d9ba592c2c306585c1f79f4875713b3351dd12c0a450e721f51b359087af90c178beb93bada66975
|
7
|
+
data.tar.gz: 975e195c4b69254dc9a47945af0e78ec696b5f784f3e6f613cece9343da983944912af173f7fb8ad02aa5f95a50a3b063a42bce6e30dc9bf6571758f3c52c3a9
|
data/.yardopts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
--file License.md --no-private --protected --title "Autoloaded"
|
1
|
+
--file History.md --file License.md --no-private --protected --title "Autoloaded"
|
data/History.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Version history for the _Autoloaded_ project
|
2
|
+
|
3
|
+
## <a name="v1.1.0"></a>v1.1.0, Tue 11/04/2013
|
4
|
+
|
5
|
+
* Correct/improve autoload behavior
|
6
|
+
* Instead of returning the source **directory** path from
|
7
|
+
[_Module#autoload?_][Ruby-Core-Module-autoload], return one or more matching
|
8
|
+
source **file** path(s)
|
9
|
+
* Use Ruby load path (`$:`) to handle relative source file paths
|
10
|
+
* Explain _Module#autoload?_ and
|
11
|
+
[_Module#constants_][Ruby-Core-Module-constants] in the [readme][readme] and
|
12
|
+
in [inline documentation][inline-documentation]
|
13
|
+
|
14
|
+
## <a name="v1.0.0"></a>v1.0.0, Wed 10/29/2013
|
15
|
+
|
16
|
+
* Add support for Ruby v2.0
|
17
|
+
|
18
|
+
## <a name="v0.0.3"></a>v0.0.3, Fri 10/24/2014
|
19
|
+
|
20
|
+
(First release)
|
21
|
+
|
22
|
+
[Ruby-Core-Module-autoload]: http://ruby-doc.org/core/Module.html#method-i-autoload-3F "‘Module#autoload’ method in the Ruby Core Library"
|
23
|
+
[Ruby-Core-Module-constants]: http://ruby-doc.org/core/Module.html#method-i-constants "‘Module#constants’ method in the Ruby Core Library"
|
24
|
+
[readme]: http://github.com/njonsson/autoloaded/blob/master/README.md "Autoloaded readme"
|
25
|
+
[inline-documentation]: http://www.rubydoc.info/github/njonsson/autoloaded "Autoloaded inline documentation"
|
data/License.md
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
[![Autoloaded graphic]][spider-gear-image]
|
2
2
|
|
3
3
|
# Autoloaded
|
4
4
|
|
@@ -70,12 +70,27 @@ module MyAwesomeGem
|
|
70
70
|
end
|
71
71
|
```
|
72
72
|
|
73
|
-
Note that your preferred casing of constants is accommodated automatically
|
73
|
+
Note that your preferred casing of constants is accommodated automatically.
|
74
74
|
|
75
75
|
```ruby
|
76
|
-
|
77
|
-
|
78
|
-
MyAwesomeGem::DB
|
76
|
+
# Unlike Kernel#autoload and Module#autoload, Autoloaded is not clairvoyant about
|
77
|
+
# what constants will be autoloaded.
|
78
|
+
MyAwesomeGem::DB.constants # => []
|
79
|
+
|
80
|
+
# But like Kernel#autoload and Module#autoload, Autoloaded does tell you which
|
81
|
+
# source files will be autoloaded. (The difference is that it may return an array
|
82
|
+
# of potential matches instead of just one filename.)
|
83
|
+
MyAwesomeGem::DB.autoload? :MySQL # => 'db/mysql'
|
84
|
+
MyAwesomeGem::DB.autoload? :PostgreSQL # => 'db/postgresql'
|
85
|
+
MyAwesomeGem::DB.autoload? :SQLServer # => 'db/sql_server'
|
86
|
+
MyAwesomeGem::DB.autoload? :Nonexistent # => nil
|
87
|
+
|
88
|
+
MyAwesomeGem::DB::MySQL
|
89
|
+
MyAwesomeGem::DB.constants # => [:MySQL]
|
90
|
+
MyAwesomeGem::DB::PostgreSQL
|
91
|
+
MyAwesomeGem::DB.constants # => [:MySQL, :PostgreSQL]
|
92
|
+
MyAwesomeGem::DB::SQLServer
|
93
|
+
MyAwesomeGem::DB.constants # => [:MySQL, :PostgreSQL, :SQLServer]
|
79
94
|
```
|
80
95
|
|
81
96
|
_Autoloaded_ does not perform deep autoloading of nested namespaces and
|
@@ -99,7 +114,7 @@ module MyAwesomeGem; end
|
|
99
114
|
# lib/my_awesome_gem/db.rb
|
100
115
|
module MyAwesomeGem
|
101
116
|
|
102
|
-
# WRONG!
|
117
|
+
# WRONG!
|
103
118
|
extend Autoloaded
|
104
119
|
|
105
120
|
module DB
|
@@ -109,6 +124,10 @@ module MyAwesomeGem
|
|
109
124
|
end
|
110
125
|
|
111
126
|
end
|
127
|
+
|
128
|
+
# some_other_file.rb
|
129
|
+
require 'my_awesome_gem'
|
130
|
+
MyAwesomeGem::DB # NameError is raised!
|
112
131
|
```
|
113
132
|
|
114
133
|
## Contributing
|
data/autoloaded.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
snake_case correspondence between the names of constants
|
26
26
|
and source files.
|
27
27
|
end_description
|
28
|
-
spec.homepage = '
|
28
|
+
spec.homepage = 'http://njonsson.github.io/autoloaded'
|
29
29
|
spec.license = 'MIT'
|
30
30
|
|
31
31
|
spec.files = `git ls-files -z`.split("\x0")
|
data/lib/autoloaded.rb
CHANGED
@@ -1,3 +1,92 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# When used to extend a module, the _Autoloaded_ module dynamically loads
|
4
|
+
# constants into that module from source files contained in its filesystem path.
|
5
|
+
#
|
6
|
+
# @note You must extend a namespace with _Autoloaded_ from within the file in
|
7
|
+
# which the namespace is defined. This is because _Autoloaded_ utilizes the
|
8
|
+
# source file path of the namespace to establish which directory will be
|
9
|
+
# autoloaded. That path is discoverable only via the stack trace of `extend
|
10
|
+
# Autoloaded`.
|
11
|
+
#
|
12
|
+
# Suppose you have the following source files:
|
13
|
+
#
|
14
|
+
# * lib/
|
15
|
+
# * my_awesome_gem/
|
16
|
+
# * db/
|
17
|
+
# * mysql.rb
|
18
|
+
# * postgresql.rb
|
19
|
+
# * sql_server.rb
|
20
|
+
# * db.rb
|
21
|
+
# * my_awesome_gem.rb
|
22
|
+
#
|
23
|
+
# The following statements establish autoloading — one statement per namespace:
|
24
|
+
#
|
25
|
+
# # lib/my_awesome_gem.rb
|
26
|
+
# module MyAwesomeGem
|
27
|
+
#
|
28
|
+
# extend Autoloaded
|
29
|
+
#
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# # lib/my_awesome_gem/db.rb
|
33
|
+
# module MyAwesomeGem
|
34
|
+
#
|
35
|
+
# module DB
|
36
|
+
#
|
37
|
+
# extend Autoloaded
|
38
|
+
#
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# Note that your preferred casing of constants is accommodated automatically.
|
44
|
+
#
|
45
|
+
# # Unlike Kernel#autoload and Module#autoload, Autoloaded is not clairvoyant about
|
46
|
+
# # what constants will be autoloaded.
|
47
|
+
# MyAwesomeGem::DB.constants # => []
|
48
|
+
#
|
49
|
+
# # But like Kernel#autoload and Module#autoload, Autoloaded does tell you which
|
50
|
+
# # source files will be autoloaded. (The difference is that it may return an array
|
51
|
+
# # of potential matches instead of just one filename.)
|
52
|
+
# MyAwesomeGem::DB.autoload? :MySQL # => 'db/mysql'
|
53
|
+
# MyAwesomeGem::DB.autoload? :PostgreSQL # => 'db/postgresql'
|
54
|
+
# MyAwesomeGem::DB.autoload? :SQLServer # => 'db/sql_server'
|
55
|
+
# MyAwesomeGem::DB.autoload? :Nonexistent # => nil
|
56
|
+
#
|
57
|
+
# MyAwesomeGem::DB::MySQL
|
58
|
+
# MyAwesomeGem::DB.constants # => [:MySQL]
|
59
|
+
# MyAwesomeGem::DB::PostgreSQL
|
60
|
+
# MyAwesomeGem::DB.constants # => [:MySQL, :PostgreSQL]
|
61
|
+
# MyAwesomeGem::DB::SQLServer
|
62
|
+
# MyAwesomeGem::DB.constants # => [:MySQL, :PostgreSQL, :SQLServer]
|
63
|
+
#
|
64
|
+
# _Autoloaded_ does not perform deep autoloading of nested namespaces and
|
65
|
+
# directories. This is by design.
|
66
|
+
#
|
67
|
+
# In the following example, autoloading of the _MyAwesomeGem_ namespace will not occur because the name of the source file in which the `extend` statement is invoked does not match the name of the namespace.
|
68
|
+
#
|
69
|
+
# # lib/my_awesome_gem.rb
|
70
|
+
# module MyAwesomeGem; end
|
71
|
+
#
|
72
|
+
# # lib/my_awesome_gem/db.rb
|
73
|
+
# module MyAwesomeGem
|
74
|
+
#
|
75
|
+
# # WRONG!
|
76
|
+
# extend Autoloaded
|
77
|
+
#
|
78
|
+
# module DB
|
79
|
+
#
|
80
|
+
# extend Autoloaded
|
81
|
+
#
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
# # some_other_file.rb
|
87
|
+
# require 'my_awesome_gem'
|
88
|
+
# MyAwesomeGem::DB # NameError is raised!
|
89
|
+
#
|
1
90
|
module Autoloaded
|
2
91
|
|
3
92
|
def self.extended(other_module)
|
@@ -5,14 +94,22 @@ module Autoloaded
|
|
5
94
|
dir_path = "#{::File.dirname caller_file_path}/#{::File.basename caller_file_path, '.rb'}"
|
6
95
|
other_module.module_eval <<-end_module_eval, __FILE__, __LINE__
|
7
96
|
def self.autoload?(symbol)
|
8
|
-
|
97
|
+
if (old_school = super)
|
98
|
+
return old_school
|
99
|
+
end
|
100
|
+
|
101
|
+
require 'autoloaded/constant'
|
102
|
+
filenames = []
|
103
|
+
::Autoloaded::Constant.new(symbol).each_matching_filename_in #{dir_path.inspect} do |filename|
|
104
|
+
filenames << filename
|
105
|
+
end
|
106
|
+
(filenames.length <= 1) ? filenames.first : filenames
|
9
107
|
end
|
10
108
|
|
11
109
|
def self.const_missing(symbol)
|
12
110
|
require 'autoloaded/constant'
|
13
111
|
::Autoloaded::Constant.new(symbol).each_matching_filename_in #{dir_path.inspect} do |filename|
|
14
|
-
|
15
|
-
require without_ext
|
112
|
+
require filename
|
16
113
|
if const_defined?(symbol)
|
17
114
|
begin
|
18
115
|
return const_get(symbol)
|
@@ -21,7 +118,7 @@ module Autoloaded
|
|
21
118
|
end
|
22
119
|
end
|
23
120
|
|
24
|
-
super
|
121
|
+
super
|
25
122
|
end
|
26
123
|
end_module_eval
|
27
124
|
end
|
data/lib/autoloaded/constant.rb
CHANGED
@@ -5,6 +5,7 @@ using ::Autoloaded::Refine::String::ToSourceFilename
|
|
5
5
|
|
6
6
|
module Autoloaded; end
|
7
7
|
|
8
|
+
# @private
|
8
9
|
class Autoloaded::Constant
|
9
10
|
|
10
11
|
attr_reader :name
|
@@ -28,6 +29,25 @@ private
|
|
28
29
|
'.rb'
|
29
30
|
end
|
30
31
|
|
32
|
+
def filename_without_extension(filename)
|
33
|
+
"#{::File.dirname filename}/#{::File.basename filename, extension}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def filename_without_load_path_prefix(filename)
|
37
|
+
first_applicable_load_path = $:.detect do |path|
|
38
|
+
filename.start_with? path
|
39
|
+
end
|
40
|
+
if first_applicable_load_path
|
41
|
+
regexp = /^#{::Regexp.escape first_applicable_load_path}\/?/
|
42
|
+
filename = filename.gsub(regexp, '')
|
43
|
+
end
|
44
|
+
filename
|
45
|
+
end
|
46
|
+
|
47
|
+
def format_filename(filename)
|
48
|
+
filename_without_load_path_prefix filename_without_extension(filename)
|
49
|
+
end
|
50
|
+
|
31
51
|
def name_signature
|
32
52
|
@name_signature ||= signature(name)
|
33
53
|
end
|
@@ -52,7 +72,7 @@ private
|
|
52
72
|
filename_signature = signature(::File.basename(filename, extension))
|
53
73
|
if (filename_signature == name_signature) &&
|
54
74
|
unless_in.add?(::File.basename(filename))
|
55
|
-
block.call filename
|
75
|
+
block.call format_filename(filename)
|
56
76
|
end
|
57
77
|
end
|
58
78
|
end
|
@@ -63,7 +83,7 @@ private
|
|
63
83
|
end
|
64
84
|
qualified = ::File.join(directory, name_source_filename)
|
65
85
|
if ::File.file?(qualified) && unless_in.add?(name_source_filename)
|
66
|
-
block.call qualified
|
86
|
+
block.call format_filename(qualified)
|
67
87
|
end
|
68
88
|
end
|
69
89
|
|
data/lib/autoloaded/refine.rb
CHANGED
data/lib/autoloaded/version.rb
CHANGED
@@ -3,8 +3,16 @@ require 'autoloaded/constant'
|
|
3
3
|
RSpec.describe Autoloaded::Constant do
|
4
4
|
let(:constant_class) { described_class }
|
5
5
|
|
6
|
+
specify("sanity check: load path includes our 'spec' directory") {
|
7
|
+
expect($:).to include(File.expand_path('../..', __FILE__))
|
8
|
+
}
|
9
|
+
|
6
10
|
describe 'for' do
|
7
|
-
let(:directory) { '
|
11
|
+
let(:directory) { File.expand_path '../../fixtures/filenames', __FILE__ }
|
12
|
+
|
13
|
+
let(:load_pathed_directory) {
|
14
|
+
directory.gsub(/^#{File.expand_path '../..', __FILE__}\/?/, '')
|
15
|
+
}
|
8
16
|
|
9
17
|
{AFilename: %w(a_filename a-file-name a-filename a_file_name afile_name afile-name AFilename),
|
10
18
|
A_FILENAME: %w(a_filename a-file-name a-filename a_file_name afile_name afile-name AFilename),
|
@@ -14,9 +22,9 @@ RSpec.describe Autoloaded::Constant do
|
|
14
22
|
describe constant_name.inspect do
|
15
23
|
let(:constant) { constant_class.new constant_name }
|
16
24
|
|
17
|
-
let(:
|
25
|
+
let(:load_pathed_filenames) {
|
18
26
|
filenames.collect do |filename|
|
19
|
-
"#{
|
27
|
+
"#{load_pathed_directory}/#{filename}"
|
20
28
|
end
|
21
29
|
}
|
22
30
|
|
@@ -32,13 +40,13 @@ RSpec.describe Autoloaded::Constant do
|
|
32
40
|
describe 'first yielded argument' do
|
33
41
|
subject(:first_yielded_argument) { yielded_args.first }
|
34
42
|
|
35
|
-
it { is_expected.to eq(
|
43
|
+
it { is_expected.to eq(load_pathed_filenames.first) }
|
36
44
|
end
|
37
45
|
|
38
46
|
describe 'subsequent yielded arguments' do
|
39
47
|
subject(:subsequent_yielded_arguments) { yielded_args[1..-1] }
|
40
48
|
|
41
|
-
it { is_expected.to match_array(
|
49
|
+
it { is_expected.to match_array(load_pathed_filenames[1..-1]) }
|
42
50
|
end
|
43
51
|
end
|
44
52
|
end
|
data/spec/autoloaded_spec.rb
CHANGED
@@ -2,47 +2,131 @@ require 'autoloaded'
|
|
2
2
|
require 'matchers'
|
3
3
|
|
4
4
|
RSpec.describe Autoloaded do
|
5
|
+
before :each do
|
6
|
+
class << self
|
7
|
+
alias_method :define_constant, :define_constants
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
5
11
|
describe 'not extending a namespace' do
|
6
|
-
|
12
|
+
subject(:source_file) { 'spec/fixtures/not_autoloaded.rb' }
|
13
|
+
|
14
|
+
it { is_expected.to define_constant(:NotAutoloaded) }
|
15
|
+
|
16
|
+
it { is_expected.to define_constant('NotAutoloaded::OldSchoolAutoload') }
|
7
17
|
|
8
|
-
|
9
|
-
|
18
|
+
it { is_expected.not_to define_constant('NotAutoloaded::Nested') }
|
19
|
+
|
20
|
+
it {
|
21
|
+
is_expected.to set_up_autoload_for_constant('NotAutoloaded::OldSchoolAutoload').
|
22
|
+
from_file('fixtures/not_autoloaded/old_school_autoload')
|
10
23
|
}
|
11
24
|
|
12
|
-
|
13
|
-
|
14
|
-
in_a_namespace_named(:NamespaceThatIsNotAutoloaded)
|
25
|
+
it {
|
26
|
+
is_expected.not_to set_up_autoload_for_constant('NotAutoloaded::Nested')
|
15
27
|
}
|
16
28
|
end
|
17
29
|
|
18
|
-
describe 'extending a namespace' do
|
19
|
-
describe '
|
20
|
-
|
21
|
-
'spec/fixtures/
|
30
|
+
describe 'extending a namespace whose constituent source files have' do
|
31
|
+
describe 'conventional names used for autoloading' do
|
32
|
+
subject(:source_file) {
|
33
|
+
'spec/fixtures/autoloaded_with_conventional_filename.rb'
|
22
34
|
}
|
23
35
|
|
24
|
-
|
25
|
-
|
36
|
+
it { is_expected.to define_constant(:AutoloadedWithConventionalFilename) }
|
37
|
+
|
38
|
+
it {
|
39
|
+
is_expected.to define_constant('AutoloadedWithConventionalFilename::OldSchoolAutoload')
|
26
40
|
}
|
27
41
|
|
28
|
-
|
29
|
-
|
30
|
-
|
42
|
+
it {
|
43
|
+
is_expected.to define_constant('AutoloadedWithConventionalFilename::Nested').
|
44
|
+
dynamically
|
45
|
+
}
|
46
|
+
|
47
|
+
it {
|
48
|
+
is_expected.not_to define_constant('AutoloadedWithConventionalFilename::NONEXISTENT')
|
49
|
+
}
|
50
|
+
|
51
|
+
it {
|
52
|
+
is_expected.to set_up_autoload_for_constant('AutoloadedWithConventionalFilename::OldSchoolAutoload').
|
53
|
+
from_file('fixtures/autoloaded_with_conventional_filename/old_school_autoload')
|
54
|
+
}
|
55
|
+
|
56
|
+
it {
|
57
|
+
is_expected.to set_up_autoload_for_constant('AutoloadedWithConventionalFilename::Nested').
|
58
|
+
from_files('fixtures/autoloaded_with_conventional_filename/nested',
|
59
|
+
'fixtures/autoloaded_with_conventional_filename/N-est-ed',
|
60
|
+
'fixtures/autoloaded_with_conventional_filename/nest_ed')
|
61
|
+
}
|
62
|
+
|
63
|
+
it {
|
64
|
+
is_expected.not_to set_up_autoload_for_constant('AutoloadedWithConventionalFilename::NONEXISTENT')
|
31
65
|
}
|
32
66
|
end
|
33
67
|
|
34
|
-
describe '
|
35
|
-
|
36
|
-
'spec/fixtures/
|
68
|
+
describe 'conventional names' do
|
69
|
+
subject(:source_file) {
|
70
|
+
'spec/fixtures/autoloaded_with_conventional_filename_only.rb'
|
71
|
+
}
|
72
|
+
|
73
|
+
it { is_expected.to define_constant(:AutoloadedWithConventionalFilenameOnly) }
|
74
|
+
|
75
|
+
it {
|
76
|
+
is_expected.to define_constant('AutoloadedWithConventionalFilenameOnly::OldSchoolAutoload')
|
77
|
+
}
|
78
|
+
|
79
|
+
it {
|
80
|
+
is_expected.to define_constant('AutoloadedWithConventionalFilenameOnly::Nested').
|
81
|
+
dynamically
|
82
|
+
}
|
83
|
+
|
84
|
+
it {
|
85
|
+
is_expected.to set_up_autoload_for_constant('AutoloadedWithConventionalFilenameOnly::OldSchoolAutoload').
|
86
|
+
from_file('fixtures/autoloaded_with_conventional_filename_only/old_school_autoload')
|
87
|
+
}
|
88
|
+
|
89
|
+
it {
|
90
|
+
is_expected.to set_up_autoload_for_constant('AutoloadedWithConventionalFilenameOnly::Nested').
|
91
|
+
from_file('fixtures/autoloaded_with_conventional_filename_only/nested')
|
92
|
+
}
|
93
|
+
|
94
|
+
it {
|
95
|
+
is_expected.not_to set_up_autoload_for_constant('AutoloadedWithConventionalFilenameOnly::NONEXISTENT')
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'unconventional names' do
|
100
|
+
subject(:source_file) {
|
101
|
+
'spec/fixtures/autoloaded_with_unconventional_filenames.rb'
|
102
|
+
}
|
103
|
+
|
104
|
+
it {
|
105
|
+
is_expected.to define_constant(:AutoloadedWithUnconventionalFilenames)
|
106
|
+
}
|
107
|
+
|
108
|
+
it {
|
109
|
+
is_expected.to define_constant('AutoloadedWithUnconventionalFilenames::OldSchoolAutoload')
|
110
|
+
}
|
111
|
+
|
112
|
+
it {
|
113
|
+
is_expected.to define_constants('AutoloadedWithUnconventionalFilenames::Nested').
|
114
|
+
dynamically
|
115
|
+
}
|
116
|
+
|
117
|
+
it {
|
118
|
+
is_expected.to set_up_autoload_for_constant('AutoloadedWithUnconventionalFilenames::OldSchoolAutoload').
|
119
|
+
from_file('fixtures/autoloaded_with_unconventional_filenames/old_school_autoload')
|
37
120
|
}
|
38
121
|
|
39
|
-
|
40
|
-
|
122
|
+
it {
|
123
|
+
is_expected.to set_up_autoload_for_constant('AutoloadedWithUnconventionalFilenames::Nested').
|
124
|
+
from_files('fixtures/autoloaded_with_unconventional_filenames/N-est-ed',
|
125
|
+
'fixtures/autoloaded_with_unconventional_filenames/nest_ed')
|
41
126
|
}
|
42
127
|
|
43
|
-
|
44
|
-
|
45
|
-
in_a_namespace_named(:NamespaceThatIsAutoloadedUnconventionally)
|
128
|
+
it {
|
129
|
+
is_expected.not_to set_up_autoload_for_constant('AutoloadedWithUnconventionalFilenames::NONEXISTENT')
|
46
130
|
}
|
47
131
|
end
|
48
132
|
end
|
File without changes
|
File without changes
|
File without changes
|
data/spec/matchers.rb
CHANGED
@@ -1,72 +1,114 @@
|
|
1
|
+
require 'support/util'
|
1
2
|
require 'support/without_side_effects'
|
2
3
|
|
3
|
-
RSpec::Matchers.define :
|
4
|
+
RSpec::Matchers.define :define_constants do |*constant_names|
|
4
5
|
match do |source_file|
|
5
6
|
# Ensure the file exists.
|
6
7
|
File.open source_file, 'r' do
|
7
8
|
end
|
8
9
|
|
9
|
-
constant_tokens = constant_name.split('::')
|
10
|
-
constant_up_till_last = constant_tokens[0...-1].join('::')
|
11
|
-
constant_last = constant_tokens.last
|
12
|
-
|
13
10
|
without_side_effects do
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
raise("#{constant_name} is already defined")
|
11
|
+
constant_names.each do |constant_name|
|
12
|
+
if Util.constantize(constant_name)
|
13
|
+
fail "constant #{constant_name} is already defined outside #{source_file}"
|
14
|
+
end
|
19
15
|
end
|
20
16
|
|
21
17
|
load source_file
|
22
18
|
|
23
|
-
|
24
|
-
|
25
|
-
|
19
|
+
any_statically_defined = false
|
20
|
+
if dynamically?
|
21
|
+
any_statically_defined = constant_names.any? do |constant_name|
|
22
|
+
current_scope = Object
|
23
|
+
constant_name.split(Util.namespace_delimiter).all? do |token|
|
24
|
+
current_scope.constants.include?(token.to_sym).tap do |result|
|
25
|
+
if result
|
26
|
+
current_scope = Util.constantize([current_scope.name, token].join(Util.namespace_delimiter))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
if any_statically_defined
|
26
34
|
false
|
27
35
|
else
|
28
|
-
|
36
|
+
constant_names.all? do |constant_name|
|
37
|
+
namespace, unqualified_constant_name = Util.namespace_and_unqualified_constant_name(constant_name,
|
38
|
+
raise_if_namespace_invalid: true)
|
39
|
+
(!dynamically? ||
|
40
|
+
!namespace.constants.include?(unqualified_constant_name.to_sym)) &&
|
41
|
+
Util.constantize(constant_name)
|
42
|
+
end
|
29
43
|
end
|
30
44
|
end
|
31
45
|
end
|
32
|
-
end
|
33
46
|
|
34
|
-
|
35
|
-
|
47
|
+
chain :dynamically do
|
48
|
+
@dynamically = true
|
49
|
+
end
|
36
50
|
|
37
|
-
|
38
|
-
|
51
|
+
description do
|
52
|
+
fragments = []
|
53
|
+
fragments << case constant_names.length
|
54
|
+
when 0
|
55
|
+
'no constants'
|
56
|
+
when 1
|
57
|
+
"constant #{constant_names.first}"
|
58
|
+
else
|
59
|
+
"constants #{constant_names.join ' and '}"
|
60
|
+
end
|
61
|
+
fragments << 'dynamically' if dynamically?
|
62
|
+
"define #{fragments.join ' '}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def dynamically?
|
66
|
+
@dynamically
|
67
|
+
end
|
68
|
+
end
|
39
69
|
|
70
|
+
RSpec::Matchers.define :set_up_autoload_for_constant do |constant_name|
|
71
|
+
match do |source_file|
|
40
72
|
# Ensure the file exists.
|
41
73
|
File.open source_file, 'r' do
|
42
74
|
end
|
43
75
|
|
44
|
-
|
45
|
-
|
46
|
-
|
76
|
+
without_side_effects do
|
77
|
+
namespace, unqualified_constant_name = Util.namespace_and_unqualified_constant_name(constant_name)
|
78
|
+
if namespace && namespace.autoload?(unqualified_constant_name)
|
79
|
+
fail "#{namespace.name}::#{unqualified_constant_name} is already set up for autoload outside #{source_file}"
|
80
|
+
end
|
47
81
|
|
48
|
-
defined_constants = without_side_effects do
|
49
82
|
load source_file
|
50
83
|
|
51
|
-
namespace =
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
84
|
+
namespace, unqualified_constant_name = Util.namespace_and_unqualified_constant_name(constant_name,
|
85
|
+
raise_if_namespace_invalid: true)
|
86
|
+
if filename_or_filenames
|
87
|
+
Array(filename_or_filenames).sort == Array(namespace.autoload?(unqualified_constant_name)).sort
|
88
|
+
else
|
89
|
+
namespace.autoload? unqualified_constant_name
|
56
90
|
end
|
57
|
-
|
58
|
-
namespace.constants.sort.collect(&:to_sym)
|
59
91
|
end
|
60
|
-
@expected_constants = constant_names.sort.collect(&:to_sym)
|
61
|
-
@extraneous_defined_constants = defined_constants - expected_constants
|
62
|
-
extraneous_defined_constants.empty?
|
63
92
|
end
|
64
93
|
|
65
|
-
chain :
|
66
|
-
@
|
94
|
+
chain :from_file do |filename|
|
95
|
+
@filename_or_filenames = filename
|
96
|
+
end
|
97
|
+
|
98
|
+
chain :from_files do |*filenames|
|
99
|
+
@filename_or_filenames = filenames
|
67
100
|
end
|
68
101
|
|
69
|
-
|
70
|
-
|
102
|
+
description do
|
103
|
+
fragments = []
|
104
|
+
fragments << "constant #{constant_name}"
|
105
|
+
if filename_or_filenames
|
106
|
+
unless (filenames = Array(filename_or_filenames)).empty?
|
107
|
+
fragments << "from file#{(filenames.length == 1) ? nil : 's'} #{filenames.join ' and '}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
"set up #{Module.name}#autoload? for #{fragments.join ' '}"
|
71
111
|
end
|
112
|
+
|
113
|
+
attr_reader :filename_or_filenames
|
72
114
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Util
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def constantize(name)
|
6
|
+
return nil unless name
|
7
|
+
|
8
|
+
begin
|
9
|
+
eval name.to_s
|
10
|
+
rescue NameError
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def namespace_and_unqualified_constant_name(constant_name,
|
16
|
+
raise_if_namespace_invalid: false)
|
17
|
+
namespace_name, unqualified_constant_name = split_namespace_and_constant(constant_name)
|
18
|
+
if namespace_name && (namespace = constantize(namespace_name)).nil?
|
19
|
+
if raise_if_namespace_invalid
|
20
|
+
raise "namespace of #{constant_name} is not defined"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
[namespace, unqualified_constant_name]
|
24
|
+
end
|
25
|
+
|
26
|
+
def namespace_delimiter
|
27
|
+
'::'
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def split_namespace_and_constant(constant_name)
|
33
|
+
if (last_delimiter_index = constant_name.to_s.rindex(namespace_delimiter))
|
34
|
+
return [constant_name[0...last_delimiter_index],
|
35
|
+
constant_name[(last_delimiter_index + namespace_delimiter.length)..-1]]
|
36
|
+
end
|
37
|
+
|
38
|
+
return [nil, constant_name]
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: autoloaded
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nils Jonsson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -70,7 +70,7 @@ files:
|
|
70
70
|
- ".yardopts"
|
71
71
|
- Gemfile
|
72
72
|
- Guardfile
|
73
|
-
- History.
|
73
|
+
- History.md
|
74
74
|
- License.md
|
75
75
|
- README.md
|
76
76
|
- Rakefile
|
@@ -90,6 +90,18 @@ files:
|
|
90
90
|
- spec/autoloaded/refine/string/to_source_filename_spec.rb
|
91
91
|
- spec/autoloaded/version_spec.rb
|
92
92
|
- spec/autoloaded_spec.rb
|
93
|
+
- spec/fixtures/autoloaded_with_conventional_filename.rb
|
94
|
+
- spec/fixtures/autoloaded_with_conventional_filename/N-est-ed.rb
|
95
|
+
- spec/fixtures/autoloaded_with_conventional_filename/nest_ed.rb
|
96
|
+
- spec/fixtures/autoloaded_with_conventional_filename/nested.rb
|
97
|
+
- spec/fixtures/autoloaded_with_conventional_filename/old_school_autoload.rb
|
98
|
+
- spec/fixtures/autoloaded_with_conventional_filename_only.rb
|
99
|
+
- spec/fixtures/autoloaded_with_conventional_filename_only/nested.rb
|
100
|
+
- spec/fixtures/autoloaded_with_conventional_filename_only/old_school_autoload.rb
|
101
|
+
- spec/fixtures/autoloaded_with_unconventional_filenames.rb
|
102
|
+
- spec/fixtures/autoloaded_with_unconventional_filenames/N-est-ed.rb
|
103
|
+
- spec/fixtures/autoloaded_with_unconventional_filenames/nest_ed.rb
|
104
|
+
- spec/fixtures/autoloaded_with_unconventional_filenames/old_school_autoload.rb
|
93
105
|
- spec/fixtures/filenames/AFilename.rb
|
94
106
|
- spec/fixtures/filenames/a-file-name.rb
|
95
107
|
- spec/fixtures/filenames/a-filename.rb
|
@@ -97,19 +109,13 @@ files:
|
|
97
109
|
- spec/fixtures/filenames/a_filename.rb
|
98
110
|
- spec/fixtures/filenames/afile-name.rb
|
99
111
|
- spec/fixtures/filenames/afile_name.rb
|
100
|
-
- spec/fixtures/
|
101
|
-
- spec/fixtures/
|
102
|
-
- spec/fixtures/namespace_that_is_autoloaded_conventionally/nest_ed.rb
|
103
|
-
- spec/fixtures/namespace_that_is_autoloaded_conventionally/nested.rb
|
104
|
-
- spec/fixtures/namespace_that_is_autoloaded_unconventionally.rb
|
105
|
-
- spec/fixtures/namespace_that_is_autoloaded_unconventionally/N-est-ed.rb
|
106
|
-
- spec/fixtures/namespace_that_is_autoloaded_unconventionally/nest_ed.rb
|
107
|
-
- spec/fixtures/namespace_that_is_not_autoloaded.rb
|
108
|
-
- spec/fixtures/namespace_that_is_not_autoloaded/nested.rb
|
112
|
+
- spec/fixtures/not_autoloaded.rb
|
113
|
+
- spec/fixtures/not_autoloaded/old_school_autoload.rb
|
109
114
|
- spec/matchers.rb
|
110
115
|
- spec/spec_helper.rb
|
116
|
+
- spec/support/util.rb
|
111
117
|
- spec/support/without_side_effects.rb
|
112
|
-
homepage:
|
118
|
+
homepage: http://njonsson.github.io/autoloaded
|
113
119
|
licenses:
|
114
120
|
- MIT
|
115
121
|
metadata: {}
|
@@ -139,6 +145,18 @@ test_files:
|
|
139
145
|
- spec/autoloaded/refine/string/to_source_filename_spec.rb
|
140
146
|
- spec/autoloaded/version_spec.rb
|
141
147
|
- spec/autoloaded_spec.rb
|
148
|
+
- spec/fixtures/autoloaded_with_conventional_filename.rb
|
149
|
+
- spec/fixtures/autoloaded_with_conventional_filename/N-est-ed.rb
|
150
|
+
- spec/fixtures/autoloaded_with_conventional_filename/nest_ed.rb
|
151
|
+
- spec/fixtures/autoloaded_with_conventional_filename/nested.rb
|
152
|
+
- spec/fixtures/autoloaded_with_conventional_filename/old_school_autoload.rb
|
153
|
+
- spec/fixtures/autoloaded_with_conventional_filename_only.rb
|
154
|
+
- spec/fixtures/autoloaded_with_conventional_filename_only/nested.rb
|
155
|
+
- spec/fixtures/autoloaded_with_conventional_filename_only/old_school_autoload.rb
|
156
|
+
- spec/fixtures/autoloaded_with_unconventional_filenames.rb
|
157
|
+
- spec/fixtures/autoloaded_with_unconventional_filenames/N-est-ed.rb
|
158
|
+
- spec/fixtures/autoloaded_with_unconventional_filenames/nest_ed.rb
|
159
|
+
- spec/fixtures/autoloaded_with_unconventional_filenames/old_school_autoload.rb
|
142
160
|
- spec/fixtures/filenames/AFilename.rb
|
143
161
|
- spec/fixtures/filenames/a-file-name.rb
|
144
162
|
- spec/fixtures/filenames/a-filename.rb
|
@@ -146,16 +164,10 @@ test_files:
|
|
146
164
|
- spec/fixtures/filenames/a_filename.rb
|
147
165
|
- spec/fixtures/filenames/afile-name.rb
|
148
166
|
- spec/fixtures/filenames/afile_name.rb
|
149
|
-
- spec/fixtures/
|
150
|
-
- spec/fixtures/
|
151
|
-
- spec/fixtures/namespace_that_is_autoloaded_conventionally/nest_ed.rb
|
152
|
-
- spec/fixtures/namespace_that_is_autoloaded_conventionally/nested.rb
|
153
|
-
- spec/fixtures/namespace_that_is_autoloaded_unconventionally.rb
|
154
|
-
- spec/fixtures/namespace_that_is_autoloaded_unconventionally/N-est-ed.rb
|
155
|
-
- spec/fixtures/namespace_that_is_autoloaded_unconventionally/nest_ed.rb
|
156
|
-
- spec/fixtures/namespace_that_is_not_autoloaded.rb
|
157
|
-
- spec/fixtures/namespace_that_is_not_autoloaded/nested.rb
|
167
|
+
- spec/fixtures/not_autoloaded.rb
|
168
|
+
- spec/fixtures/not_autoloaded/old_school_autoload.rb
|
158
169
|
- spec/matchers.rb
|
159
170
|
- spec/spec_helper.rb
|
171
|
+
- spec/support/util.rb
|
160
172
|
- spec/support/without_side_effects.rb
|
161
173
|
has_rdoc:
|
data/History.markdown
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
module NamespaceThatIsNotAutoloaded; end
|