require3 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 20923b83b2c2fd84983d468119c94a62bacec1c8
4
+ data.tar.gz: 53bd929da016af99bd3ad195cc912230af3ca440
5
+ SHA512:
6
+ metadata.gz: 1a7074ea862ff6d7c5ba040bb3788f1c2ce88aee04b1786510578ba39b21389bfcbb7c16caf509616f48ce0761ad7fe244783552e758e723a422cc65b9389882
7
+ data.tar.gz: f86d85780ca3dabeaef25fef4f260ccd3edae12187a8560269a6b0d6da66cab4e57e721768b67f6a9455b5534b612c91334f12cf88f6f64e531bf4774ae9f624
@@ -0,0 +1,76 @@
1
+ require "require3/version"
2
+
3
+ # Don't pollute global namespace
4
+ begin
5
+ old = ENV["ALIAS2_NO_EXPORT"]
6
+ ENV["ALIAS2_NO_EXPORT"] = "1"
7
+ require "alias2"
8
+ ensure
9
+ ENV["ALIAS2_NO_EXPORT"] = old
10
+ end
11
+
12
+ module Require3
13
+ class << self
14
+ def require(config)
15
+ lib, aliases = config.instance_of?(Hash) ? config.first : config
16
+
17
+ last_loaded = $"[-1]
18
+
19
+ first_load = Kernel::require(lib)
20
+ return first_load unless first_load && aliases
21
+
22
+ # Path/file name components.
23
+ # lib can be frozen so we use sub() first
24
+ lib = lib.sub(%r{\A(?:\.\.?/)+}, "")
25
+ lib.sub!(/\.(?:rb|o|dll)\z/, "")
26
+
27
+ begin
28
+ aliases = const_get(camelize(lib)).constants if aliases == "*".freeze
29
+
30
+ # FIXME: a/b/c may not always define A::B::C
31
+ case aliases
32
+ when String
33
+ set_alias(lib, aliases)
34
+ when Array
35
+ aliases.each { |name| set_alias("#{lib}/#{name}", name) }
36
+ else
37
+ aliases.each do |target, alias_as|
38
+ target = target.to_s
39
+ # If the target has a namespace use it as is
40
+ target = "#{lib}/#{target}" unless target.include?("::")
41
+ set_alias(target, alias_as)
42
+ end
43
+ end
44
+ rescue
45
+ # Remove libs that were loaded by our require
46
+ # Is this portable?
47
+ $".pop while $".any? && $"[-1] != last_loaded
48
+ raise
49
+ end
50
+
51
+ first_load
52
+ end
53
+
54
+ private
55
+
56
+ def set_alias(target, alias_as)
57
+ Alias2.alias(camelize(target), camelize(alias_as))
58
+ end
59
+
60
+ def camelize(term)
61
+ # term can be a Symbol or a String that's frozen (so we dup)
62
+ string = term.to_s.dup
63
+
64
+ # More or less stolen from ActiveSupport::Inflector#camelize
65
+ # https://api.rubyonrails.org/v4.2.6/classes/ActiveSupport/Inflector.html#method-i-camelize
66
+ string.sub!(/\A[a-z\d]*/) { $&.capitalize }
67
+ string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
68
+ string.gsub!(/\//, "::")
69
+ string
70
+ end
71
+ end
72
+ end
73
+
74
+ def require3(name)
75
+ Require3.require(name)
76
+ end
@@ -0,0 +1,3 @@
1
+ module Require3
2
+ VERSION = "0.0.1".freeze
3
+ end
@@ -0,0 +1,12 @@
1
+ module A
2
+ module Baz
3
+ end
4
+
5
+ module B
6
+ module Foo
7
+ end
8
+
9
+ module Bar
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,4 @@
1
+ module A
2
+ module B
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module A
2
+ module C
3
+ module Foo
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ require_relative "./b.rb"
2
+ require_relative "./c.rb"
3
+
4
+ module A
5
+ module JustDependencies
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ require_relative "./b.rb"
2
+ require_relative "./c.rb"
@@ -0,0 +1 @@
1
+ require "a/b"
@@ -0,0 +1,2 @@
1
+ require "./b.rb"
2
+ require "./c.rb"
@@ -0,0 +1,14 @@
1
+ require "minitest/autorun"
2
+ require "require2"
3
+
4
+ class TestPageNumber < MiniTest::Test
5
+ def setup
6
+ @p = Object.new
7
+ @p.extend PageNumber
8
+ end
9
+
10
+ def test_simple_alias
11
+ assert_equal 100, @p.page(-1)
12
+ end
13
+
14
+ end
@@ -0,0 +1,137 @@
1
+ require "minitest/autorun"
2
+ require "require3"
3
+
4
+ class TestRequire3 < MiniTest::Test
5
+ CONSTANTS = %w[Foo Bar Baz CSV]
6
+ FILES = %w[a/b.rb a/c.rb]
7
+
8
+ def setup
9
+ @libroot = File.join(File.dirname(__FILE__), "lib")
10
+ $: << @libroot
11
+ end
12
+
13
+ def teardown
14
+ FILES.each { |name| $".delete("#@libroot/#{name}") }
15
+
16
+ CONSTANTS.each do |name|
17
+ Object.send(:remove_const, name) if Object.const_defined?(name)
18
+ end
19
+ end
20
+
21
+ def test_returns_true_if_not_loaded_and_false_if_loaded
22
+ assert_equal true, require3("a/b")
23
+ assert_equal false, require3("a/b")
24
+ end
25
+
26
+ def test_without_aliases
27
+ require3 "a/b"
28
+ assert Object.const_defined?("A::B")
29
+ end
30
+
31
+ def test_with_simple_alias
32
+ require3 "a/b" => "foo"
33
+ assert Object.const_defined?("Foo")
34
+ assert Object.const_defined?("A::B")
35
+ assert_equal A::B, Foo
36
+ end
37
+
38
+ def test_with_glob
39
+ require3 "a/b" => "*"
40
+
41
+ assert Object.const_defined?("Foo")
42
+ assert Object.const_defined?("Bar")
43
+ assert Object.const_defined?("A::B::Foo")
44
+ assert Object.const_defined?("A::B::Bar")
45
+
46
+ assert_equal A::B::Foo, Foo
47
+ assert_equal A::B::Bar, Bar
48
+ end
49
+
50
+ def test_with_array_argument
51
+ require3 "a/b" => %w[foo bar]
52
+
53
+ assert Object.const_defined?("Foo")
54
+ assert Object.const_defined?("Bar")
55
+ assert Object.const_defined?("A::B::Foo")
56
+ assert Object.const_defined?("A::B::Bar")
57
+
58
+ assert_equal A::B::Foo, Foo
59
+ assert_equal A::B::Bar, Bar
60
+ end
61
+
62
+ def test_with_hash_aliases_using_path_style_names
63
+ require3 "a/b" => { :foo => "foo", "a/baz" => "baz" }
64
+
65
+ assert Object.const_defined?("Foo")
66
+ assert Object.const_defined?("Baz")
67
+ assert Object.const_defined?("A::B::Foo")
68
+ assert Object.const_defined?("A::Baz")
69
+
70
+ assert_equal A::B::Foo, Foo
71
+ assert_equal A::Baz, Baz
72
+ end
73
+
74
+ def test_with_hash_aliases_using_class_style_names
75
+ require3 "a/b" => { "Foo" => "Foo", "A::Baz" => "Baz" }
76
+
77
+ assert Object.const_defined?("Foo")
78
+ assert Object.const_defined?("Baz")
79
+ assert Object.const_defined?("A::B::Foo")
80
+ assert Object.const_defined?("A::Baz")
81
+
82
+ assert_equal A::B::Foo, Foo
83
+ assert_equal A::Baz, Baz
84
+ end
85
+
86
+ def test_relative_path_simple_alias
87
+ Dir.chdir @libroot do
88
+ require3 "./a/c.rb" => "foo"
89
+ end
90
+
91
+ assert Object.const_defined?("Foo")
92
+ assert Object.const_defined?("A::C")
93
+
94
+ assert_equal A::C, Foo
95
+ end
96
+
97
+ def test_relative_path_using_array_argument
98
+ Dir.chdir @libroot do
99
+ require3 "./a/c.rb" => %w[foo]
100
+ end
101
+
102
+ assert Object.const_defined?("Foo")
103
+ assert Object.const_defined?("A::C::Foo")
104
+
105
+ assert_equal A::C::Foo, Foo
106
+ end
107
+
108
+ def test_removes_loaded_features_on_error
109
+ assert_raises NameError do
110
+ require3 "a/b" => {:bad => "foo"}
111
+ end
112
+
113
+ assert $".none? { |path| path.end_with?("a/b.rb") }
114
+ end
115
+
116
+ def test_removes_loaded_dependency_features_on_error
117
+ assert_raises NameError do
118
+ require3 "a/just_dependencies" => {:bad => "foo"}
119
+ end
120
+
121
+ assert $".none? { |path| path.end_with?("a/just_dependencies.rb") }
122
+ assert $".none? { |path| path.end_with?("a/b.rb") }
123
+ assert $".none? { |path| path.end_with?("a/c.rb") }
124
+ end
125
+
126
+ def test_does_not_remove_other_loaded_dependency_features_on_error
127
+ require "csv"
128
+
129
+ assert_raises NameError do
130
+ require3 "a/b" => {:bad => "foo"}
131
+ end
132
+
133
+ # CSV was successfuly loaded outside require3 so make sure it's not removed by require3
134
+ assert $".any? { |path| path.end_with?("/csv.rb") }
135
+ end
136
+
137
+ end
@@ -0,0 +1,137 @@
1
+ require "minitest/autorun"
2
+ require "require3"
3
+
4
+ class TestRequire3 < MiniTest::Test
5
+ CONSTANTS = %w[Foo Bar Baz CSV]
6
+ FILES = %w[a/b.rb a/c.rb]
7
+
8
+ def setup
9
+ @libroot = File.join(File.dirname(__FILE__), "lib")
10
+ $: << @libroot
11
+ end
12
+
13
+ def teardown
14
+ FILES.each { |name| $".delete("#@libroot/#{name}") }
15
+
16
+ CONSTANTS.each do |name|
17
+ Object.send(:remove_const, name) if Object.const_defined?(name)
18
+ end
19
+ end
20
+
21
+ def test_returns_true_if_not_loaded_and_false_if_loaded
22
+ assert_equal true, require2("a/b")
23
+ assert_equal false, require2("a/b")
24
+ end
25
+
26
+ def test_without_aliases
27
+ require2 "a/b"
28
+ assert Object.const_defined?("A::B")
29
+ end
30
+
31
+ def test_with_simple_alias
32
+ require2 "a/b" => "foo"
33
+ assert Object.const_defined?("Foo")
34
+ assert Object.const_defined?("A::B")
35
+ assert_equal A::B, Foo
36
+ end
37
+
38
+ def test_with_glob
39
+ require2 "a/b" => "*"
40
+
41
+ assert Object.const_defined?("Foo")
42
+ assert Object.const_defined?("Bar")
43
+ assert Object.const_defined?("A::B::Foo")
44
+ assert Object.const_defined?("A::B::Bar")
45
+
46
+ assert_equal A::B::Foo, Foo
47
+ assert_equal A::B::Bar, Bar
48
+ end
49
+
50
+ def test_with_array_argument
51
+ require2 "a/b" => %w[foo bar]
52
+
53
+ assert Object.const_defined?("Foo")
54
+ assert Object.const_defined?("Bar")
55
+ assert Object.const_defined?("A::B::Foo")
56
+ assert Object.const_defined?("A::B::Bar")
57
+
58
+ assert_equal A::B::Foo, Foo
59
+ assert_equal A::B::Bar, Bar
60
+ end
61
+
62
+ def test_with_hash_aliases_using_path_style_names
63
+ require2 "a/b" => { :foo => "foo", "a/baz" => "baz" }
64
+
65
+ assert Object.const_defined?("Foo")
66
+ assert Object.const_defined?("Baz")
67
+ assert Object.const_defined?("A::B::Foo")
68
+ assert Object.const_defined?("A::Baz")
69
+
70
+ assert_equal A::B::Foo, Foo
71
+ assert_equal A::Baz, Baz
72
+ end
73
+
74
+ def test_with_hash_aliases_using_class_style_names
75
+ require2 "a/b" => { "Foo" => "Foo", "A::Baz" => "Baz" }
76
+
77
+ assert Object.const_defined?("Foo")
78
+ assert Object.const_defined?("Baz")
79
+ assert Object.const_defined?("A::B::Foo")
80
+ assert Object.const_defined?("A::Baz")
81
+
82
+ assert_equal A::B::Foo, Foo
83
+ assert_equal A::Baz, Baz
84
+ end
85
+
86
+ def test_relative_path_simple_alias
87
+ Dir.chdir @libroot do
88
+ require2 "./a/c.rb" => "foo"
89
+ end
90
+
91
+ assert Object.const_defined?("Foo")
92
+ assert Object.const_defined?("A::C")
93
+
94
+ assert_equal A::C, Foo
95
+ end
96
+
97
+ def test_relative_path_using_array_argument
98
+ Dir.chdir @libroot do
99
+ require2 "./a/c.rb" => %w[foo]
100
+ end
101
+
102
+ assert Object.const_defined?("Foo")
103
+ assert Object.const_defined?("A::C::Foo")
104
+
105
+ assert_equal A::C::Foo, Foo
106
+ end
107
+
108
+ def test_removes_loaded_features_on_error
109
+ assert_raises NameError do
110
+ require2 "a/b" => {:bad => "foo"}
111
+ end
112
+
113
+ assert $".none? { |path| path.end_with?("a/b.rb") }
114
+ end
115
+
116
+ def test_removes_loaded_dependency_features_on_error
117
+ assert_raises NameError do
118
+ require2 "a/just_dependencies" => {:bad => "foo"}
119
+ end
120
+
121
+ assert $".none? { |path| path.end_with?("a/just_dependencies.rb") }
122
+ assert $".none? { |path| path.end_with?("a/b.rb") }
123
+ assert $".none? { |path| path.end_with?("a/c.rb") }
124
+ end
125
+
126
+ def test_does_not_remove_other_loaded_dependency_features_on_error
127
+ require "csv"
128
+
129
+ assert_raises NameError do
130
+ require2 "a/b" => {:bad => "foo"}
131
+ end
132
+
133
+ # CSV was successfuly loaded outside require2 so make sure it's not removed by require2
134
+ assert $".any? { |path| path.end_with?("/csv.rb") }
135
+ end
136
+
137
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: require3
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Skye Shaw
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: alias2
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.8'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
69
+ description:
70
+ email: skye.shaw@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/require3.rb
76
+ - lib/require3/version.rb
77
+ - test/lib/a/b.rb
78
+ - test/lib/a/b.rb~
79
+ - test/lib/a/c.rb
80
+ - test/lib/a/just_dependencies.rb
81
+ - test/lib/a/just_dependencies.rb~
82
+ - test/lib/a/requires.rb~
83
+ - test/lib/a/with_dependencies.rb~
84
+ - test/test_require2.rb~
85
+ - test/test_require3.rb
86
+ - test/test_require3.rb~
87
+ homepage: http://github.com/sshaw/require2
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.6.14
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: Kernel#require something and make its contents accessible via a different
111
+ namespace.
112
+ test_files:
113
+ - test/lib/a/b.rb
114
+ - test/lib/a/b.rb~
115
+ - test/lib/a/c.rb
116
+ - test/lib/a/just_dependencies.rb
117
+ - test/lib/a/just_dependencies.rb~
118
+ - test/lib/a/requires.rb~
119
+ - test/lib/a/with_dependencies.rb~
120
+ - test/test_require2.rb~
121
+ - test/test_require3.rb
122
+ - test/test_require3.rb~