blob: 84e45c1f27108fa77b8dd1de4e9f1f4bbc889495 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package model
import (
"fmt"
"net/url"
"reflect"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
apiModel "github.com/apache/plc4x/plc4go/pkg/api/model"
apiValues "github.com/apache/plc4x/plc4go/pkg/api/values"
"github.com/apache/plc4x/plc4go/spi/utils"
spiValues "github.com/apache/plc4x/plc4go/spi/values"
)
// TestRenderTest is a lazy test of Default* structs without proper initialization
func TestRenderTest(t *testing.T) {
suts := []interface {
fmt.Stringer
utils.Serializable
}{
&DefaultArrayInfo{},
&DefaultPlcBrowseItem{},
&DefaultPlcBrowseRequest{},
&DefaultPlcBrowseRequestBuilder{},
&DefaultPlcBrowseRequestResult{},
&DefaultPlcBrowseResponse{},
&DefaultPlcBrowseResponseItem{},
&DefaultPlcConsumerRegistration{},
&DefaultPlcDiscoveryItem{},
&DefaultPlcReadRequest{DefaultPlcTagRequest: NewDefaultPlcTagRequest(nil, nil)},
&DefaultPlcReadRequestResult{},
&DefaultPlcReadResponse{},
&DefaultPlcSubscriptionEvent{},
&DefaultPlcSubscriptionEventItem{},
&DefaultPlcSubscriptionHandle{},
&DefaultPlcSubscriptionRequest{DefaultPlcTagRequest: NewDefaultPlcTagRequest(nil, nil)},
&DefaultPlcSubscriptionRequestResult{},
&DefaultPlcSubscriptionResponse{},
&DefaultPlcSubscriptionResponseItem{},
&DefaultPlcTagRequest{},
&DefaultPlcUnsubscriptionRequest{},
&DefaultPlcUnsubscriptionRequestResult{},
&DefaultPlcUnsubscriptionResponse{},
&DefaultPlcWriteRequest{DefaultPlcTagRequest: NewDefaultPlcTagRequest(nil, nil)},
&DefaultPlcWriteRequestResult{},
&DefaultPlcWriteResponse{},
&PlcResponseItem{},
}
for _, sut := range suts {
t.Run(fmt.Sprintf("%T", sut), func(t *testing.T) {
t.Run("String", func(t *testing.T) {
assert.NotEmptyf(t, sut.String(), "string should at least return type informations")
})
t.Run("Get*/IsÜ*", func(t *testing.T) {
valueOf := reflect.ValueOf(sut)
for i := 0; i < valueOf.NumMethod(); i++ {
method := valueOf.Method(i)
methodName := valueOf.Type().Method(i).Name
if strings.HasPrefix(methodName, "Get") || strings.HasPrefix(methodName, "Is") {
t.Run(methodName, func(t *testing.T) {
if na := method.Type().NumIn(); na != 0 {
t.Skipf("skipping because to many argument: %d", na)
}
method.Call(nil)
})
}
}
})
t.Run("Serialize", func(t *testing.T) {
serialize, err := sut.Serialize()
assert.NoError(t, err)
_ = serialize
})
})
}
}
// TODO: ensure mocks are created in test context...
// TestRenderTestCustom test some custom objects
func TestRenderTestCustom(t *testing.T) {
tests := []struct {
name string
sut func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
}
extraCall func(t *testing.T, _sut any)
}{
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcBrowseItem(
mockTag(t),
"some name",
"some datatype",
true,
true,
true,
map[string]apiModel.PlcBrowseItem{
"tagid1": mockBrowseItem(t),
"tagid2": mockBrowseItem(t),
},
map[string]apiValues.PlcValue{
"tagid1": spiValues.PlcNull{},
"tagid2": spiValues.PlcNull{},
"tagid3": nil,
},
).(interface {
fmt.Stringer
utils.Serializable
})
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcBrowseRequest(
map[string]apiModel.PlcQuery{
"tagid1": NewMockPlcQuery(t),
"tagid2": NewMockPlcQuery(t),
},
[]string{
"tagid1",
"tagid2",
},
nil,
)
},
extraCall: func(t *testing.T, _sut any) {
sut := _sut.(*DefaultPlcBrowseRequest)
// TODO: add browser calls
sut.GetQuery("tagid")
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcBrowseResponse(
NewDefaultPlcBrowseRequest(nil, nil, nil),
map[string][]apiModel.PlcBrowseItem{
"tagid": nil,
},
map[string]apiModel.PlcResponseCode{
"tagid": 0,
},
).(interface { // TODO: workaround
fmt.Stringer
utils.Serializable
})
},
extraCall: func(t *testing.T, _sut any) {
sut := _sut.(*DefaultPlcBrowseResponse)
// TODO: add assertions
sut.GetResponseCode("tagid")
sut.GetQueryResults("tagid")
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcBrowseResponseItem(0, nil)
},
},
{
// TODO: we need a mock here for improvement
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcConsumerRegistration(nil, nil, nil).(interface { // TODO: workaround
fmt.Stringer
utils.Serializable
})
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcDiscoveryItem(
"something",
"something",
url.URL{},
map[string][]string{
"something": {"else"},
},
"something",
nil,
).(interface { // TODO: workaround
fmt.Stringer
utils.Serializable
})
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcReadRequest(
map[string]apiModel.PlcTag{
"tagid": nil,
},
[]string{
"tagid",
},
nil,
nil,
).(interface { // TODO: workaround
fmt.Stringer
utils.Serializable
})
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcReadResponse(
NewDefaultPlcReadRequest(nil, nil, nil, nil),
map[string]apiModel.PlcResponseCode{
"tagid": 0,
},
map[string]apiValues.PlcValue{
"tagid": nil,
},
).(interface { // TODO: workaround
fmt.Stringer
utils.Serializable
})
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcSubscriptionEvent(
nil,
map[string]apiModel.PlcTag{
"tagid": nil,
},
map[string]apiModel.PlcSubscriptionType{
"tagid": 0,
},
map[string]time.Duration{
"tagid": 0,
},
map[string]apiModel.PlcResponseCode{
"tagid": 0,
},
map[string]apiValues.PlcValue{
"tagid": nil,
},
).(interface { // TODO: workaround
fmt.Stringer
utils.Serializable
})
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcSubscriptionEventItem(
0,
nil,
0,
0,
nil,
)
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcSubscriptionHandle(
nil,
).(interface { // TODO: workaround
fmt.Stringer
utils.Serializable
})
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcSubscriptionRequest(
nil,
[]string{"tagid"},
map[string]apiModel.PlcSubscriptionTag{
"tagid": nil,
},
map[string]apiModel.PlcSubscriptionType{
"tagid": 0,
},
map[string]time.Duration{
"tagid": 0,
},
map[string][]apiModel.PlcSubscriptionEventConsumer{
"tagd": nil,
},
).(interface { // TODO: workaround
fmt.Stringer
utils.Serializable
})
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcSubscriptionResponse(
NewDefaultPlcSubscriptionRequest(nil, nil, nil, nil, nil, nil),
map[string]apiModel.PlcResponseCode{
"tagid": 0,
},
map[string]apiModel.PlcSubscriptionHandle{
"tagid": nil,
},
).(interface { // TODO: workaround
fmt.Stringer
utils.Serializable
})
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcSubscriptionResponseItem(
0,
NewDefaultPlcSubscriptionHandle(nil),
)
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcTagRequest(
map[string]apiModel.PlcTag{
"tagid": nil,
},
[]string{"tagid"},
)
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcUnsubscriptionRequestResult(
NewDefaultPlcUnsubscriptionRequest(nil),
NewDefaultPlcUnsubscriptionResponse(nil),
nil,
).(interface { // TODO: workaround
fmt.Stringer
utils.Serializable
})
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcWriteRequest(
map[string]apiModel.PlcTag{
"tagid": nil,
},
[]string{"tagid"},
map[string]apiValues.PlcValue{
"tageid": nil,
},
nil,
nil,
).(interface { // TODO: workaround
fmt.Stringer
utils.Serializable
})
},
},
{
sut: func(t *testing.T) interface {
fmt.Stringer
utils.Serializable
} {
return NewDefaultPlcWriteResponse(
NewDefaultPlcWriteRequest(nil, nil, nil, nil, nil),
map[string]apiModel.PlcResponseCode{
"tagid": 0,
},
).(interface { // TODO: workaround
fmt.Stringer
utils.Serializable
})
},
},
}
for _, tt := range tests {
sut := tt.sut
testName := fmt.Sprintf("%T", sut(t))
if tt.name != "" {
testName += " - " + tt.name
}
t.Run(testName, func(t *testing.T) {
t.Run("String", func(t *testing.T) {
assert.NotEmptyf(t, sut(t).String(), "string should at least return type informations")
})
t.Run("Get*/IsÜ*", func(t *testing.T) {
valueOf := reflect.ValueOf(sut(t))
for i := 0; i < valueOf.NumMethod(); i++ {
method := valueOf.Method(i)
methodName := valueOf.Type().Method(i).Name
if strings.HasPrefix(methodName, "Get") || strings.HasPrefix(methodName, "Is") {
t.Run(methodName, func(t *testing.T) {
// TODO: if it is 1 arg and a string it is probably the get tags something: maybe we hardcode it here
if na := method.Type().NumIn(); na != 0 {
t.Skipf("skipping because to many argument: %d", na)
}
method.Call(nil)
})
}
}
})
t.Run("Serialize", func(t *testing.T) {
serialize, err := sut(t).Serialize()
assert.NoError(t, err)
_ = serialize
})
if tt.extraCall != nil {
t.Run("extra call", func(t *testing.T) {
tt.extraCall(t, sut(t))
})
}
})
}
}
func mockBrowseItem(t *testing.T) *MockPlcBrowseItem {
item := NewMockPlcBrowseItem(t)
item.EXPECT().String().Return("mocktag").Maybe()
return item
}
func mockTag(t *testing.T) *MockPlcTag {
tag := NewMockPlcTag(t)
tag.EXPECT().String().Return("mocktag").Maybe()
return tag
}