pattern-match 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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