|
| 1 | +module GrapeEntityMatchers |
| 2 | + module DocumentMatcher |
| 3 | + def document(documentable) |
| 4 | + DocumentMatcher.new(documentable) |
| 5 | + end |
| 6 | + |
| 7 | + class DocumentMatcher |
| 8 | + def initialize(documentable) |
| 9 | + @expected_documentable = documentable |
| 10 | + end |
| 11 | + |
| 12 | + def description |
| 13 | + "ensure that #{@subject} documents the #{@expected_documentable} exposure" |
| 14 | + end |
| 15 | + |
| 16 | + def matches?(subject) |
| 17 | + @subject = subject |
| 18 | + |
| 19 | + has_documentation? && verify_documentation |
| 20 | + end |
| 21 | + |
| 22 | + def type(type_value) |
| 23 | + @type = type_value |
| 24 | + self |
| 25 | + end |
| 26 | + |
| 27 | + def required(required_value) |
| 28 | + @required = required_value |
| 29 | + self |
| 30 | + end |
| 31 | + |
| 32 | + def desc(desc_value) |
| 33 | + @desc = desc_value |
| 34 | + self |
| 35 | + end |
| 36 | + |
| 37 | + def default(default_value) |
| 38 | + @default = default_value |
| 39 | + self |
| 40 | + end |
| 41 | + |
| 42 | + def values(values) |
| 43 | + @values = values |
| 44 | + self |
| 45 | + end |
| 46 | + |
| 47 | + def with(documentation) |
| 48 | + @documentation = documentation |
| 49 | + self |
| 50 | + end |
| 51 | + |
| 52 | + def failure_message |
| 53 | + "#{@subject} didn't document #{@expected_documentable} "\ |
| 54 | + "as expected: #{expected_documentation}, got #{match_documentation}" |
| 55 | + end |
| 56 | + |
| 57 | + def failure_message_when_negated |
| 58 | + message = "didn't expect #{@subject} to document #{@expected_documentable}" |
| 59 | + message << " with: #{expected_documentation}" unless expected_documentation.empty? |
| 60 | + message << ", got: #{actual_documentation}" |
| 61 | + end |
| 62 | + |
| 63 | + private |
| 64 | + |
| 65 | + def expected_documentation |
| 66 | + @documentation || |
| 67 | + { |
| 68 | + type: @type, |
| 69 | + desc: @desc, |
| 70 | + required: @required, |
| 71 | + default: @default, |
| 72 | + values: @values |
| 73 | + }.compact |
| 74 | + end |
| 75 | + |
| 76 | + def match_documentation |
| 77 | + if has_documentation? |
| 78 | + exposure[:documentation].slice(*expected_documentation.keys) |
| 79 | + end |
| 80 | + end |
| 81 | + |
| 82 | + def actual_documentation |
| 83 | + exposure.try(:[], :documentation) |
| 84 | + end |
| 85 | + |
| 86 | + def has_documentation? |
| 87 | + @subject.exposures.has_key?(@expected_documentable) && |
| 88 | + exposure[:documentation] |
| 89 | + end |
| 90 | + |
| 91 | + def exposure |
| 92 | + @subject.exposures[@expected_documentable] |
| 93 | + end |
| 94 | + |
| 95 | + def verify_documentation |
| 96 | + if @documentation |
| 97 | + @documentation == exposure[:documentation] |
| 98 | + else |
| 99 | + expected_documentation == match_documentation |
| 100 | + end |
| 101 | + end |
| 102 | + end |
| 103 | + end |
| 104 | +end |
0 commit comments