royw-read_page_cache 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.
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2009 Roy Wright
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,43 @@
1
+ = read_page_cache
2
+
3
+ == Synopsis
4
+ The purpose of the module is to cache web pages used for testing by overriding
5
+ the classes' read_page method and replacing it with one that will cache pages.
6
+
7
+ == Usage
8
+ Your main code needs to have a read_page(page) instance method(s). Here's an
9
+ example:
10
+
11
+ class ClassName
12
+ def read_page(page)
13
+ open(page).read
14
+ end
15
+ end
16
+
17
+ Then your test code should include:
18
+
19
+ # default directory is '/tmp'
20
+ directory = '/path/to/cache/files'
21
+
22
+ require 'cache_extensions'
23
+ ReadPageCache.attach_to ClassName, directory
24
+
25
+ You may attach_to however many classes that you need to.
26
+
27
+ If you want to override all the read_page(page) methods in your application,
28
+ then your test code can instead use:
29
+
30
+ # default directory is '/tmp'
31
+ directory = '/path/to/cache/files'
32
+
33
+ require 'cache_extensions'
34
+ ReadPageCache.attach_to_classes directory
35
+
36
+ That's it. The first time you run your tests, the web pages your application
37
+ accesses with read_page will be cached, then the cached files will be used by
38
+ all subsequent accesses. You may want to review the cache and add any files
39
+ you want to your version control system.
40
+
41
+ == Copyright
42
+
43
+ Copyright (c) 2009 Roy Wright. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "read_page_cache"
8
+ gem.summary = %Q{TODO}
9
+ gem.email = "roy@wright.org"
10
+ gem.homepage = "http://github.com/royw/read_page_cache"
11
+ gem.authors = ["Roy Wright"]
12
+
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+ rescue LoadError
16
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
17
+ end
18
+
19
+ require 'spec/rake/spectask'
20
+ Spec::Rake::SpecTask.new(:spec) do |spec|
21
+ spec.libs << 'lib' << 'spec'
22
+ spec.spec_files = FileList['spec/**/*_spec.rb']
23
+ end
24
+
25
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
26
+ spec.libs << 'lib' << 'spec'
27
+ spec.pattern = 'spec/**/*_spec.rb'
28
+ spec.rcov = true
29
+ end
30
+
31
+
32
+ task :default => :spec
33
+
34
+ require 'rake/rdoctask'
35
+ Rake::RDocTask.new do |rdoc|
36
+ if File.exist?('VERSION.yml')
37
+ config = YAML.load(File.read('VERSION.yml'))
38
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
39
+ else
40
+ version = ""
41
+ end
42
+
43
+ rdoc.rdoc_dir = 'rdoc'
44
+ rdoc.title = "read_page_cache #{version}"
45
+ rdoc.rdoc_files.include('README*')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ end
48
+
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 1
3
+ :major: 0
4
+ :minor: 0
@@ -0,0 +1,18 @@
1
+ # == Synopsis
2
+ # add a mkdirs method to the File class
3
+ class File
4
+ class << self
5
+ my_extension("mkdirs") do
6
+ ##
7
+ # make directories including any missing in the path
8
+ #
9
+ # @param [String] dirspec the path to make sure exists
10
+ def File.mkdirs(dirspec)
11
+ unless File.exists?(dirspec)
12
+ mkdirs(File.dirname(dirspec))
13
+ Dir.mkdir(dirspec)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ ######################################################################
2
+ # my extensions to Module. (taken from rake, named changed to not clash
3
+ # when rake is used for this rails project.
4
+ #
5
+ class Module
6
+ # Check for an existing method in the current class before extending. IF
7
+ # the method already exists, then a warning is printed and the extension is
8
+ # not added. Otherwise the block is yielded and any definitions in the
9
+ # block will take effect.
10
+ #
11
+ # Usage:
12
+ #
13
+ # class String
14
+ # rake_extension("xyz") do
15
+ # def xyz
16
+ # ...
17
+ # end
18
+ # end
19
+ # end
20
+ #
21
+ def my_extension(method)
22
+ unless instance_methods.include?(method.to_s) || instance_methods.include?(method.to_sym)
23
+ yield
24
+ end
25
+ end
26
+ end # module Module
27
+
@@ -0,0 +1,89 @@
1
+ require 'module_extensions'
2
+ require 'file_extensions'
3
+
4
+ # == Synopsis
5
+ # The purpose of the module is to cache web pages used for
6
+ # testing by overriding the classes' read_page method and
7
+ # replacing it with one that will cache pages.
8
+ #
9
+ # == Usage
10
+ # Your main code needs to have a read_page(page) instance
11
+ # method(s). Here's an example:
12
+ #
13
+ # class ClassName
14
+ # def read_page(page)
15
+ # open(page).read
16
+ # end
17
+ # end
18
+ #
19
+ # Then your test code should include:
20
+ #
21
+ # # default directory is '/tmp'
22
+ # directory = '/path/to/cache/files'
23
+ # require 'cache_extensions'
24
+ # ReadPageCache.attach_to ClassName, directory
25
+ #
26
+ # You may attach_to however many classes that you need to.
27
+ #
28
+ # If you want to override all the read_page(page) methods
29
+ # in your application, then your test code can instead use:
30
+ #
31
+ # # default directory is '/tmp'
32
+ # directory = '/path/to/cache/files'
33
+ # require 'cache_extensions'
34
+ # ReadPageCache.attach_to_classes directory
35
+ #
36
+ # That's it. The first time you run your tests, the pages
37
+ # your application accesses with read_page will be cached,
38
+ # then the cached files will be used by all subsequent accesses.
39
+ #
40
+ module ReadPageCache
41
+ # == Synopsis
42
+ # Attach the read_page and cache_file methods to the given
43
+ # class (cls) and use the given directory for the cache files
44
+ def self.attach_to(cls, directory='/tmp')
45
+
46
+ # define the read_page(page) method on the given class: cls
47
+ cls.send('define_method', "read_page") do |page|
48
+ data = nil
49
+ filespec = page.gsub(/^http:\//, directory).gsub(/\/$/, '.html')
50
+ if File.exist?(filespec)
51
+ data = open(filespec).read
52
+ else
53
+ data = open(page).read
54
+ _cache_file(page, data)
55
+ end
56
+ data
57
+ end
58
+
59
+ # define the cache_file(page, data) method on the given class: cls
60
+ cls.send('define_method', "_cache_file") do |page, data|
61
+ begin
62
+ filespec = page.gsub(/^http:\//, directory).gsub(/\/$/, '.html')
63
+ unless File.exist?(filespec)
64
+ puts "caching #{filespec}"
65
+ File.mkdirs(File.dirname(filespec))
66
+ File.open(filespec, 'w') { |f| f.puts data }
67
+ end
68
+ rescue Exception => eMsg
69
+ puts eMsg.to_s
70
+ end
71
+ end
72
+ end
73
+
74
+ # == Synopsis
75
+ # Find all classes that have a read_page instance method and
76
+ # then overwrite that read_page method with one that handles
77
+ # the caching. Use the given directory for the cache files.
78
+ def self.attach_to_classes(directory='/tmp')
79
+ ObjectSpace.each_object(Class) do |cls|
80
+ # need to check all scopes for read_page instance method
81
+ if(cls.public_instance_methods(false).include?("read_page") ||
82
+ cls.protected_instance_methods(false).include?("read_page") ||
83
+ cls.private_instance_methods(false).include?("read_page"))
84
+ ReadPageCache.attach_to(cls, directory)
85
+ end
86
+ end
87
+ end
88
+ end
89
+
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+ require 'ruby-debug'
3
+ require 'open-uri'
4
+
5
+ TMPDIR = File.join(File.dirname(__FILE__), '../tmp')
6
+ Dir.mkdir(TMPDIR) unless File.exist?(TMPDIR)
7
+
8
+ TEST_DATA = "Testing cache read"
9
+
10
+ describe "ReadPageCache" do
11
+
12
+ after(:each) do
13
+ Dir.glob(File.join(TMPDIR, '*')).each {|f| File.delete(f) if File.exist?(f)}
14
+ end
15
+
16
+ it 'should add read_page method to a class' do
17
+ class A
18
+ end
19
+ # attach to the class then create instance
20
+ ReadPageCache.attach_to A, TMPDIR
21
+ a = A.new
22
+ a.respond_to?('read_page').should be_true
23
+ end
24
+
25
+ it 'should add read_page method to a class not the instance' do
26
+ class A
27
+ end
28
+ # create instance then attach to the class
29
+ a = A.new
30
+ ReadPageCache.attach_to A, TMPDIR
31
+ a.respond_to?('read_page').should be_true
32
+ end
33
+
34
+ # this is not nice but we make a web access to www.example.com
35
+ # just to get a response to cache. There probably is a better
36
+ # website to do this to.
37
+ it 'should override the read_page method in a class' do
38
+ class A
39
+ def read_page(page)
40
+ open(page).read
41
+ end
42
+ end
43
+ ReadPageCache.attach_to A, TMPDIR
44
+ a = A.new
45
+ a.read_page('http://www.example.com/')
46
+ filespec = File.join(TMPDIR, 'www.example.com.html')
47
+ (File.exist?(filespec).should be_true) && (File.size(filespec).should > 0)
48
+ end
49
+
50
+ it 'should read from the cache' do
51
+ filespec = File.join(TMPDIR, 'www.example.com.html')
52
+ File.open(filespec, "w") {|f| f.puts TEST_DATA}
53
+
54
+ class A
55
+ def read_page(page)
56
+ open(page).read
57
+ end
58
+ end
59
+ ReadPageCache.attach_to A, TMPDIR
60
+ a = A.new
61
+ data = a.read_page('http://www.example.com/').strip
62
+ data.should == TEST_DATA
63
+ end
64
+
65
+ it 'should replace all read_page methods in all classes' do
66
+ # create two classes with read_page methods
67
+ class A
68
+ def read_page(page)
69
+ open(page).read
70
+ end
71
+ end
72
+ class B
73
+ def read_page(page)
74
+ open(page).read
75
+ end
76
+ end
77
+ # when we attach to the class, ReadPageCache also puts a _cache_file method
78
+ # into the class, so we can simply test for it's presence.
79
+ ReadPageCache.attach_to_classes(TMPDIR)
80
+ a = A.new
81
+ b = B.new
82
+ (a.respond_to?('_cache_file').should be_true) && (b.respond_to?('_cache_file').should be_true)
83
+ end
84
+
85
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec'
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ require 'read_page_cache'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: royw-read_page_cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Roy Wright
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-20 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: roy@wright.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - LICENSE
27
+ - README.rdoc
28
+ - Rakefile
29
+ - VERSION.yml
30
+ - lib/file_extensions.rb
31
+ - lib/module_extensions.rb
32
+ - lib/read_page_cache.rb
33
+ - spec/read_page_cache_spec.rb
34
+ - spec/spec_helper.rb
35
+ has_rdoc: true
36
+ homepage: http://github.com/royw/read_page_cache
37
+ post_install_message:
38
+ rdoc_options:
39
+ - --charset=UTF-8
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ requirements: []
55
+
56
+ rubyforge_project:
57
+ rubygems_version: 1.2.0
58
+ signing_key:
59
+ specification_version: 2
60
+ summary: TODO
61
+ test_files:
62
+ - spec/spec_helper.rb
63
+ - spec/read_page_cache_spec.rb