class_loader 0.4.15 → 3.0.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 (44) hide show
  1. data/Rakefile +2 -1
  2. data/lib/class_loader/class_loader.rb +99 -207
  3. data/lib/class_loader/support.rb +0 -11
  4. data/lib/class_loader/watcher.rb +44 -0
  5. data/lib/class_loader.rb +6 -19
  6. data/readme.md +27 -28
  7. data/spec/class_loader_spec/anonymous_class/some_namespace/some_class.rb +2 -0
  8. data/spec/class_loader_spec/another_namespace/some_namespace/namespace_a.rb +2 -0
  9. data/spec/class_loader_spec/another_namespace/{AnotherNamespace/NamespaceB.rb → some_namespace/namespace_b.rb} +1 -1
  10. data/spec/class_loader_spec/another_namespace/some_namespace.rb +2 -0
  11. data/spec/class_loader_spec/basics/another_class.rb +2 -0
  12. data/spec/class_loader_spec/{basic/BasicSpec/SomeNamespace/SomeClass.rb → basics/some_class.rb} +0 -0
  13. data/spec/class_loader_spec/basics/some_namespace/some_class.rb +2 -0
  14. data/spec/class_loader_spec/basics/some_namespace.rb +2 -0
  15. data/spec/class_loader_spec/infinity_loop/some_class.rb +2 -0
  16. data/spec/class_loader_spec/namespace_resolving/some_namespace/some_class.rb +2 -0
  17. data/spec/class_loader_spec/namespace_resolving/some_namespace.rb +2 -0
  18. data/spec/class_loader_spec/{namespace_type_resolving/NamespaceIsAlreadyDefinedAsClass/SomeClass.rb → only_once/some_class.rb} +0 -0
  19. data/spec/class_loader_spec/{namespace_type_resolving/NamespaceTypeResolving/SomeClass.rb → preloading/some_class.rb} +0 -0
  20. data/spec/class_loader_spec/preloading/some_namespace/another_class.rb +2 -0
  21. data/spec/class_loader_spec/preloading/some_namespace.rb +2 -0
  22. data/spec/class_loader_spec/reloading/some_class.rb +3 -0
  23. data/spec/class_loader_spec.rb +96 -78
  24. metadata +20 -27
  25. data/lib/class_loader/chained_adapter.rb +0 -48
  26. data/lib/class_loader/file_system_adapter/camel_case_translator.rb +0 -16
  27. data/lib/class_loader/file_system_adapter/underscored_translator.rb +0 -16
  28. data/lib/class_loader/file_system_adapter.rb +0 -145
  29. data/lib/class_loader/spec.rb +0 -17
  30. data/lib/class_loader/tasks.rb +0 -8
  31. data/spec/class_loader_spec/anonymous_class/AnonymousSpec/ClassInsideOfAnonymousClass.rb +0 -2
  32. data/spec/class_loader_spec/another_namespace/AnotherNamespace/NamespaceA.rb +0 -2
  33. data/spec/class_loader_spec/basic/BasicSpec.rb +0 -2
  34. data/spec/class_loader_spec/infinity_loop/InfinityLoop.rb +0 -2
  35. data/spec/class_loader_spec/namespace_type_resolving/NamespaceTypeResolving.rb +0 -2
  36. data/spec/class_loader_spec/only_once/OnlyOnceSpec.rb +0 -2
  37. data/spec/class_loader_spec/preloading/PreloadingSpec.rb +0 -2
  38. data/spec/file_system_adapter_spec/common/SomeNamespace/SomeClass.rb +0 -1
  39. data/spec/file_system_adapter_spec/multiple_class_paths/path_a/ClassInPathA.rb +0 -2
  40. data/spec/file_system_adapter_spec/multiple_class_paths/path_b/ClassInPathB.rb +0 -2
  41. data/spec/file_system_adapter_spec/shouldnt_mess/CamelCaseClass.rb +0 -0
  42. data/spec/file_system_adapter_spec/shouldnt_mess/underscored_class.rb +0 -0
  43. data/spec/file_system_adapter_spec.rb +0 -112
  44. data/spec/translators_spec.rb +0 -35
