file-visitor 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,94 @@
1
+
2
+ require "time"
3
+
4
+ class File
5
+ class Visitor
6
+ end
7
+ end
8
+
9
+ module File::Visitor::TimeUtils
10
+
11
+ UNIT_SEC = {
12
+ :sec => 1,
13
+ :min => 60,
14
+ :hour => 60 * 60,
15
+ :day => 60 * 60 * 24,
16
+ :month => 60 * 60 * 24 * 31,
17
+ :year => 60 * 60 * 24 * 365
18
+ }
19
+ # aliases
20
+ UNIT_SEC.merge!({
21
+ :secs => UNIT_SEC[:sec],
22
+ :second => UNIT_SEC[:sec],
23
+ :seconds => UNIT_SEC[:sec],
24
+ :mins => UNIT_SEC[:min],
25
+ :minute => UNIT_SEC[:min],
26
+ :minutes => UNIT_SEC[:min],
27
+ :hours => UNIT_SEC[:hour],
28
+ :days => UNIT_SEC[:day],
29
+ :months => UNIT_SEC[:month],
30
+ :years => UNIT_SEC[:year],
31
+ })
32
+
33
+ COMPARATOR = [
34
+ :equals_to,
35
+ :==,
36
+ :is_greater_than,
37
+ :is_younger_than,
38
+ :>,
39
+ :is_greater_than=,
40
+ :is_younger_than=,
41
+ :>=,
42
+ :is_less_than,
43
+ :is_older_than,
44
+ :<,
45
+ :is_less_than=,
46
+ :is_older_than=,
47
+ :<=,
48
+ ]
49
+
50
+ def unitexp2sec(count, unit_name)
51
+ if (!count.is_a?(Fixnum) || count < 0)
52
+ raise ArgumentError,
53
+ "time count must be positive fixnum: #{count}"
54
+ end
55
+ if !UNIT_SEC[unit_name]
56
+ raise ArgumentError, "unknown time unit: #{unit_name}"
57
+ end
58
+ count * UNIT_SEC[unit_name]
59
+ end
60
+
61
+ def compare_time(time1, comparator, time2)
62
+ time1 = to_time(time1)
63
+ time2 = to_time(time2)
64
+
65
+ unless COMPARATOR.include?(comparator)
66
+ raise ArgumentError,
67
+ "invalid comparator: #{comparator.to_s}"
68
+ end
69
+
70
+ case comparator
71
+ when :equals_to, :==
72
+ return time1 == time2
73
+ when :is_greater_than, :is_younger_than, :>
74
+ return time1 > time2
75
+ when :is_greater_than=, :is_younger_than=, :>=
76
+ return time1 >= time2
77
+ when :is_less_than, :is_older_than, :<
78
+ return time1 < time2
79
+ when :is_less_than=, :is_older_than=, :<=
80
+ return time1 <= time2
81
+ else
82
+ raise RuntimeError,
83
+ "invalid comparator: #{comparator.to_s}"
84
+ end
85
+ end
86
+
87
+ def to_time(time)
88
+ return time if time.is_a?(Time)
89
+ return Time.parse(time) if time.is_a?(String)
90
+ raise ArgumentError, "invalid time: #{time.inspect}"
91
+ end
92
+
93
+ end
94
+
@@ -0,0 +1,62 @@
1
+
2
+ require 'file/visitor'
3
+ require 'spec_utils'
4
+
5
+ describe 'use case test' do
6
+ include SpecUtils
7
+
8
+ before(:each) do
9
+ setup_test_dir
10
+ end
11
+
12
+ context "collect log file" do
13
+
14
+ before(:each) do
15
+ @path1 = create_file(['log', '2013-01'], '2013-01-01.log', 'a')
16
+ @path2 = create_file(['log', '2013-02'], '2013-02-02.log', 'b')
17
+ @path3 = create_file(['log', '2013-02'], '2013-02-03.log', 'c')
18
+ @path4 = create_file(['log', '2013-01'], '2013-01-03.txt', 'd')
19
+ end
20
+
21
+ it 'removes 2013-02 logs' do
22
+ visitor = File::Visitor.new
23
+ visitor.add_filter(:ext, :log)
24
+ visitor.add_filter { |path| path =~ /2013\-02/ }
25
+
26
+ FileUtils.stub!(:rm).with(@path2)
27
+ FileUtils.stub!(:rm).with(@path3)
28
+
29
+ visitor.visit(test_dir) do |path|
30
+ FileUtils.rm(path)
31
+ end
32
+ end
33
+
34
+ it 'removes old logs' do
35
+ time1 = Time.parse("2013-01-01 00:00:00")
36
+ time2 = Time.parse("2013-01-02 00:00:00")
37
+ time3 = Time.parse("2013-01-03 00:00:00")
38
+ time4 = Time.parse("2013-01-04 00:00:00")
39
+
40
+ File.utime(time1, time1, @path1)
41
+ File.utime(time2, time2, @path2)
42
+ File.utime(time3, time3, @path3)
43
+ File.utime(time4, time4, @path4)
44
+
45
+ Time.stub!(:now).and_return(Time.parse("2013-01-04 22:00:00"))
46
+
47
+ visitor = File::Visitor.new
48
+ visitor.add_filter(:mtime, :passed, 1, :day)
49
+
50
+ visitor.file_list(test_dir).should == [@path1, @path2, @path3]
51
+
52
+ visitor.add_filter(:mtime, :passed, 2, :days)
53
+ visitor.file_list(test_dir).should == [@path1, @path2]
54
+
55
+ visitor.add_filter(:mtime, :passed, 3, :days)
56
+ visitor.file_list(test_dir).should == [@path1]
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+
@@ -0,0 +1,23 @@
1
+
2
+ require 'file/visitor/filter/ext'
3
+
4
+ describe File::Visitor::Filter::Ext do
5
+
6
+ it 'can be created with String/Symbol' do
7
+ filter = File::Visitor::Filter::Ext.new(:txt)
8
+ filter = File::Visitor::Filter::Ext.new("txt")
9
+ end
10
+
11
+ it 'can match filename extention' do
12
+ filter = File::Visitor::Filter::Ext.new(:txt)
13
+ filter.match?("/path/to/file.txt").should be_true
14
+ filter.match?("/path/to/file.dat").should be_false
15
+ end
16
+
17
+ it 'can be stringified' do
18
+ filter = File::Visitor::Filter::Ext.new(:jpg)
19
+ filter.to_s.should == "File::Visitor::Filter::Ext[.jpg]"
20
+ end
21
+
22
+ end
23
+
@@ -0,0 +1,116 @@
1
+
2
+ require 'file/visitor/filter/mtime'
3
+ require 'spec_helper'
4
+ require 'fileutils'
5
+ require 'time'
6
+
7
+ describe File::Visitor::Filter::Mtime do
8
+
9
+ before(:each) do
10
+ @ns = File::Visitor::Filter::Mtime
11
+ cleanup_spec_data_dir
12
+ end
13
+
14
+ after(:each) do
15
+ cleanup_spec_data_dir
16
+ end
17
+
18
+ it "can be created with comparator/target_time" do
19
+ filter = @ns.new(:equals_to, Time.now)
20
+ filter.should be_a @ns
21
+ end
22
+
23
+ context ":passed" do
24
+
25
+ it ":passed initialize" do
26
+ Time.stub!(:now).and_return(
27
+ Time.parse("2013-01-05 05:00"))
28
+
29
+ filter1 = @ns.new(:passed, 2, :days)
30
+
31
+ file1 = spec_data_create("file1")
32
+ file2 = spec_data_create("file2")
33
+ file3 = spec_data_create("file3")
34
+ file4 = spec_data_create("file4")
35
+
36
+ time1 = Time.parse("2013-01-03 04:59")
37
+ time2 = Time.parse("2013-01-03 05:00")
38
+ time3 = Time.parse("2013-01-03 05:01")
39
+ time4 = Time.parse("2013-01-04 05:00")
40
+
41
+ File.utime(time1, time1, file1)
42
+ File.utime(time2, time2, file2)
43
+ File.utime(time3, time3, file3)
44
+ File.utime(time4, time4, file4)
45
+
46
+ filter1.match?(file1).should be_true
47
+ filter1.match?(file2).should be_false
48
+ filter1.match?(file3).should be_false
49
+ filter1.match?(file4).should be_false
50
+
51
+ filter2 = @ns.new(:passed=, 2, :days)
52
+ filter2.match?(file1).should be_true
53
+ filter2.match?(file2).should be_true
54
+ filter2.match?(file3).should be_false
55
+ filter2.match?(file4).should be_false
56
+ end
57
+
58
+ end
59
+
60
+ it "raises error with invalid comparator" do
61
+ expect { @ns.new(:invalid, Time.now) }.to \
62
+ raise_error(ArgumentError, %r/comparator must/)
63
+ end
64
+
65
+ it "raises error with non-Time instance" do
66
+ expect { @ns.new(:equals_to, :now) }.to \
67
+ raise_error(ArgumentError, %r/time must be/)
68
+ end
69
+
70
+ context "match?" do
71
+
72
+ before(:each) do
73
+ @file1 = spec_data_create("file1")
74
+ @file2 = spec_data_create("file2")
75
+ @file3 = spec_data_create("file3")
76
+ @file4 = spec_data_create("file4")
77
+
78
+ @time1 = Time.parse("2013-01-05 00:00")
79
+ @time2 = Time.parse("2013-01-06 00:00")
80
+ @time3 = Time.parse("2013-01-07 00:00")
81
+ @time4 = Time.parse("2013-01-08 00:00")
82
+
83
+ File.utime(@time1, @time1, @file1)
84
+ File.utime(@time2, @time2, @file2)
85
+ File.utime(@time3, @time3, @file3)
86
+ File.utime(@time4, @time4, @file4)
87
+ end
88
+
89
+ it "supports eq filter" do
90
+ filter = @ns.new(:equals_to, @time2)
91
+ filter.match?(@file1).should be_false
92
+ filter.match?(@file2).should be_true
93
+ filter.match?(@file3).should be_false
94
+ filter.match?(@file4).should be_false
95
+ end
96
+
97
+ it "supports lt filter" do
98
+ filter = @ns.new(:is_less_than, @time2)
99
+ filter.match?(@file1).should be_true
100
+ filter.match?(@file2).should be_false
101
+ filter.match?(@file3).should be_false
102
+ filter.match?(@file4).should be_false
103
+ end
104
+
105
+ it "supports gt filter" do
106
+ filter = @ns.new(:is_greater_than, @time2)
107
+ filter.match?(@file1).should be_false
108
+ filter.match?(@file2).should be_false
109
+ filter.match?(@file3).should be_true
110
+ filter.match?(@file4).should be_true
111
+ end
112
+
113
+ end
114
+
115
+ end
116
+
@@ -0,0 +1,40 @@
1
+
2
+ require 'file/visitor/filter/name'
3
+
4
+ describe File::Visitor::Filter::Name do
5
+
6
+ it 'can be created with new()' do
7
+ filter = File::Visitor::Filter::Name.new('hoge')
8
+ end
9
+
10
+ it 'can match filename string' do
11
+ filter = File::Visitor::Filter::Name.new('file')
12
+
13
+ filter.match?("/path/to/file").should be_true
14
+ filter.match?("file").should be_true
15
+
16
+ filter.match?("file.txt").should be_false
17
+ filter.match?(".file").should be_false
18
+ end
19
+
20
+ it 'can match filename regexp' do
21
+ filter = File::Visitor::Filter::Name.new(/file\.\w+/)
22
+
23
+ filter.match?("/path/to/file.txt").should be_true
24
+ filter.match?("/path/to/xxx_file.txt").should be_true
25
+ filter.match?("file.jpg").should be_true
26
+
27
+ filter.match?("/path/to/file").should be_false
28
+ end
29
+
30
+ it 'can be stringified' do
31
+ str1 = File::Visitor::Filter::Name.new("strfilter").to_s
32
+ str2 = File::Visitor::Filter::Name.new(/filename\.\w+/).to_s
33
+
34
+ str1.should be_a String
35
+ str2.should be_a String
36
+
37
+ str1.should_not == str2
38
+ end
39
+
40
+ end
@@ -0,0 +1,36 @@
1
+
2
+ require 'file/visitor/filter/proc'
3
+
4
+ describe File::Visitor::Filter::Proc do
5
+
6
+ it 'can be created with new()' do
7
+ filter = File::Visitor::Filter::Proc.new(proc { |path| true })
8
+ end
9
+
10
+ it 'raises error when non-proc instance given' do
11
+ expect {
12
+ filter = File::Visitor::Filter::Proc.new(true)
13
+ }.to raise_error(ArgumentError, /Proc instance required/)
14
+ end
15
+
16
+ it 'can match path with custom proc' do
17
+ filter = File::Visitor::Filter::Proc.new(proc { |path|
18
+ path =~ /log/
19
+ })
20
+ filter.match?("/tmp/hoge/fuga.log").should be_true
21
+ filter.match?("/tmp/log/fuga.txt").should be_true
22
+ filter.match?("/tmp/hoge/fuga").should be_false
23
+ end
24
+
25
+ it 'can be stringified' do
26
+ filter1 = File::Visitor::Filter::Proc.new(proc { true })
27
+ filter2 = File::Visitor::Filter::Proc.new(proc { false })
28
+
29
+ filter1.to_s.should be_a String
30
+ filter2.to_s.should be_a String
31
+
32
+ filter1.to_s.should_not == filter2.to_s
33
+ end
34
+
35
+ end
36
+
@@ -0,0 +1,26 @@
1
+
2
+ require 'file/visitor/filter_dispatcher'
3
+
4
+ describe File::Visitor::FilterDispatcher do
5
+
6
+ it "dispatches filter classname" do
7
+ File::Visitor::FilterDispatcher.dispatch(:name)\
8
+ .should == File::Visitor::Filter::Name
9
+ File::Visitor::FilterDispatcher.dispatch(:filename)\
10
+ .should == File::Visitor::Filter::Name
11
+
12
+ File::Visitor::FilterDispatcher.dispatch(:ext)\
13
+ .should == File::Visitor::Filter::Ext
14
+ File::Visitor::FilterDispatcher.dispatch(:extension)\
15
+ .should == File::Visitor::Filter::Ext
16
+ File::Visitor::FilterDispatcher.dispatch(:filetype)\
17
+ .should == File::Visitor::Filter::Ext
18
+
19
+ File::Visitor::FilterDispatcher.dispatch(:mtime)\
20
+ .should == File::Visitor::Filter::Mtime
21
+ File::Visitor::FilterDispatcher.dispatch(:modified_time)\
22
+ .should == File::Visitor::Filter::Mtime
23
+ end
24
+
25
+ end
26
+
@@ -0,0 +1,12 @@
1
+
2
+ require 'file/visitor/filter'
3
+
4
+ describe File::Visitor::Filter do
5
+
6
+ it "create filter namespace" do
7
+ File::Visitor::Filter.should_not be_nil
8
+
9
+ end
10
+
11
+ end
12
+
@@ -0,0 +1,156 @@
1
+
2
+ require 'file/visitor/time_utils'
3
+
4
+ describe File::Visitor::TimeUtils do
5
+ include File::Visitor::TimeUtils
6
+
7
+ describe 'unitexp2sec' do
8
+
9
+ it "returns seconds with unit string of time" do
10
+ unitexp2sec(1, :sec).should == 1
11
+ unitexp2sec(2, :sec).should == 2
12
+ unitexp2sec(3, :sec).should == 3
13
+
14
+ unitexp2sec(1, :min).should == 60
15
+ unitexp2sec(2, :min).should == 120
16
+ unitexp2sec(3, :min).should == 180
17
+
18
+ unitexp2sec(1, :hour).should == 60 * 60 * 1
19
+ unitexp2sec(2, :hour).should == 60 * 60 * 2
20
+ unitexp2sec(3, :hour).should == 60 * 60 * 3
21
+ end
22
+
23
+ it "returns seconds with unit string aliases" do
24
+ unitexp2sec(1, :second).should == 1
25
+ unitexp2sec(2, :seconds).should == 2
26
+ unitexp2sec(3, :secs).should == 3
27
+
28
+ unitexp2sec(1, :mins).should == 60
29
+ unitexp2sec(2, :minute).should == 120
30
+ unitexp2sec(3, :minutes).should == 180
31
+
32
+ unitexp2sec(1, :hours).should == 60 * 60 * 1
33
+ unitexp2sec(2, :days).should == 60 * 60 * 24 * 2
34
+ unitexp2sec(3, :months).should == 60 * 60 * 24 * 31 * 3
35
+ end
36
+
37
+ it "raises error with invalid count" do
38
+ expect { unitexp2sec(nil, :day) }.to \
39
+ raise_error(ArgumentError, %r/time count must be/)
40
+ expect { unitexp2sec(-1, :day) }.to \
41
+ raise_error(ArgumentError, %r/time count must be/)
42
+ end
43
+
44
+ it "raises error with invalid unit name" do
45
+ expect { unitexp2sec(1 , :nichi) }.to \
46
+ raise_error(ArgumentError, %r/unknown time unit/)
47
+ end
48
+
49
+ end
50
+
51
+ describe 'compare_time' do
52
+
53
+ it "supports equals_to" do
54
+ compare_time(
55
+ '2011-12-01 00:00:04',
56
+ :equals_to,
57
+ '2011-12-01 00:00:05'
58
+ ).should be_false
59
+
60
+ compare_time(
61
+ '2011-12-01 00:00:05',
62
+ :equals_to,
63
+ '2011-12-01 00:00:05'
64
+ ).should be_true
65
+
66
+ compare_time(
67
+ '2011-12-01 00:00:05',
68
+ :equals_to,
69
+ '2011-12-01 00:00:06'
70
+ ).should be_false
71
+ end
72
+
73
+ it "supports is_greater_than" do
74
+ compare_time(
75
+ '2011-12-01 00:00:04',
76
+ :is_greater_than,
77
+ '2011-12-01 00:00:05'
78
+ ).should be_false
79
+
80
+ compare_time(
81
+ '2011-12-01 00:00:05',
82
+ :is_greater_than,
83
+ '2011-12-01 00:00:05'
84
+ ).should be_false
85
+
86
+ compare_time(
87
+ '2011-12-01 00:00:06',
88
+ :is_greater_than,
89
+ '2011-12-01 00:00:05'
90
+ ).should be_true
91
+ end
92
+
93
+ it "supports is_greater_than=" do
94
+ compare_time(
95
+ '2011-12-01 00:00:04',
96
+ :is_greater_than=,
97
+ '2011-12-01 00:00:05'
98
+ ).should be_false
99
+
100
+ compare_time(
101
+ '2011-12-01 00:00:05',
102
+ :is_greater_than=,
103
+ '2011-12-01 00:00:05'
104
+ ).should be_true
105
+
106
+ compare_time(
107
+ '2011-12-01 00:00:06',
108
+ :is_greater_than=,
109
+ '2011-12-01 00:00:05'
110
+ ).should be_true
111
+ end
112
+
113
+ it "supports is_less_than" do
114
+ compare_time(
115
+ '2011-12-01 00:00:04',
116
+ :is_less_than,
117
+ '2011-12-01 00:00:05'
118
+ ).should be_true
119
+
120
+ compare_time(
121
+ '2011-12-01 00:00:05',
122
+ :is_less_than,
123
+ '2011-12-01 00:00:05'
124
+ ).should be_false
125
+
126
+ compare_time(
127
+ '2011-12-01 00:00:06',
128
+ :is_less_than,
129
+ '2011-12-01 00:00:05'
130
+ ).should be_false
131
+ end
132
+
133
+ it "supports is_less_than=" do
134
+ compare_time(
135
+ '2011-12-01 00:00:04',
136
+ :is_less_than=,
137
+ '2011-12-01 00:00:05'
138
+ ).should be_true
139
+
140
+ compare_time(
141
+ '2011-12-01 00:00:05',
142
+ :is_less_than=,
143
+ '2011-12-01 00:00:05'
144
+ ).should be_true
145
+
146
+ compare_time(
147
+ '2011-12-01 00:00:06',
148
+ :is_less_than=,
149
+ '2011-12-01 00:00:05'
150
+ ).should be_false
151
+ end
152
+
153
+ end
154
+
155
+ end
156
+