File: test_helper.rb

package info (click to toggle)
ruby-representable 3.0.4-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 896 kB
  • sloc: ruby: 6,432; makefile: 3
file content (145 lines) | stat: -rw-r--r-- 3,476 bytes parent folder | download
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
require 'representable'

require 'minitest/autorun'
require 'test_xml/mini_test'

require "representable/debug"

module Minitest::Assertions
  def assert_equal_xml(text, subject)
    subject.gsub("\n", "").gsub(/(\s\s+)/, "").must_equal(text.gsub("\n", "").gsub(/(\s\s+)/, ""))
  end
end
String.infect_an_assertion :assert_equal_xml, :must_xml

# TODO: delete all that in 4.0:
class Album
  attr_accessor :songs, :best_song
  def initialize(songs=nil, best_song=nil)
    @songs      = songs
    @best_song  = best_song
  end

  def ==(other)
    songs == other.songs and best_song == other.best_song
  end
end

class Song
  attr_accessor :name, :track # never change this, track rendered with Rails#to_json.
  def initialize(name=nil, track=nil)
    @name   = name
    @track  = track
  end

  def ==(other)
    name == other.name and track == other.track
  end
end

module XmlHelper
  def xml(document)
    Nokogiri::XML(document).root
  end
end

module AssertJson
  module Assertions
    def assert_json(expected, actual, msg=nil)
      msg = message(msg, "") { diff expected, actual }
      assert(expected.split("").sort == actual.split("").sort, msg)
    end
  end
end

Minitest::Spec.class_eval do
  include AssertJson::Assertions
  include XmlHelper

  def self.for_formats(formats)
    formats.each do |format, cfg|
      mod, output, input = cfg
      yield format, mod, output, input
    end
  end

  def render(object, *args)
    AssertableDocument.new(object.send("to_#{format}", *args), format)
  end

  def parse(object, input, *args)
    object.send("from_#{format}", input, *args)
  end

  class AssertableDocument
    attr_reader :document

    def initialize(document, format)
      @document, @format = document, format
    end

    def must_equal_document(*args)
      return document.must_equal_xml(*args) if @format == :xml
      document.must_equal(*args)
    end
  end

  def self.representer!(options={}, &block)
    fmt = options # we need that so the 2nd call to ::let(within a ::describe) remembers the right format.

    name   = options[:name]   || :representer
    format = options[:module] || Representable::Hash

    let(name) do
      mod = options[:decorator] ? Class.new(Representable::Decorator) : Module.new

      inject_representer(mod, fmt)

      mod.module_eval do
        include format
        instance_exec(&block)
      end

      mod
    end

    undef :inject_representer if method_defined? :inject_representer

    def inject_representer(mod, options)
      return unless options[:inject]

      injected_name = options[:inject]
      injected = send(injected_name) # song_representer
      mod.singleton_class.instance_eval do
        define_method(injected_name) { injected }
      end
    end
  end

  module TestMethods
    def representer_for(modules=[Representable::Hash], &block)
      Module.new do
        extend TestMethods
        include(*modules)
        module_exec(&block)
      end
    end

    alias_method :representer!, :representer_for
  end
  include TestMethods
end

class BaseTest < Minitest::Spec
  let(:new_album)  { OpenStruct.new.extend(representer) }
  let(:album)      { OpenStruct.new(:songs => ["Fuck Armageddon"]).extend(representer) }
  let(:song) { OpenStruct.new(:title => "Resist Stance") }
  let(:song_representer) { Module.new do include Representable::Hash; property :title end  }

end

Band = Struct.new(:id, :name) do
  def [](*attrs)
    attrs.collect { |attr| send(attr) }
  end
end