file_glob 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,35 @@
1
+ FileGlob
2
+ ========
3
+
4
+ Quacks like a Regexp, tastes like Dir.glob.
5
+
6
+ Use this with any library that expects a regular expression. Use FileGlob in place of a Regexp when [shell pattern matching ](http://www.ruby-doc.org/core-1.9.3/File.html#method-c-fnmatch) makes more sense.
7
+
8
+ Usage
9
+ -----
10
+
11
+ Filter a set of file paths:
12
+
13
+ glob = FileGlob.new("test/**/*_test.rb")
14
+ paths.select{|path| path =~ glob }
15
+
16
+ Perform different actions for different file types:
17
+
18
+ image = FileGlob.new("*.{png,jpg,gif}")
19
+ text = FileGlob.new("*.txt")
20
+
21
+ case path
22
+ when image then process_image(path)
23
+ when text then process_text(path)
24
+ end
25
+
26
+ Installation
27
+ ------------
28
+
29
+ Install with rubygems:
30
+
31
+ gem install file_glob
32
+
33
+ -----
34
+
35
+ Adam Sanderson, http://www.monkeyandcrow.com
@@ -0,0 +1,9 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.pattern = 'test/**/*_test.rb'
5
+ t.verbose = false
6
+ end
7
+
8
+ desc "Run tests"
9
+ task :default => :test
@@ -0,0 +1,71 @@
1
+ class FileGlob
2
+ attr_reader :pattern
3
+
4
+ def initialize(pattern)
5
+ @pattern = pattern
6
+ end
7
+
8
+ def =~ path
9
+ 0 if File.fnmatch?(pattern, path)
10
+ end
11
+
12
+ def === path
13
+ File.fnmatch?(pattern, path)
14
+ end
15
+
16
+ def match(path)
17
+ GlobMatchData.new(path) if self =~ path
18
+ end
19
+
20
+ def to_s
21
+ pattern
22
+ end
23
+
24
+ def inspect
25
+ "<#FileGlob #{pattern}>"
26
+ end
27
+
28
+ private
29
+
30
+ # Interface that quacks like Regexp's MatchData.
31
+ # It should cover most common cases.
32
+ class GlobMatchData
33
+ attr_reader :string
34
+
35
+ def intialize(string)
36
+ @string = string
37
+ end
38
+
39
+ def [] i
40
+ check_index!(i)
41
+ string
42
+ end
43
+
44
+ def begin(i)
45
+ check_index!(i)
46
+ 0
47
+ end
48
+
49
+ def end
50
+ check_index!(i)
51
+ string.length
52
+ end
53
+
54
+ def size
55
+ 1
56
+ end
57
+
58
+ alias_method :length, :size
59
+
60
+ def names
61
+ []
62
+ end
63
+
64
+ private
65
+
66
+ def check_index!(i)
67
+ throw IndexError.new("FileGlob only matches once") if i > 0
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,18 @@
1
+ require "minitest/autorun"
2
+ require_relative "./matcher_mixin"
3
+ require_relative "../lib/file_glob"
4
+
5
+ # Ensure our interface matches the "matcher" duck type of Regexp.
6
+ #
7
+ class FileGlobInterfaceTest < MiniTest::Unit::TestCase
8
+ include MatcherMixin
9
+
10
+ def setup
11
+ @matcher = FileGlob.new("*.rb")
12
+ end
13
+
14
+ def matching_example
15
+ "file.rb"
16
+ end
17
+
18
+ end
@@ -0,0 +1,38 @@
1
+ require "minitest/autorun"
2
+ require_relative "../lib/file_glob"
3
+
4
+ class FileGlobTest < MiniTest::Unit::TestCase
5
+ MATCH = "file.rb"
6
+ NO_MATCH = "file.yml"
7
+
8
+ def setup
9
+ @glob = FileGlob.new '*.rb'
10
+ end
11
+
12
+ def test_matches_with_squiggle_operator
13
+ assert @glob =~ MATCH
14
+ end
15
+
16
+ def test_only_matches_when_pattern_matches
17
+ assert !(@glob =~ NO_MATCH)
18
+ end
19
+
20
+ def test_can_be_used_on_righthand_side
21
+ assert MATCH =~ @glob
22
+ end
23
+
24
+ def test_matches_with_match
25
+ assert @glob.match(MATCH)
26
+ end
27
+
28
+ def test_only_matches_with_match_when_pattern_matches
29
+ assert !@glob.match(NO_MATCH)
30
+ end
31
+
32
+ def test_can_be_used_in_a_case_statement
33
+ case MATCH
34
+ when @glob then assert(true)
35
+ else flunk "Should define ==="
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,36 @@
1
+ # These tests minimaly verify the interface of a "matcher" object.
2
+ # They ensure that it behaves like a regexp for matching purposes.
3
+ #
4
+ # For tests around behavior, see file_glob_test.rb
5
+ #
6
+ module MatcherMixin
7
+
8
+ def setup
9
+ raise NotImplementedError.new "Setup must define @matcher"
10
+ end
11
+
12
+ def matching_example
13
+ raise NotImplementedError.new "Provide a string that matches @matcher"
14
+ end
15
+
16
+ def test_responds_to_matching_methods
17
+ assert @matcher.respond_to? :"=~"
18
+ assert @matcher.respond_to? :match
19
+ assert @matcher.respond_to? :"==="
20
+ end
21
+
22
+ def test_squiggle_operator_returns_an_index
23
+ i = @matcher =~ matching_example
24
+
25
+ assert_kind_of Fixnum, i
26
+ end
27
+
28
+ def test_match_returns_a_match_data_like_object
29
+ data = @matcher.match(matching_example)
30
+
31
+ assert data.respond_to? :[]
32
+ assert data.respond_to? :string
33
+ assert data.respond_to? :length
34
+ end
35
+
36
+ end
@@ -0,0 +1,19 @@
1
+ require "minitest/autorun"
2
+ require_relative "./matcher_mixin"
3
+
4
+ # Verify that Regexp quacks like a "matcher".
5
+ #
6
+ # This might seem silly, but it ensures that the duck type we are attempting to
7
+ # match actually matches our expectations.
8
+ #
9
+ class RegexpInterfaceTest < MiniTest::Unit::TestCase
10
+ include MatcherMixin
11
+
12
+ def setup
13
+ @matcher = /.+\.rb/
14
+ end
15
+
16
+ def matching_example
17
+ "file.rb"
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: file_glob
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Adam Sanderson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-15 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: Use FileGlob in place of a Regexp when shell pattern matching makes more
15
+ sense.
16
+ email:
17
+ - netghost@gmail.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - lib/file_glob.rb
23
+ - test/file_glob_interface_test.rb
24
+ - test/file_glob_test.rb
25
+ - test/matcher_mixin.rb
26
+ - test/regexp_interface_test.rb
27
+ - README.markdown
28
+ - Rakefile
29
+ homepage: https://github.com/adamsanderson/file_glob
30
+ licenses: []
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubyforge_project:
49
+ rubygems_version: 1.8.11
50
+ signing_key:
51
+ specification_version: 3
52
+ summary: Quacks like a Regexp, tastes like your shell's a file glob.
53
+ test_files: []