~tim/scheme-vm

ref: c5110102ce2df2d78a0c87f293edf20f5a3984e7 scheme-vm/spec/compiler/pattern_spec.rb -rw-r--r-- 2.5 KiB
c5110102Tim Morgan Add more char functions 3 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
require_relative '../spec_helper'

describe Compiler::Pattern do
  describe '#match' do
    it 'matches if length is the same' do
      expect(described_class.new(['and']).match(['and'])).to eq({})
    end

    it 'does not match if length is different' do
      expect(described_class.new(['and']).match(['and', 'foo'])).to be_nil
    end

    it 'matches without a sexp' do
      expect(described_class.new(['assert', 'test']).match(['assert', 'foo'])).to eq('test' => 'foo')
    end

    it 'does not error if pattern contains a sexp but expression does not' do
      pattern = described_class.new(['assert', ['x', 'y', 'z']])
      expect(pattern.match(['assert', 'foo'])).to be_nil
    end

    it 'matches if length is different but pattern allows for variability' do
      pattern = described_class.new(['and', 'var1', '...'])
      expect(pattern.match(['and'])).to eq('var1' => nil, 'var1...' => [])
      expect(pattern.match(['and', 'foo'])).to eq('var1' => 'foo', 'var1...' => [])
      expect(pattern.match(['and', 'foo', 'bar'])).to eq('var1' => 'foo', 'var1...' => ['bar'])
      expect(pattern.match(['and', 'foo', 'bar', 'baz'])).to eq('var1' => 'foo', 'var1...' => ['bar', 'baz'])
    end

    it 'matches sub patterns' do
      pattern = described_class.new(['let', [['name', 'val'], '...']])
      expect(pattern.match(['let', [['foo', 'bar'], ['baz', 'quz']]])).to eq(
        'name'    => 'foo',
        'val'     => 'bar',
        'name...' => ['baz'],
        'val...'  => ['quz']
      )
      pattern = described_class.new(['let', [['name1', 'val1'], ['name2', 'val2'], '...']])
      expect(pattern.match(['let', [['foo', 'bar']]])).to eq(
        'name1'    => 'foo',
        'val1'     => 'bar',
        'name2'    => nil,
        'val2'     => nil,
        'name2...' => [],
        'val2...'  => []
      )
      pattern = described_class.new(['let', []])
      expect(pattern.match(['let', [[]]])).to eq({})
    end

    it 'matches literals literally' do
      pattern = described_class.new(
        ['assert', ['expected', 'eq?', 'actual']],
        literals: ['eq?']
      )
      result = pattern.match(
        ['assert', ['foo', 'eq?', 'bar']]
      )
      expect(result).to eq(
        'expected' => 'foo',
        'actual' => 'bar'
      )
    end

    it 'does not match if literal does not match' do
      pattern = described_class.new(
        ['assert', ['expected', 'eq?', 'actual']],
        literals: ['eq?']
      )
      result = pattern.match(
        ['assert', ['foo', '==', 'bar']]
      )
      expect(result).to be_nil
    end
  end
end