history_file 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +7 -0
- data/CHANGELOG.markdown +9 -0
- data/Gemfile +5 -1
- data/Gemfile.lock +2 -11
- data/Guardfile +11 -11
- data/README.markdown +99 -0
- data/VERSION +1 -1
- data/history_file.gemspec +9 -7
- data/lib/history_file/file_delegator.rb +31 -10
- data/lib/history_file/history_file.rb +11 -2
- data/spec/history_file/history_file_spec.rb +89 -43
- data/spec/spec_helper.rb +27 -37
- metadata +23 -21
- data/README.rdoc +0 -32
data/.travis.yml
ADDED
data/CHANGELOG.markdown
ADDED
data/Gemfile
CHANGED
@@ -12,6 +12,7 @@ group :development do
|
|
12
12
|
gem "jeweler", "~> 1.8.4"
|
13
13
|
gem "simplecov", ">= 0"
|
14
14
|
end
|
15
|
+
|
15
16
|
group :development, :test do
|
16
17
|
gem 'webmock'
|
17
18
|
gem 'rspec'
|
@@ -20,6 +21,9 @@ group :development, :test do
|
|
20
21
|
gem 'guard-rspec'
|
21
22
|
gem 'guard-bundler'
|
22
23
|
gem 'guard-yard'
|
23
|
-
gem 'guard-spork'
|
24
24
|
gem 'rb-fsevent'
|
25
25
|
end
|
26
|
+
|
27
|
+
platform :ruby do
|
28
|
+
gem 'redcarpet'
|
29
|
+
end
|
data/Gemfile.lock
CHANGED
@@ -5,12 +5,9 @@ GEM
|
|
5
5
|
i18n (~> 0.6)
|
6
6
|
multi_json (~> 1.0)
|
7
7
|
addressable (2.3.2)
|
8
|
-
childprocess (0.3.6)
|
9
|
-
ffi (~> 1.0, >= 1.0.6)
|
10
8
|
coderay (1.0.8)
|
11
9
|
crack (0.3.1)
|
12
10
|
diff-lcs (1.1.3)
|
13
|
-
ffi (1.1.5)
|
14
11
|
git (1.2.5)
|
15
12
|
guard (1.5.4)
|
16
13
|
listen (>= 0.4.2)
|
@@ -23,11 +20,6 @@ GEM
|
|
23
20
|
guard-rspec (2.1.1)
|
24
21
|
guard (>= 1.1)
|
25
22
|
rspec (~> 2.11)
|
26
|
-
guard-spork (1.2.3)
|
27
|
-
childprocess (>= 0.2.3)
|
28
|
-
guard (>= 1.1)
|
29
|
-
spork (>= 0.8.4)
|
30
|
-
sys-proctable
|
31
23
|
guard-yard (2.0.1)
|
32
24
|
guard (>= 1.1.0)
|
33
25
|
yard (>= 0.7.0)
|
@@ -50,6 +42,7 @@ GEM
|
|
50
42
|
rb-fsevent (0.9.2)
|
51
43
|
rdoc (3.12)
|
52
44
|
json (~> 1.4)
|
45
|
+
redcarpet (2.2.2)
|
53
46
|
rspec (2.12.0)
|
54
47
|
rspec-core (~> 2.12.0)
|
55
48
|
rspec-expectations (~> 2.12.0)
|
@@ -69,8 +62,6 @@ GEM
|
|
69
62
|
simplecov-html (~> 0.7.1)
|
70
63
|
simplecov-html (0.7.1)
|
71
64
|
slop (3.3.3)
|
72
|
-
spork (0.9.2)
|
73
|
-
sys-proctable (0.9.2)
|
74
65
|
terminal-notifier (1.4.2)
|
75
66
|
thor (0.16.0)
|
76
67
|
webmock (1.9.0)
|
@@ -86,11 +77,11 @@ DEPENDENCIES
|
|
86
77
|
guard
|
87
78
|
guard-bundler
|
88
79
|
guard-rspec
|
89
|
-
guard-spork
|
90
80
|
guard-yard
|
91
81
|
jeweler (~> 1.8.4)
|
92
82
|
rb-fsevent
|
93
83
|
rdoc (~> 3.12)
|
84
|
+
redcarpet
|
94
85
|
rspec
|
95
86
|
shoulda
|
96
87
|
simplecov
|
data/Guardfile
CHANGED
@@ -26,17 +26,17 @@ guard 'rspec', :version => 2 do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
|
29
|
-
guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
29
|
+
# guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do
|
30
|
+
# watch('config/application.rb')
|
31
|
+
# watch('config/environment.rb')
|
32
|
+
# watch('config/environments/test.rb')
|
33
|
+
# watch(%r{^config/initializers/.+\.rb$})
|
34
|
+
# watch('Gemfile')
|
35
|
+
# watch('Gemfile.lock')
|
36
|
+
# watch('spec/spec_helper.rb') { :rspec }
|
37
|
+
# watch('test/test_helper.rb') { :test_unit }
|
38
|
+
# watch(%r{features/support/}) { :cucumber }
|
39
|
+
# end
|
40
40
|
|
41
41
|
guard 'yard', port: 8808, stdout: '/dev/null' do
|
42
42
|
watch(%r{app/.+\.rb})
|
data/README.markdown
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
HistoryFile
|
2
|
+
===========
|
3
|
+
|
4
|
+
Behaves like a `File` class and does some convenience stuff
|
5
|
+
around a `HistoryFile::FileDelegator` instance. It lets you
|
6
|
+
version files by dates. A date prefix is added to the file
|
7
|
+
name.
|
8
|
+
|
9
|
+
If you want to write a file to store data from yesterday,
|
10
|
+
you could write:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
> f = HistoryFile[1.day.ago].new("/tmp/foo.txt", "w")
|
14
|
+
=> #<File:/tmp/2012.11.02-foo.txt>
|
15
|
+
```
|
16
|
+
|
17
|
+
The returned `HistoryFile::FileDelegator` object supports all
|
18
|
+
methods that File has, but adds a date prefix to those methods
|
19
|
+
that revolve around a single file (reading, writing, etc.)
|
20
|
+
|
21
|
+
If a file for a given date is not available, `HistoryFile` falls
|
22
|
+
back to the freshest file that is older than the given date.
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
> f = HistoryFile[3.days.ago].new("test.txt", "w")
|
26
|
+
=> #<File:./2012.11.12-test.txt>
|
27
|
+
> f.write("I am old")
|
28
|
+
=> 8
|
29
|
+
> f.close
|
30
|
+
=> nil
|
31
|
+
> HistoryFile[Date.today].read("test.txt")
|
32
|
+
=> "I am old"
|
33
|
+
> HistoryFile[10.days.ago].read("test.txt")
|
34
|
+
Errno::ENOENT: No such file or directory - ./2012.11.05-test.txt
|
35
|
+
```
|
36
|
+
It does this for every method where a prefix is added and when
|
37
|
+
an `Errno::ENOENT` is thrown.
|
38
|
+
|
39
|
+
Methods that patch all arguments with a date prefix
|
40
|
+
---------------------------------------------------
|
41
|
+
You can pass an arbitrary amount of arguments to these methods,
|
42
|
+
but all of them are file names. So we'll go ahead and prefix all
|
43
|
+
of them:
|
44
|
+
|
45
|
+
- `delete`
|
46
|
+
- `unlink`
|
47
|
+
- `safe_unlink`
|
48
|
+
|
49
|
+
Methods that patch nothing and just delegate to File
|
50
|
+
----------------------------------------------------
|
51
|
+
These are mostly methods that are either not `HistoryFile` specific
|
52
|
+
(i.e. `File.join` to join components with the OS dependant path
|
53
|
+
separator) or where one can't dumbly prefix filenames.
|
54
|
+
|
55
|
+
- `absolute_path`
|
56
|
+
- `basename`
|
57
|
+
- `catname`
|
58
|
+
- `chmod`
|
59
|
+
- `chown`
|
60
|
+
- `compare`
|
61
|
+
- `copy`
|
62
|
+
- `directory?`
|
63
|
+
- `dirname`
|
64
|
+
- `expand_path`
|
65
|
+
- `extname`
|
66
|
+
- `fnmatch`
|
67
|
+
- `fnmatch?`
|
68
|
+
- `identical?`
|
69
|
+
- `install`
|
70
|
+
- `join`
|
71
|
+
- `lchown`
|
72
|
+
- `link`
|
73
|
+
- `makedirs`
|
74
|
+
- `move`
|
75
|
+
- `path`
|
76
|
+
- `realdirpath`
|
77
|
+
- `realpath`
|
78
|
+
- `rename`
|
79
|
+
- `split`
|
80
|
+
- `umask`
|
81
|
+
- `utime`
|
82
|
+
|
83
|
+
Methods that add a prefix to the filename
|
84
|
+
-----------------------------------------
|
85
|
+
All methods not mentioned in the previous two sections
|
86
|
+
|
87
|
+
Methods that automatically create a sub directory
|
88
|
+
-------------------------------------------------
|
89
|
+
If you set `HistoryFile.mode = :subdir` and you call one of the
|
90
|
+
following methods, Historyfile will create a sub directory for the given
|
91
|
+
date if it does not exist already
|
92
|
+
|
93
|
+
- `new`
|
94
|
+
- `open`
|
95
|
+
|
96
|
+
Tests
|
97
|
+
-----
|
98
|
+
We use simplecov and it reports 100% coverage.
|
99
|
+
[![Build Status](https://secure.travis-ci.org/moviepilot/history_file.png?branch=master)](https://travis-ci.org/moviepilot/history_file)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/history_file.gemspec
CHANGED
@@ -5,25 +5,27 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "history_file"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jannis Hermanns"]
|
12
|
-
s.date = "2012-11-
|
12
|
+
s.date = "2012-11-21"
|
13
13
|
s.description = "A File like class that supports versioning by date and has a fallback to older files"
|
14
14
|
s.email = "jannis@moviepilot.com"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE.txt",
|
17
|
-
"README.
|
17
|
+
"README.markdown"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
21
|
".rvmrc",
|
22
|
+
".travis.yml",
|
23
|
+
"CHANGELOG.markdown",
|
22
24
|
"Gemfile",
|
23
25
|
"Gemfile.lock",
|
24
26
|
"Guardfile",
|
25
27
|
"LICENSE.txt",
|
26
|
-
"README.
|
28
|
+
"README.markdown",
|
27
29
|
"Rakefile",
|
28
30
|
"VERSION",
|
29
31
|
"history_file.gemspec",
|
@@ -43,6 +45,7 @@ Gem::Specification.new do |s|
|
|
43
45
|
s.specification_version = 3
|
44
46
|
|
45
47
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
48
|
+
s.add_runtime_dependency(%q<redcarpet>, [">= 0"])
|
46
49
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
47
50
|
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
48
51
|
s.add_development_dependency(%q<bundler>, [">= 0"])
|
@@ -55,9 +58,9 @@ Gem::Specification.new do |s|
|
|
55
58
|
s.add_development_dependency(%q<guard-rspec>, [">= 0"])
|
56
59
|
s.add_development_dependency(%q<guard-bundler>, [">= 0"])
|
57
60
|
s.add_development_dependency(%q<guard-yard>, [">= 0"])
|
58
|
-
s.add_development_dependency(%q<guard-spork>, [">= 0"])
|
59
61
|
s.add_development_dependency(%q<rb-fsevent>, [">= 0"])
|
60
62
|
else
|
63
|
+
s.add_dependency(%q<redcarpet>, [">= 0"])
|
61
64
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
62
65
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
63
66
|
s.add_dependency(%q<bundler>, [">= 0"])
|
@@ -70,10 +73,10 @@ Gem::Specification.new do |s|
|
|
70
73
|
s.add_dependency(%q<guard-rspec>, [">= 0"])
|
71
74
|
s.add_dependency(%q<guard-bundler>, [">= 0"])
|
72
75
|
s.add_dependency(%q<guard-yard>, [">= 0"])
|
73
|
-
s.add_dependency(%q<guard-spork>, [">= 0"])
|
74
76
|
s.add_dependency(%q<rb-fsevent>, [">= 0"])
|
75
77
|
end
|
76
78
|
else
|
79
|
+
s.add_dependency(%q<redcarpet>, [">= 0"])
|
77
80
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
78
81
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
79
82
|
s.add_dependency(%q<bundler>, [">= 0"])
|
@@ -86,7 +89,6 @@ Gem::Specification.new do |s|
|
|
86
89
|
s.add_dependency(%q<guard-rspec>, [">= 0"])
|
87
90
|
s.add_dependency(%q<guard-bundler>, [">= 0"])
|
88
91
|
s.add_dependency(%q<guard-yard>, [">= 0"])
|
89
|
-
s.add_dependency(%q<guard-spork>, [">= 0"])
|
90
92
|
s.add_dependency(%q<rb-fsevent>, [">= 0"])
|
91
93
|
end
|
92
94
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module HistoryFile
|
2
|
-
# This class delegates all method calls to the
|
2
|
+
# This class delegates all method calls to the `File` class.
|
3
3
|
# The generic methods that don't revolve around one specific
|
4
|
-
# file,
|
4
|
+
# file, `File.join` for example, are just passed on. These
|
5
5
|
# methods are defined in
|
6
6
|
# {HistoryFile::FileDelegator::EXCLUDED_METHODS}.
|
7
7
|
#
|
@@ -16,7 +16,7 @@ module HistoryFile
|
|
16
16
|
# > puts fd.read("/path/to/my_file.txt")
|
17
17
|
# => hello there
|
18
18
|
#
|
19
|
-
# This will pass on your block to
|
19
|
+
# This will pass on your block to `File.open`, but with a
|
20
20
|
# prefixed the filename. So what's really called is:
|
21
21
|
#
|
22
22
|
# File.open("/path/to/some_prefix-my_file.txt")
|
@@ -65,15 +65,21 @@ module HistoryFile
|
|
65
65
|
:safe_unlink
|
66
66
|
]
|
67
67
|
|
68
|
+
POTENTIALLY_FILE_CREATING_METHODS = [
|
69
|
+
:new,
|
70
|
+
:open
|
71
|
+
]
|
72
|
+
|
68
73
|
# @param prefix [String] The prefix for all methods that revolve around
|
69
74
|
# filenames
|
70
|
-
# @param fallback_glob [
|
71
|
-
# smaller file on Errno::ENOENT, you can supply a
|
72
|
-
# will be used with
|
75
|
+
# @param fallback_glob [Hash] If you want to fall back to an alphabetically
|
76
|
+
# smaller file on Errno::ENOENT, you can supply a :fallback_glob here. It
|
77
|
+
# will be used with `Dir.glob` to find all candidates (so this should match
|
73
78
|
# all prefixes)
|
74
|
-
def initialize(
|
75
|
-
@prefix = prefix
|
76
|
-
@fallback_glob = fallback_glob
|
79
|
+
def initialize(opts)
|
80
|
+
@prefix = opts[:prefix] or raise ArgumentError,":prefix needed"
|
81
|
+
@fallback_glob = opts[:fallback_glob]
|
82
|
+
@subdir = opts[:use_subdirs]
|
77
83
|
end
|
78
84
|
|
79
85
|
# Either
|
@@ -95,7 +101,11 @@ module HistoryFile
|
|
95
101
|
def prefixed_filename(f)
|
96
102
|
dir = File.dirname(f.to_s)
|
97
103
|
file = File.basename(f.to_s)
|
98
|
-
|
104
|
+
if @subdir
|
105
|
+
File.join(dir, @prefix, file)
|
106
|
+
else
|
107
|
+
File.join(dir, "#{@prefix}-#{file}")
|
108
|
+
end
|
99
109
|
end
|
100
110
|
|
101
111
|
private
|
@@ -116,6 +126,7 @@ module HistoryFile
|
|
116
126
|
def delegate_with_patched_filename(method, *args, &block)
|
117
127
|
filename = args.slice!(0,1).first
|
118
128
|
pf = prefixed_filename(filename)
|
129
|
+
create_prefix_subdir(method, pf)
|
119
130
|
begin
|
120
131
|
File.send(method, pf, *args, &block)
|
121
132
|
rescue Errno::ENOENT => e
|
@@ -124,6 +135,16 @@ module HistoryFile
|
|
124
135
|
end
|
125
136
|
end
|
126
137
|
|
138
|
+
# We just assume that #new and #open are used to create files and create
|
139
|
+
# sub directories for prefixes when in prefix mode.
|
140
|
+
def create_prefix_subdir(method, filename)
|
141
|
+
return unless @subdir
|
142
|
+
return unless POTENTIALLY_FILE_CREATING_METHODS.include?(method)
|
143
|
+
dir = File.dirname(filename.to_s)
|
144
|
+
return if Dir.exists?(dir)
|
145
|
+
Dir.mkdir(dir)
|
146
|
+
end
|
147
|
+
|
127
148
|
# Treats all arguments of the methods as files and prepends the
|
128
149
|
# history prefix
|
129
150
|
def delegate_with_patched_filenames(method, *args, &block)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Behaves like a
|
1
|
+
# Behaves like a `File` class and does some convenience stuff
|
2
2
|
# around a {HistoryFile::FileDelegator} instance. It all
|
3
3
|
# revolves about defining a time offset. If however, you want
|
4
4
|
# to access different versions of a file, use it like this:
|
@@ -27,10 +27,19 @@
|
|
27
27
|
#
|
28
28
|
module HistoryFile
|
29
29
|
|
30
|
+
def self.mode=(mode)
|
31
|
+
return @mode = :filename if mode.to_sym == :filename
|
32
|
+
return @mode = :subdir if mode.to_sym == :subdir
|
33
|
+
raise ArgumentError, "Mode must be :filename or :subdir"
|
34
|
+
end
|
35
|
+
|
30
36
|
def self.[](offset)
|
31
37
|
validate_offset(offset)
|
38
|
+
use_subdirs = @mode == :subdir
|
32
39
|
fallback_glob = "[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9][0-9]-"
|
33
|
-
FileDelegator.new(prefix(offset),
|
40
|
+
FileDelegator.new(prefix: prefix(offset),
|
41
|
+
fallback_glob: fallback_glob,
|
42
|
+
use_subdirs: use_subdirs)
|
34
43
|
end
|
35
44
|
|
36
45
|
private
|
@@ -3,41 +3,81 @@ require 'date'
|
|
3
3
|
|
4
4
|
describe HistoryFile::FileDelegator do
|
5
5
|
|
6
|
-
|
6
|
+
context "prefixing the filename" do
|
7
|
+
let(:fd){ HistoryFile::FileDelegator.new(prefix: "some_prefix") }
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
after(:all) do
|
10
|
+
File.unlink("some_prefix-rspec_tmp_test.txt") rescue nil
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
13
|
+
before(:each) do
|
14
|
+
HistoryFile.mode = :filename
|
15
|
+
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
it "raises an exception if a :prefix is missing" do
|
18
|
+
expect{
|
19
|
+
HistoryFile::FileDelegator.new({})
|
20
|
+
}.to raise_error(ArgumentError, ":prefix needed")
|
21
|
+
end
|
22
|
+
|
23
|
+
it "raises an exception if you try to set an invalid mode" do
|
24
|
+
expect{
|
25
|
+
HistoryFile.mode = :made_up
|
26
|
+
}.to raise_error(ArgumentError, "Mode must be :filename or :subdir")
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
it "delegates generic methods to File directly" do
|
31
|
+
File.should_receive(:split).with("/some/path")
|
32
|
+
fd.split("/some/path")
|
33
|
+
end
|
34
|
+
|
35
|
+
it "delegates bulk methods with all parameters prefixed" do
|
36
|
+
offset = Date.parse("1983-04-03")
|
37
|
+
File.should_receive(:unlink).with("./1983.04.03-file1", "./1983.04.03-file2")
|
38
|
+
HistoryFile[offset].unlink("file1", "file2")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "instanciating new File instances works as expected" do
|
42
|
+
f = fd.new("rspec_tmp_test.txt", "w")
|
43
|
+
f.write("works")
|
44
|
+
f.close
|
45
|
+
File.read("some_prefix-rspec_tmp_test.txt").should == "works"
|
46
|
+
end
|
22
47
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
48
|
+
it "writing into a file using a block works as expected" do
|
49
|
+
fd.open("rspec_tmp_test.txt", "w") do |file|
|
50
|
+
file.write("works")
|
51
|
+
end
|
52
|
+
File.read("some_prefix-rspec_tmp_test.txt").should == "works"
|
53
|
+
end
|
28
54
|
end
|
29
55
|
|
30
|
-
|
31
|
-
|
32
|
-
|
56
|
+
context "prefixing with sub directories" do
|
57
|
+
let(:sdfd){ HistoryFile::FileDelegator.new(prefix: "some_prefix", use_subdirs: true) }
|
58
|
+
|
59
|
+
it "creates the right filename with a directory as a prefix" do
|
60
|
+
sdfd.prefixed_filename('test').should == "./some_prefix/test"
|
33
61
|
end
|
34
|
-
|
62
|
+
|
63
|
+
it "attempts to create a directory" do
|
64
|
+
Dir.should_receive(:mkdir).with("./some_prefix")
|
65
|
+
File.should_receive(:open).with("./some_prefix/foo")
|
66
|
+
sdfd.open("foo") do |io|
|
67
|
+
io.write "don't"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
35
71
|
end
|
36
72
|
end
|
37
73
|
|
38
74
|
describe HistoryFile do
|
39
75
|
|
40
76
|
context "writing and reading files" do
|
77
|
+
before(:each) do
|
78
|
+
HistoryFile.mode = :filename
|
79
|
+
end
|
80
|
+
|
41
81
|
it "uses a correct prefix" do
|
42
82
|
offset = Date.parse("1979-12-22")
|
43
83
|
HistoryFile[offset].open("rspec_tmp_test.txt", "w") do |file|
|
@@ -54,33 +94,39 @@ describe HistoryFile do
|
|
54
94
|
end
|
55
95
|
end
|
56
96
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
97
|
+
# We run these tests twice
|
98
|
+
[:subdir, :filename].each do |mode|
|
99
|
+
|
100
|
+
HistoryFile.mode = mode
|
101
|
+
context "falling back to older files in #{mode} mode" do
|
102
|
+
before(:all) do
|
103
|
+
[1,2,3,6,7].each do |i|
|
104
|
+
date = DateTime.now - i
|
105
|
+
HistoryFile[date].open("ht.txt", "w") do |file|
|
106
|
+
file.write "Day #{i} #{mode}"
|
107
|
+
end
|
63
108
|
end
|
64
109
|
end
|
65
|
-
end
|
66
110
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
111
|
+
after(:all) do
|
112
|
+
[1,2,3,6,7].each do |i|
|
113
|
+
date = DateTime.now - i
|
114
|
+
HistoryFile[date].unlink("ht.txt")
|
115
|
+
end
|
116
|
+
Dir.unlink("some_prefix") rescue nil
|
71
117
|
end
|
72
|
-
end
|
73
118
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
119
|
+
it "to yesterday's file" do
|
120
|
+
date = DateTime.now - 4
|
121
|
+
HistoryFile[date].read("ht.txt").should == "Day 6 #{mode}"
|
122
|
+
end
|
78
123
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
124
|
+
it "to an error if nothing older exists" do
|
125
|
+
expect{
|
126
|
+
date = DateTime.now - 8
|
127
|
+
HistoryFile[date].read("ht.txt")
|
128
|
+
}.to raise_error(Errno::ENOENT)
|
129
|
+
end
|
84
130
|
end
|
85
131
|
end
|
86
132
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,56 +1,46 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require 'spork'
|
3
2
|
require 'simplecov'
|
4
3
|
SimpleCov.start
|
5
4
|
require 'bundler'
|
6
5
|
Bundler.require
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
8
|
+
ENV["RAILS_ENV"] ||= 'test'
|
9
|
+
# require File.expand_path("../../config/environment", __FILE__)
|
10
|
+
#require 'capybara/poltergeist'
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
#require 'capybara/poltergeist'
|
12
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
13
|
+
# in spec/support/ and its subdirectories.
|
14
|
+
Dir[File.expand_path("../../spec/support/**/*.rb", __FILE__)].each {|f| require f}
|
17
15
|
|
18
|
-
|
19
|
-
#
|
20
|
-
|
16
|
+
RSpec.configure do |config|
|
17
|
+
# == Mock Framework
|
18
|
+
#
|
19
|
+
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
20
|
+
#
|
21
|
+
# config.mock_with :mocha
|
22
|
+
# config.mock_with :flexmock
|
23
|
+
# config.mock_with :rr
|
24
|
+
config.mock_with :rspec
|
21
25
|
|
22
|
-
|
23
|
-
# == Mock Framework
|
24
|
-
#
|
25
|
-
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
26
|
-
#
|
27
|
-
# config.mock_with :mocha
|
28
|
-
# config.mock_with :flexmock
|
29
|
-
# config.mock_with :rr
|
30
|
-
config.mock_with :rspec
|
26
|
+
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
31
27
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
module TestResponseExtensions
|
37
|
-
def json_body
|
38
|
-
JSON.parse(self.body)
|
39
|
-
end
|
28
|
+
end
|
40
29
|
|
41
|
-
|
42
|
-
|
43
|
-
|
30
|
+
module TestResponseExtensions
|
31
|
+
def json_body
|
32
|
+
JSON.parse(self.body)
|
44
33
|
end
|
45
34
|
|
46
|
-
def
|
47
|
-
|
35
|
+
def unauthorized?
|
36
|
+
code.to_i == 401
|
48
37
|
end
|
38
|
+
end
|
49
39
|
|
40
|
+
def expect_id_and_return(id, ret_val)
|
41
|
+
lambda { |id| id.to_s.should == id.to_s; ret_val }
|
50
42
|
end
|
51
43
|
|
44
|
+
|
52
45
|
require File.expand_path("../../lib/history_file/", __FILE__)
|
53
46
|
|
54
|
-
# Spork.each_run do
|
55
|
-
# FactoryGirl.reload
|
56
|
-
# end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: history_file
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: redcarpet
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: shoulda
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -203,22 +219,6 @@ dependencies:
|
|
203
219
|
- - ! '>='
|
204
220
|
- !ruby/object:Gem::Version
|
205
221
|
version: '0'
|
206
|
-
- !ruby/object:Gem::Dependency
|
207
|
-
name: guard-spork
|
208
|
-
requirement: !ruby/object:Gem::Requirement
|
209
|
-
none: false
|
210
|
-
requirements:
|
211
|
-
- - ! '>='
|
212
|
-
- !ruby/object:Gem::Version
|
213
|
-
version: '0'
|
214
|
-
type: :development
|
215
|
-
prerelease: false
|
216
|
-
version_requirements: !ruby/object:Gem::Requirement
|
217
|
-
none: false
|
218
|
-
requirements:
|
219
|
-
- - ! '>='
|
220
|
-
- !ruby/object:Gem::Version
|
221
|
-
version: '0'
|
222
222
|
- !ruby/object:Gem::Dependency
|
223
223
|
name: rb-fsevent
|
224
224
|
requirement: !ruby/object:Gem::Requirement
|
@@ -242,15 +242,17 @@ executables: []
|
|
242
242
|
extensions: []
|
243
243
|
extra_rdoc_files:
|
244
244
|
- LICENSE.txt
|
245
|
-
- README.
|
245
|
+
- README.markdown
|
246
246
|
files:
|
247
247
|
- .document
|
248
248
|
- .rvmrc
|
249
|
+
- .travis.yml
|
250
|
+
- CHANGELOG.markdown
|
249
251
|
- Gemfile
|
250
252
|
- Gemfile.lock
|
251
253
|
- Guardfile
|
252
254
|
- LICENSE.txt
|
253
|
-
- README.
|
255
|
+
- README.markdown
|
254
256
|
- Rakefile
|
255
257
|
- VERSION
|
256
258
|
- history_file.gemspec
|
@@ -274,7 +276,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
274
276
|
version: '0'
|
275
277
|
segments:
|
276
278
|
- 0
|
277
|
-
hash:
|
279
|
+
hash: -4078239623642015702
|
278
280
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
279
281
|
none: false
|
280
282
|
requirements:
|
data/README.rdoc
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
HistoryFile
|
2
|
-
===========
|
3
|
-
|
4
|
-
Behaves like a {File} class and does some convenience stuff
|
5
|
-
around a {HistoryFile::FileDelegator} instance. It all
|
6
|
-
revolves about defining a time offset. If however, you want
|
7
|
-
to access different versions of a file, use it like this:
|
8
|
-
|
9
|
-
```ruby
|
10
|
-
> f = HistoryFile[1.day.ago].new("/tmp/foo.txt", "w")
|
11
|
-
=> #<File:/tmp/2012.11.02-foo.txt>
|
12
|
-
```
|
13
|
-
|
14
|
-
The returned {HistoryFile::FileDelegator} object supports all
|
15
|
-
methods that File has, but adds a date prefix to those methods
|
16
|
-
that revolve around a single file (reading, writing, etc.)
|
17
|
-
|
18
|
-
If a file for a given date is not available, {HistoryFile} falls
|
19
|
-
back to the freshest file that is older than the given date.
|
20
|
-
|
21
|
-
```ruby
|
22
|
-
> f = HistoryFile[3.days.ago].new("test.txt", "w")
|
23
|
-
=> #<File:./2012.11.12-test.txt>
|
24
|
-
> f.write("I am old")
|
25
|
-
=> 8
|
26
|
-
> f.close
|
27
|
-
=> nil
|
28
|
-
> HistoryFile[Date.today].read("test.txt")
|
29
|
-
=> "I am old"
|
30
|
-
> HistoryFile[10.days.ago].read("test.txt")
|
31
|
-
Errno::ENOENT: No such file or directory - ./2012.11.05-test.txt
|
32
|
-
```
|