pattern-match 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,60 @@
1
+ require 'pattern-match/core'
2
+
3
+ class Class
4
+ include PatternMatch::Deconstructable
5
+
6
+ def deconstruct(val)
7
+ raise NotImplementedError, "need to define `#{__method__}'"
8
+ end
9
+
10
+ private
11
+
12
+ def accept_self_instance_only(val)
13
+ raise PatternMatch::PatternNotMatch unless val.kind_of?(self)
14
+ end
15
+ end
16
+
17
+ class << Array
18
+ def deconstruct(val)
19
+ accept_self_instance_only(val)
20
+ val
21
+ end
22
+ end
23
+
24
+ class << Struct
25
+ def deconstruct(val)
26
+ accept_self_instance_only(val)
27
+ val.values
28
+ end
29
+ end
30
+
31
+ class << Complex
32
+ def deconstruct(val)
33
+ accept_self_instance_only(val)
34
+ val.rect
35
+ end
36
+ end
37
+
38
+ class << Rational
39
+ def deconstruct(val)
40
+ accept_self_instance_only(val)
41
+ [val.numerator, val.denominator]
42
+ end
43
+ end
44
+
45
+ class << MatchData
46
+ def deconstruct(val)
47
+ accept_self_instance_only(val)
48
+ val.captures.empty? ? [val[0]] : val.captures
49
+ end
50
+ end
51
+
52
+ class Regexp
53
+ include PatternMatch::Deconstructable
54
+
55
+ def deconstruct(val)
56
+ m = Regexp.new("\\A#{source}\\z", options).match(val.to_s)
57
+ raise PatternMatch::PatternNotMatch unless m
58
+ m.captures.empty? ? [m[0]] : m.captures
59
+ end
60
+ end
@@ -0,0 +1,46 @@
1
+ require 'pattern-match/core'
2
+
3
+ module PatternMatch
4
+ module Deconstructable
5
+ remove_method :call
6
+ def call(*subpatterns)
7
+ if Object == self
8
+ PatternKeywordArgStyleDeconstructor.new(Object, :respond_to?, :__send__, *subpatterns)
9
+ else
10
+ pattern_matcher(*subpatterns)
11
+ end
12
+ end
13
+ end
14
+
15
+ module AttributeMatcher
16
+ def self.included(klass)
17
+ class << klass
18
+ def pattern_matcher(*subpatterns)
19
+ PatternKeywordArgStyleDeconstructor.new(self, :respond_to?, :__send__, *subpatterns)
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ module KeyMatcher
26
+ def self.included(klass)
27
+ class << klass
28
+ def pattern_matcher(*subpatterns)
29
+ PatternKeywordArgStyleDeconstructor.new(self, :has_key?, :[], *subpatterns)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ class Hash
37
+ include PatternMatch::KeyMatcher
38
+ end
39
+
40
+ class Object
41
+ def assert_pattern(pattern)
42
+ match(self) do
43
+ Kernel.eval("with(#{pattern}) { self }", Kernel.binding)
44
+ end
45
+ end
46
+ end
@@ -1,3 +1,3 @@
1
1
  module PatternMatch
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1"
3
3
  end
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f) }
18
18
  s.require_paths = ['lib']
19
19
  s.add_development_dependency 'rake'
20
+ s.add_development_dependency 'simplecov'
20
21
  s.extra_rdoc_files = ['README.rdoc']
21
22
  s.rdoc_options = ['--main', 'README.rdoc']
22
23
  end
