royw-read_page_cache 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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