1// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
2//
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7//
8// 1. Redistributions of source code must retain the above copyright notice, this
9//    list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright notice,
11//    this list of conditions and the following disclaimer in the documentation
12//    and/or other materials provided with the distribution.
13//
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25package seelog
26
27import (
28	"errors"
29	"strconv"
30	"testing"
31)
32
33// bytesVerifier is a byte receiver which is used for correct input testing.
34// It allows to compare expected result and actual result in context of received bytes.
35type bytesVerifier struct {
36	expectedBytes   []byte // bytes that are expected to be written in next Write call
37	waitingForInput bool   // true if verifier is waiting for a Write call
38	writtenData     []byte // real bytes that actually were received during the last Write call
39	testEnv         *testing.T
40}
41
42func newBytesVerifier(t *testing.T) (*bytesVerifier, error) {
43	if t == nil {
44		return nil, errors.New("testing environment param is nil")
45	}
46
47	verifier := new(bytesVerifier)
48	verifier.testEnv = t
49
50	return verifier, nil
51}
52
53// Write is used to check whether verifier was waiting for input and whether bytes are the same as expectedBytes.
54// After Write call, waitingForInput is set to false.
55func (verifier *bytesVerifier) Write(bytes []byte) (n int, err error) {
56	if !verifier.waitingForInput {
57		verifier.testEnv.Errorf("unexpected input: %v", string(bytes))
58		return
59	}
60
61	verifier.waitingForInput = false
62	verifier.writtenData = bytes
63
64	if verifier.expectedBytes != nil {
65		if bytes == nil {
66			verifier.testEnv.Errorf("incoming 'bytes' is nil")
67		} else {
68			if len(bytes) != len(verifier.expectedBytes) {
69				verifier.testEnv.Errorf("'Bytes' has unexpected len. Expected: %d. Got: %d. . Expected string: %q. Got: %q",
70					len(verifier.expectedBytes), len(bytes), string(verifier.expectedBytes), string(bytes))
71			} else {
72				for i := 0; i < len(bytes); i++ {
73					if verifier.expectedBytes[i] != bytes[i] {
74						verifier.testEnv.Errorf("incorrect data on position %d. Expected: %d. Got: %d. Expected string: %q. Got: %q",
75							i, verifier.expectedBytes[i], bytes[i], string(verifier.expectedBytes), string(bytes))
76						break
77					}
78				}
79			}
80		}
81	}
82
83	return len(bytes), nil
84}
85
86func (verifier *bytesVerifier) ExpectBytes(bytes []byte) {
87	verifier.waitingForInput = true
88	verifier.expectedBytes = bytes
89}
90
91func (verifier *bytesVerifier) MustNotExpect() {
92	if verifier.waitingForInput {
93		errorText := "Unexpected input: "
94
95		if verifier.expectedBytes != nil {
96			errorText += "len = " + strconv.Itoa(len(verifier.expectedBytes))
97			errorText += ". text = " + string(verifier.expectedBytes)
98		}
99
100		verifier.testEnv.Errorf(errorText)
101	}
102}
103
104func (verifier *bytesVerifier) Close() error {
105	return nil
106}
107
108// nullWriter implements io.Writer inteface and does nothing, always returning a successful write result
109type nullWriter struct {
110}
111
112func (writer *nullWriter) Write(bytes []byte) (n int, err error) {
113	return len(bytes), nil
114}
115
116func (writer *nullWriter) Close() error {
117	return nil
118}
119