@@ -0,0 +1,9 @@
1
+ begin
2
+ if ENV['COVERAGE']
3
+ require 'simplecov'
4
+ SimpleCov.start do
5
+ add_filter '/test/'
6
+ end
7
+ end
8
+ rescue LoadError
9
+ end
@@ -0,0 +1,92 @@
1
+ require_relative 'helper'
2
+ require 'test/unit'
3
+ require_relative '../lib/pattern-match'
4
+ require_relative '../lib/pattern-match/experimental'
5
+
6
+ class TestExperimental < Test::Unit::TestCase
7
+ def test_matcher_attribute_matcher
8
+ person_class = Struct.new(:name, :age) do
9
+ include PatternMatch::AttributeMatcher
10
+ end
11
+
12
+ company_class = Struct.new(:name) do
13
+ include PatternMatch::AttributeMatcher
14
+ end
15
+
16
+ match([person_class.new("Mary", 50), company_class.new("C")]) do
17
+ with(_[company_class.(:name => "Mary"), company_class.(:name => "C")]) { flunk }
18
+ with(_[person_class.(:age, :name => person_name), company_class.(:name => company_name)]) do
19
+ assert_equal("Mary", person_name)
20
+ assert_equal(50, age)
21
+ assert_equal("C", company_name)
22
+ end
23
+ with(_) { flunk }
24
+ end
25
+ end
26
+
27
+ def test_matcher_class_hash
28
+ match({a: 0, b: 1}) do
29
+ with(Hash.(a: a, b: b, c: c)) { flunk }
30
+ with(Hash.(a: a, b: b)) do
31
+ assert_equal(0, a)
32
+ assert_equal(1, b)
33
+ end
34
+ with(_) { flunk }
35
+ end
36
+
37
+ match({a: 0, b: 1}) do
38
+ with(Hash.(a: a)) do
39
+ assert_equal(0, a)
40
+ end
41
+ with(_) { flunk }
42
+ end
43
+
44
+ match({a: 0}) do
45
+ with(Hash.(a: 0)) { pass }
46
+ with(_) { flunk }
47
+ end
48
+
49
+ match({a: 0, b: 1}) do
50
+ with(Hash.(:a, :b, :c)) { flunk }
51
+ with(Hash.(:a, :b)) do
52
+ assert_equal(0, a)
53
+ assert_equal(1, b)
54
+ end
55
+ with(_) { flunk }
56
+ end
57
+
58
+ match({a: 0, b: 1}) do
59
+ with(Hash.(:a, :b, b: b2)) do
60
+ assert_equal(0, a)
61
+ assert_raise(NameError) { b }
62
+ assert_equal(1, b2)
63
+ end
64
+ with(_) { flunk }
65
+ end
66
+ end
67
+
68
+ def test_matcher_class_object
69
+ match(0) do
70
+ with(Object.(:to_s, :to_i => i & 1)) { flunk }
71
+ with(Object.(:to_s, :to_i => i & 0)) do
72
+ assert_equal('0', to_s)
73
+ assert_equal(0, i)
74
+ end
75
+ with(_) { flunk }
76
+ end
77
+
78
+ assert_raise(PatternMatch::MalformedPatternError) do
79
+ match(0) do
80
+ with(Object.(a, b)) {}
81
+ end
82
+ end
83
+ end
84
+
85
+ def test_object_assert_pattern
86
+ assert_equal([0], [0].assert_pattern('_[Fixnum]'))
87
+ assert_equal([0], [0].assert_pattern('_[a & Fixnum], guard { a.even? }'))
88
+ assert_raise(PatternMatch::NoMatchingPatternError) do
89
+ [0, 1].assert_pattern('_[Fixnum]')
90
+ end
91
+ end
92
+ end
@@ -1,11 +1,13 @@
1
+ require_relative 'helper'
1
2
  require 'test/unit'
2
3
  require_relative '../lib/pattern-match'
3
4
 
4
- class TestPatternMatch < Test::Unit::TestCase
5
+ class TestStandard < Test::Unit::TestCase
5
6
  def test_basic
6
7
  this = self
7
8
  ret = match([0, 1, 2, 3]) do
8
9
  with(nil) { flunk }
10
+ with(_[]) { flunk }
9
11
  with(_[a, 0, 0, b]) { flunk }
10
12
  with(_[a, Fixnum , 2, b]) do
11
13
  assert_equal(this, self)
@@ -31,6 +33,17 @@ class TestPatternMatch < Test::Unit::TestCase
31
33
  with(i, guard { i.even? }) { pass }
32
34
  with(_) { flunk }
33
35
  end
36
+
37
+ match([]) do
38
+ with(_[]) { pass }
39
+ with(_) { flunk }
40
+ end
41
+
42
+ assert_raise(ArgumentError) do
43
+ match(0) do
44
+ p 1
45
+ end
46
+ end
34
47
  end
35
48
 
36
49
  def test_variable_shadowing
@@ -92,7 +105,7 @@ class TestPatternMatch < Test::Unit::TestCase
92
105
  end
93
106
 
94
107
  def test_override_singleton_method
95
- skip 'Module#prepend not supported' unless Module.private_method_defined?(:prepend)
108
+ skip 'Module#prepend not supported' unless Module.respond_to?(:prepend, true)
96
109
  match(0) do
97
110
  with(_test_override_singleton_method) do
98
111
  def self._test_override_singleton_method
@@ -110,6 +123,12 @@ class TestPatternMatch < Test::Unit::TestCase
110
123
  end
111
124
  with(_) { flunk }
112
125
  end
126
+
127
+ assert_raise(PatternMatch::MalformedPatternError) do
128
+ match(0) do
129
+ with(_(0, :==, nil)) {}
130
+ end
131
+ end
113
132
  end
114
133
 
115
134
  def test_splat
@@ -498,10 +517,17 @@ class TestPatternMatch < Test::Unit::TestCase
498
517
  end
499
518
  end
500
519
 
501
- def test_match_without_argument
520
+ def test_match_without_arguments
502
521
  assert_equal(1, 2.times.find(&match { with(1) { true }; with(_) { false } }))
503
522
  end
504
523
 
524
+ def test_match_too_many_arguments
525
+ assert_raise(ArgumentError) do
526
+ match(0, 1) do
527
+ end
528
+ end
529
+ end
530
+
505
531
  def test_deconstructor_class
506
532
  assert_raise(NotImplementedError) do
507
533
  c = Class.new
@@ -524,26 +550,6 @@ class TestPatternMatch < Test::Unit::TestCase
524
550
  end
525
551
  end
526
552
 