@@ -1,145 +0,0 @@
1
- class ClassLoader::FileSystemAdapter
2
- attr_reader :translator
3
-
4
- def initialize class_name_translator
5
- @translator = class_name_translator
6
- @paths, @watched_paths, @file_name_cache = [], [], {}
7
- @watched_files, @first_check = {}, true
8
- end
9
-
10
- def exist? class_name
11
- !!to_file_path(class_name)
12
- end
13
- alias_method :exists?, :exist?
14
-
15
- def read class_name
16
- file_path = to_file_path class_name
17
- return nil unless file_path
18
-
19
- if file_path =~ /\.rb$/
20
- File.open(file_path){|f| f.read}
21
- else
22
- "module #{class_name}; end;"
23
- end
24
- end
25
-
26
- def to_file_path class_name
27
- file_path, exist = @file_name_cache[class_name] || []
28
- unless exist
29
- normalized_name = translator.to_file_path class_name
30
- file_path = catch :found do
31
- # files
32
- paths.each do |base|
33
- try = "#{base}/#{normalized_name}.rb"
34
- if File.exist? try
35
- throw :found, try
36
- end
37
- end
38
-
39
- # dirs
40
- paths.each do |base|
41
- try = "#{base}/#{normalized_name}"
42
- if File.exist? try
43
- throw :found, try
44
- end
45
- end
46
-
47
- nil
48
- end
49
- @file_name_cache[class_name] = [file_path, true]
50
- end
51
- file_path
52
- end
53
-
54
- def to_class_name normalized_path
55
- raise "Internal error, file_name should be absolute path (#{normalized_path})!" unless normalized_path =~ /^\//
56
- raise "Internal error, file_name should be without .rb suffix (#{normalized_path})!" if normalized_path =~ /\.rb$/
57
-
58
- paths.each do |base_path|
59
- if normalized_path.start_with? base_path
60
- normalized_name = normalized_path.sub(base_path + '/', '')
61
- if translator.is_it_class? normalized_name
62
- return translator.to_class_name(normalized_name)
63
- end
64
- end
65
- end
66
- nil
67
- end
68
-
69
- def add_path base_path, watch = false
70
- base_path = File.expand_path(base_path)
71
- # raise "#{base_path} already added!" if paths.include? base_path
72
- unless paths.include? base_path
73
- paths << base_path
74
- watched_paths << base_path if watch
75
- end
76
- end
77
-
78
- def delete_path path
79
- path = File.expand_path(path)
80
- paths.delete path
81
- watched_paths.delete path
82
- end
83
-
84
- def clear
85
- @paths, @watched_paths, @file_name_cache = [], [], {}
86
- @watched_files, @first_check = {}, true
87
- end
88
-
89
- def each_changed_class &block
90
- unless @first_check == @watched_paths
91
- @first_check = @watched_paths.clone
92
- each_watched_file{|file_path, file_name| remember_file file_path}
93
- else
94
- each_watched_file do |file_path, file_name|
95
- if file_changed? file_path
96
- remember_file file_path
97
-
98
- normalized_name = file_name.sub(/\.rb$/, "")
99
- block.call translator.to_class_name(normalized_name)
100
- end
101
- end
102
- end
103
- end
104
-
105
- def each_class &block
106
- @paths.each do |base_path|
107
- Dir.glob("#{base_path}/**/*.rb").each do |file_path|
108
- normalized_path = file_path.sub(/\.rb$/, "")
109
-
110
- normalized_name = normalized_path.sub(base_path + "/", '')
111
- class_name = translator.to_class_name(normalized_name)
112
- block.call class_name
113
- end
114
- end
115
- end
116
-
117
- def each_watched_file &block
118
- @watched_paths.each do |base_path|
119
- Dir.glob("#{base_path}/**/*.rb").each do |file_path|
120
- file_name = file_path.sub(base_path + '/', '')
121
-
122
- if translator.is_it_class? file_name
123
- block.call file_path, file_name
124
- end
125
- end
126
- end
127
- end
128
-
129
- def inspect
130
- "FileSystemAdapter (#{@paths.join(', ')})"
131
- end
132
-
133
- protected
134
- attr_reader :paths, :watched_paths, :watcher, :watched_files
135
-
136
- def file_changed? file_path
137
- old_time = watched_files[file_path]
138
- old_time == nil or old_time != File.mtime(file_path)
139
- end
140
-
141
- def remember_file file_path
142
- watched_files[file_path] = File.mtime(file_path)
143
- end
144
-
145
- end
@@ -1,17 +0,0 @@
1
- require 'rspec_ext'
2
-
3
- rspec do
4
- def self.with_autoload_path *paths
5
- before(:all){paths.each{|path| ClassLoader.autoload_path path}}
6
- after(:all){paths.each{|path| ClassLoader.delete_path path}}
7
- end
8
-
9
- def with_autoload_path *paths, &b
10
- begin
11
- paths.each{|path| ClassLoader.autoload_path path}
12
- b.call
13
- ensure
14
- paths.each{|path| ClassLoader.delete_path path}
15
- end
16
- end
17
- end
@@ -1,8 +0,0 @@
1
- desc "Cleans tmp files generated by ClassLoader in debug mode"
2
- namespace :class_loader do
3
- task :clean do
4
- Dir['../**/*.cltmp.rb'].each do |path|
5
- File.delete path
6
- end
7
- end
8
- end
@@ -1,2 +0,0 @@
1
- class ClassInsideOfAnonymousClass
2
- end
@@ -1,2 +0,0 @@
1
- class NamespaceA
2
- end
@@ -1,2 +0,0 @@
1
- class BasicSpec
2
- end
@@ -1,2 +0,0 @@
1
- class InvalidInfinityLoopClassName
2
- end
@@ -1,2 +0,0 @@
1
- class NamespaceTypeResolving
2
- end
@@ -1,2 +0,0 @@
1
- class OnlyOnceSpec
2
- end
@@ -1,2 +0,0 @@
1
- class PreloadingSpec
2
- end
@@ -1 +0,0 @@
1
- class SomeClass; end
@@ -1,2 +0,0 @@
1
- class ClassInPathA
2
- end
@@ -1,2 +0,0 @@
1
- class ClassInPathB
2
- end
@@ -1,112 +0,0 @@
1
- require "rspec_ext"
2
- require "class_loader"
3
-
4
- describe ClassLoader::FileSystemAdapter do
5
- with_tmp_spec_dir
6
-
7
- before do
8
- @fs_adapter = ClassLoader::FileSystemAdapter.new(ClassLoader::CamelCaseTranslator)
9
-
10
- # Actually we are testing both ChainedAdapter and FileSystemAdapter
11
- @adapter = ClassLoader::ChainedAdapter.new
12
- @adapter.adapters << @fs_adapter
13
-
14
- @adapter.add_path "#{spec_dir}/common"
15
- end
16
-
17
- def write_file path, klass
18
- File.open("#{spec_dir}/#{path}", 'w'){|f| f.write "class #{klass}; end"}
19
- end
20
-
21
- it "exist?" do
22
- @adapter.exist?("SomeNamespace").should be_true
23
- @adapter.exist?("SomeNamespace::SomeClass").should be_true
24
- @adapter.exist?("SomeNamespace::NonExistingClass").should be_false
25
- end
26
-
27
- it "should works with multiple class paths" do
28
- @adapter.add_path "#{spec_dir}/multiple_class_paths/path_a"
29
- @adapter.add_path "#{spec_dir}/multiple_class_paths/path_b"
30
-
31
- @adapter.exist?("ClassInPathA").should be_true
32
- @adapter.exist?("ClassInPathB").should be_true
33
- end
34
-
35
- it "read" do
36
- @adapter.read("SomeNamespace::SomeClass").should == "class SomeClass; end"
37
- end
38
-
39
- it "to_file_path" do
40
- @adapter.to_file_path("NonExistingClass").should be_nil
41
- @adapter.to_file_path("SomeNamespace::SomeClass").should =~ /SomeNamespace\/SomeClass/
42
- end
43
-
44
- it "to_class_name" do
45
- @adapter.to_class_name("#{spec_dir}/non_existing_path").should be_nil
46
- @adapter.to_class_name("#{spec_dir}/common/SomeNamespace").should == "SomeNamespace"
47
- @adapter.to_class_name("#{spec_dir}/common/SomeNamespace/SomeClass").should == "SomeNamespace::SomeClass"
48
- end
49
-
50
- it "shouldn't add path twice" do
51
- @adapter.clear
52
- @adapter.add_path "#{spec_dir}/common"
53
- @adapter.add_path "#{spec_dir}/common"
54
- @fs_adapter.instance_variable_get("@paths").size.should == 1
55
- end
56
-
57
- describe "file watching" do
58
- def changed_classes
59
- changed = []
60
- @adapter.each_changed_class{|c| changed << c}
61
- changed
62
- end
63
-
64
- it "each_changed_class shouldn't affect paths not specified for watching" do
65
- @adapter.add_path "#{spec_dir}/search_only_watched", false
66
- changed_classes.should == []
67
-
68
- sleep(1) && write_file("watching/SomeClass.rb", "SomeClass")
69
- changed_classes.should == []
70
- end
71
-
72
- it "each_changed_class" do
73
- @adapter.add_path "#{spec_dir}/watching", true
74
-
75
- changed_classes.should == []
76
-
77
- sleep(1) && write_file("watching/SomeClass.rb", "SomeClass")
78
- changed_classes.should == ["SomeClass"]
79
-
80
- sleep(1) && write_file("watching/SomeClass.rb", "SomeClass")
81
- changed_classes.should == ["SomeClass"]
82
- end
83
- end
84
-
85
- describe "Underscored shouldn't mess with CamelCase" do
86
- before do
87
- @camel_case_adapter = ClassLoader::FileSystemAdapter.new(ClassLoader::CamelCaseTranslator)
88
- @camel_case_adapter.add_path "#{spec_dir}/shouldnt_mess", true
89
- @camel_case_file_path = "#{spec_dir}/shouldnt_mess/CamelCaseClass.rb"
90
-
91
- @underscored_adapter = ClassLoader::FileSystemAdapter.new(ClassLoader::UnderscoredTranslator)
92
- @underscored_adapter.add_path "#{spec_dir}/shouldnt_mess", true
93
- @underscored_file_path = "#{spec_dir}/shouldnt_mess/underscored_class.rb"
94
- end
95
-
96
-
97
- it "should watch only files understable by its translator (CamelCase shouldn't load Underscored)" do
98
- watched = []
99
- @camel_case_adapter.each_watched_file{|file_path, relative_name| watched << relative_name}
100
- watched.should == ["CamelCaseClass.rb"]
101
-
102
- watched = []
103
- @underscored_adapter.each_watched_file{|file_path, relative_name| watched << relative_name}
104
- watched.should == ["underscored_class.rb"]
105
- end
106
-
107
- it "CamelCase to_class_name shouldn't translate Underscored" do
108
- @camel_case_adapter.to_class_name(@camel_case_file_path.sub(/\.rb$/, '')).should == "CamelCaseClass"
109
- @underscored_adapter.to_class_name(@underscored_file_path.sub(/\.rb$/, '')).should == "UnderscoredClass"
110
- end
111
- end
112
- end
@@ -1,35 +0,0 @@
1
- require 'rspec_ext'
2
- require 'class_loader/file_system_adapter/camel_case_translator'
3
- require 'class_loader/file_system_adapter/underscored_translator'
4
-
5
- describe "Translators" do
6
- describe "CamelCase" do
7
- before :all do
8
- @t = ClassLoader::CamelCaseTranslator
9
- end
10
-
11
- it "is_it_class?" do
12
- @t.is_it_class?("SomeClass.rb").should be_true
13
- @t.is_it_class?("SomeNamespace/SomeClass.rb").should be_true
14
-
15
- @t.is_it_class?("someclass.rb").should be_false
16
- @t.is_it_class?("some_class.rb").should be_false
17
- @t.is_it_class?("some_namespace/some_class.rb").should be_false
18
- end
19
- end
20
-
21
- describe "Underscored" do
22
- before :all do
23
- @t = ClassLoader::UnderscoredTranslator
24
- end
25
-
26
- it "is_it_class?" do
27
- @t.is_it_class?("SomeClass.rb").should be_false
28
- @t.is_it_class?("SomeNamespace/SomeClass.rb").should be_false
29
-
30
- @t.is_it_class?("someclass.rb").should be_true
31
- @t.is_it_class?("some_class.rb").should be_true
32
- @t.is_it_class?("some_namespace/some_class.rb").should be_true
33
- end
34
- end
35
- end