-
Notifications
You must be signed in to change notification settings - Fork 0
/
matcher.rb
103 lines (85 loc) · 2.25 KB
/
matcher.rb
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
module Spec
module BeardMatchers
class File
def initialize(name, &block)
@contents = []
@name = name
if block_given?
instance_eval(&block)
end
end
def contains(text)
@contents << text
end
def matches?(root)
unless root.join(@name).exist?
throw :failure, root.join(@name)
end
contents = ::File.read(root.join(@name))
@contents.each do |string|
unless contents.include?(string)
throw :failure, [root.join(@name), string, contents]
end
end
end
end
class Directory
attr_reader :tree
def initialize(root = nil, &block)
@tree = {}
@negative_tree = []
@root = root
instance_eval(&block) if block_given?
end
def directory(name, &block)
@tree[name] = block_given? && Directory.new(location(name), &block)
end
def file(name, &block)
@tree[name] = File.new(location(name), &block)
end
def no_file(name)
@negative_tree << name
end
def location(name)
[@root, name].compact.join("/")
end
def matches?(root)
@tree.each do |file, value|
unless value
unless root.join(location(file)).exist?
throw :failure, "#{root}/#{location(file)}"
end
else
value.matches?(root)
end
end
@negative_tree.each do |file|
if root.join(location(file)).exist?
throw :failure, [:not, "unexpected #{root}/#{location(file)}"]
end
end
nil
end
end
class Root < Directory
def failure_message
if @failure.is_a?(Array) && @failure[0] == :not
"Structure should not have had #{@failure[1]}, but it did"
elsif @failure.is_a?(Array)
"Structure should have #{@failure[0]} with #{@failure[1]}. It had:\n#{@failure[2]}"
else
"Structure should have #{@failure}, but it didn't"
end
end
def matches?(root)
@failure = catch :failure do
super
end
!@failure
end
end
def have_structure(&block)
Root.new(&block)
end
end
end