527
- def test_deconstructor_class_attributes_with_hash
528
- person_class = Struct.new(:name, :age) do
529
- include PatternMatch::AttributeMatcher
530
- end
531
-
532
- company_class = Struct.new(:name) do
533
- include PatternMatch::AttributeMatcher
534
- end
535
-
536
- match([person_class.new("Mary", 50), company_class.new("C")]) do
537
- with(_[company_class.(:name => "Mary"), company_class.(:name => "C")]) { flunk }
538
- with(_[person_class.(:age, :name => person_name), company_class.(:name => company_name)]) do
539
- assert_equal("Mary", person_name)
540
- assert_equal(50, age)
541
- assert_equal("C", company_name)
542
- end
543
- with(_) { flunk }
544
- end
545
- end
546
-
547
553
  def test_deconstructor_class_complex
548
554
  match(Complex(0, 1)) do
549
555
  with(Complex.(a, b)) do
@@ -604,62 +610,4 @@ class TestPatternMatch < Test::Unit::TestCase
604
610
  with(_) { flunk }
605
611
  end
606
612
  end
607
-
608
- def test_deconstructor_class_hash
609
- match({a: 0, b: 1}) do
610
- with(Hash.(a: a, b: b, c: c)) { flunk }
611
- with(Hash.(a: a, b: b)) do
612
- assert_equal(0, a)
613
- assert_equal(1, b)
614
- end
615
- with(_) { flunk }
616
- end
617
-
618
- match({a: 0, b: 1}) do
619
- with(Hash.(a: a)) do
620
- assert_equal(0, a)
621
- end
622
- with(_) { flunk }
623
- end
624
-
625
- match({a: 0}) do
626
- with(Hash.(a: 0)) { pass }
627
- with(_) { flunk }
628
- end
629
-
630
- match({a: 0, b: 1}) do
631
- with(Hash.(:a, :b, :c)) { flunk }
632
- with(Hash.(:a, :b)) do
633
- assert_equal(0, a)
634
- assert_equal(1, b)
635
- end
636
- with(_) { flunk }
637
- end
638
-
639
- match({a: 0, b: 1}) do
640
- with(Hash.(:a, :b, b: b2)) do
641
- assert_equal(0, a)
642
- assert_raise(NameError) { b }
643
- assert_equal(1, b2)
644
- end
645
- with(_) { flunk }
646
- end
647
- end
648
-
649
- def test_object
650
- match(0) do
651
- with(Object.(:to_s, :to_i => i & 1)) { flunk }
652
- with(Object.(:to_s, :to_i => i & 0)) do
653
- assert_equal('0', to_s)
654
- assert_equal(0, i)
655
- end
656
- with(_) { flunk }
657
- end
658
-
659
- assert_raise(PatternMatch::MalformedPatternError) do
660
- match(0) do
661
- with(Object.(a, b)) {}
662
- end
663
- end
664
- end
665
613
  end
metadata CHANGED
@@ -1,27 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pattern-match
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kazuki Tsujimoto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-23 00:00:00.000000000 Z
11
+ date: 2014-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: simplecov
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
25
39
  - !ruby/object:Gem::Version
26
40
  version: '0'
27
41
  description: A pattern matching library.
@@ -32,39 +46,44 @@ extensions: []
32
46
  extra_rdoc_files:
33
47
  - README.rdoc
34
48
  files:
35
- - .gitignore
36
- - .travis.yml
49
+ - ".gitignore"
50
+ - ".travis.yml"
37
51
  - BSDL
38
52
  - COPYING
39
53
  - Gemfile
40
54
  - README.rdoc
41
55
  - Rakefile
42
56
  - lib/pattern-match.rb
57
+ - lib/pattern-match/core.rb
58
+ - lib/pattern-match/deconstructor.rb
59
+ - lib/pattern-match/experimental.rb
43
60
  - lib/pattern-match/version.rb
44
61
  - pattern-match.gemspec
45
- - test/test_pattern-match.rb
62
+ - test/helper.rb
63
+ - test/test_experimental.rb
64
+ - test/test_standard.rb
46
65
  homepage: https://github.com/k-tsj/pattern-match
47
66
  licenses: []
48
67
  metadata: {}
49
68
  post_install_message:
50
69
  rdoc_options:
51
- - --main
70
+ - "--main"
52
71
  - README.rdoc
53
72
  require_paths:
54
73
  - lib
55
74
  required_ruby_version: !ruby/object:Gem::Requirement
56
75
  requirements:
57
- - - '>='
76
+ - - ">="
58
77
  - !ruby/object:Gem::Version
59
78
  version: '0'
60
79
  required_rubygems_version: !ruby/object:Gem::Requirement
61
80
  requirements:
62
- - - '>='
81
+ - - ">="
63
82
  - !ruby/object:Gem::Version
64
83
  version: '0'
65
84
  requirements: []
66
85
  rubyforge_project:
67
- rubygems_version: 2.0.0
86
+ rubygems_version: 2.2.0
68
87
  signing_key:
69
88
  specification_version: 4
70
89
  summary: A pattern matching library