Skip to content

Refactor cleanup tests #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: package-refactor-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions customskill/examples/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ func main() {
http.ListenAndServe(":8080", nil)
}

func onLaunch(launchRequest *request.LaunchRequest) (*response.Response, map[string]interface{}, error) {
func onLaunch(launchRequest *request.LaunchRequest, metadata *request.Metadata) (*response.Response, map[string]interface{}, error) {
resp := response.New()
resp.SetEndSession(response.Bool(true))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the session stay open if the user is launching the skill? seems like the example could be misleading.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth adding some speech here so if the user tries it out then they can at least get some output speech?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonably. It's on my "todo" list but I'm currently getting slammed at work. Hope to have time later this week to work on this.

sessAttrs := make(map[string]interface{})
sessAttrs["hello"] = "world"
return resp, sessAttrs, nil
metadata.Session.Attributes["hello"] = "world"
return resp, metadata.Session.Attributes, nil
}
40 changes: 25 additions & 15 deletions customskill/request/request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,25 +194,35 @@ func TestRequest_BootstrapFromJSON(t *testing.T) {
}

for _, test := range tests {
jsonUnmarshal = test.jsonUnmarshal
t.Run(test.name, func(t *testing.T) {
// Record & restore original functions.
jsonUnmarshalOriginal := jsonUnmarshal
defer func() {
jsonUnmarshal = jsonUnmarshalOriginal
}()

m, r, err := BootstrapFromJSON([]byte(test.payload))
if !errorContains(err, test.partialErrorMessage) {
t.Errorf("%s: error mismatch:\n\tgot: %v\n\texpected: it to contain %s", test.name, err, pointerStr(test.partialErrorMessage))
continue
}
// Override mocked functions.
jsonUnmarshal = test.jsonUnmarshal

if test.partialErrorMessage != nil {
continue
}
// Exercise the function being tested.
m, r, err := BootstrapFromJSON([]byte(test.payload))
if !errorContains(err, test.partialErrorMessage) {
t.Errorf("error mismatch:\n\tgot: %v\n\twanted: it to contain %s", err, pointerStr(test.partialErrorMessage))
return
}

if !reflect.DeepEqual(*m, *test.metadata) {
t.Errorf("%s: metadata mismatch:\n\tgot: %#v\n\twanted: %#v", test.name, *m, *test.metadata)
}
if test.partialErrorMessage != nil {
return
}

if !reflect.DeepEqual(r, test.request) {
t.Errorf("%s: request mismatch:\n\tgot: %#v\n\twanted: %#v", test.name, r, test.request)
}
if !reflect.DeepEqual(*m, *test.metadata) {
t.Errorf("metadata mismatch: got: %+v, wanted: %+v", *m, *test.metadata)
}

if !reflect.DeepEqual(r, test.request) {
t.Errorf("request mismatch: got: %+v, wanted: %+v", r, test.request)
}
})
}
}

Expand Down
8 changes: 4 additions & 4 deletions customskill/skill.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (s *Skill) Handle(w io.Writer, b []byte) error {
return errors.New("no OnLaunch handler defined")
}
lr := e.(*request.LaunchRequest)
resp, sess, err = s.OnLaunch(lr)
resp, sess, err = s.OnLaunch(lr, m)
if err != nil {
return errors.New("OnLaunch handler failed: " + err.Error())
}
Expand All @@ -49,7 +49,7 @@ func (s *Skill) Handle(w io.Writer, b []byte) error {
return errors.New("no OnIntent handler defined")
}
ir := e.(*request.IntentRequest)
resp, sess, err = s.OnIntent(ir, &m.Session)
resp, sess, err = s.OnIntent(ir, m)
if err != nil {
return errors.New("OnIntent handler failed: " + err.Error())
}
Expand All @@ -58,8 +58,8 @@ func (s *Skill) Handle(w io.Writer, b []byte) error {
return errors.New("no OnSessionEnded handler defined")
}
ser := e.(*request.SessionEndedRequest)
if err = s.OnSessionEnded(ser); err != nil {
return errors.New("OnSessionEnded handler failed: " + err.Error())
if err = s.OnSessionEnded(ser, m); err != nil {
return errors.New("OnSessionEnded handler failed:" + err.Error())
}
// A skill cannot return a response to SessionEndedRequest.
return nil
Expand Down
99 changes: 45 additions & 54 deletions customskill/skill_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package customskill

import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"strings"
Expand All @@ -14,16 +13,6 @@ import (
)

func TestSkill_Handle(t *testing.T) {
handleTests(t)
}

func BenchmarkSkill_Handle(b *testing.B) {
for n := 0; n < b.N; n++ {
handleTests(b)
}
}

func handleTests(t testingiface) {
var tests = []struct {
name string
skill *Skill
Expand All @@ -38,7 +27,7 @@ func handleTests(t testingiface) {
name: "happy-path-launch-request",
skill: &Skill{
ValidApplicationIDs: []string{"testApplicationId"},
OnLaunch: func(request *request.LaunchRequest) (*response.Response, map[string]interface{}, error) {
OnLaunch: func(request *request.LaunchRequest, metadata *request.Metadata) (*response.Response, map[string]interface{}, error) {
sessAttrs := make(map[string]interface{})
sessAttrs["name"] = "happy-path-launch-request"
return response.New(), sessAttrs, nil
Expand All @@ -62,7 +51,7 @@ func handleTests(t testingiface) {
name: "happy-path-intent-request",
skill: &Skill{
ValidApplicationIDs: []string{"testApplicationId"},
OnIntent: func(intentRequest *request.IntentRequest, session *request.Session) (*response.Response, map[string]interface{}, error) {
OnIntent: func(intentRequest *request.IntentRequest, metadata *request.Metadata) (*response.Response, map[string]interface{}, error) {
sessAttrs := make(map[string]interface{})
sessAttrs["name"] = "happy-path-intent-request"
return response.New(), sessAttrs, nil
Expand All @@ -86,9 +75,9 @@ func handleTests(t testingiface) {
name: "happy-path-intent-request-with-session-attributes",
skill: &Skill{
ValidApplicationIDs: []string{"testApplicationId"},
OnIntent: func(intentRequest *request.IntentRequest, session *request.Session) (*response.Response, map[string]interface{}, error) {
session.Attributes["name"] = "happy-path-intent-request-with-session-attributes"
return response.New(), session.Attributes, nil
OnIntent: func(intentRequest *request.IntentRequest, metadata *request.Metadata) (*response.Response, map[string]interface{}, error) {
metadata.Session.Attributes["name"] = "happy-path-intent-request-with-session-attributes"
return response.New(), metadata.Session.Attributes, nil
},
},
b: `
Expand All @@ -110,7 +99,7 @@ func handleTests(t testingiface) {
name: "happy-path-session-ended-request",
skill: &Skill{
ValidApplicationIDs: []string{"testApplicationId"},
OnSessionEnded: func(endedRequest *request.SessionEndedRequest) error {
OnSessionEnded: func(endedRequest *request.SessionEndedRequest, metadata *request.Metadata) error {
return nil
},
},
Expand Down Expand Up @@ -203,7 +192,7 @@ func handleTests(t testingiface) {
name: "on-launch-request-handler-error-returns-error",
skill: &Skill{
ValidApplicationIDs: []string{"testApplicationId"},
OnLaunch: func(request *request.LaunchRequest) (*response.Response, map[string]interface{}, error) {
OnLaunch: func(request *request.LaunchRequest, metadata *request.Metadata) (*response.Response, map[string]interface{}, error) {
return nil, nil, errors.New("dummy error")
},
},
Expand Down Expand Up @@ -242,7 +231,7 @@ func handleTests(t testingiface) {
name: "on-intent-request-handler-error-returns-error",
skill: &Skill{
ValidApplicationIDs: []string{"testApplicationId"},
OnIntent: func(intentRequest *request.IntentRequest, session *request.Session) (*response.Response, map[string]interface{}, error) {
OnIntent: func(intentRequest *request.IntentRequest, metadata *request.Metadata) (*response.Response, map[string]interface{}, error) {
return nil, nil, errors.New("dummy error")
},
},
Expand Down Expand Up @@ -281,7 +270,7 @@ func handleTests(t testingiface) {
name: "on-session-ended-request-handler-error-returns-error",
skill: &Skill{
ValidApplicationIDs: []string{"testApplicationId"},
OnSessionEnded: func(endedRequest *request.SessionEndedRequest) error {
OnSessionEnded: func(endedRequest *request.SessionEndedRequest, metadata *request.Metadata) error {
return errors.New("dummy error")
},
},
Expand All @@ -302,7 +291,7 @@ func handleTests(t testingiface) {
name: "responses-which-cannot-be-marshalled-returns-error",
skill: &Skill{
ValidApplicationIDs: []string{"testApplicationId"},
OnLaunch: func(request *request.LaunchRequest) (*response.Response, map[string]interface{}, error) {
OnLaunch: func(request *request.LaunchRequest, metadata *request.Metadata) (*response.Response, map[string]interface{}, error) {
return nil, nil, nil
},
},
Expand All @@ -326,7 +315,7 @@ func handleTests(t testingiface) {
name: "writer-which-cannot-be-written-returns-error",
skill: &Skill{
ValidApplicationIDs: []string{"testApplicationId"},
OnLaunch: func(request *request.LaunchRequest) (*response.Response, map[string]interface{}, error) {
OnLaunch: func(request *request.LaunchRequest, metadata *request.Metadata) (*response.Response, map[string]interface{}, error) {
return nil, nil, nil
},
},
Expand All @@ -350,7 +339,7 @@ func handleTests(t testingiface) {
name: "writer-which-partially-writes-returns-error",
skill: &Skill{
ValidApplicationIDs: []string{"testApplicationId"},
OnLaunch: func(request *request.LaunchRequest) (*response.Response, map[string]interface{}, error) {
OnLaunch: func(request *request.LaunchRequest, metadata *request.Metadata) (*response.Response, map[string]interface{}, error) {
return nil, nil, nil
},
},
Expand All @@ -373,46 +362,48 @@ func handleTests(t testingiface) {
}

for _, test := range tests {
t.Logf("Testing: %s", test.name)
// Override mocked functions
if test.requestBootstrapFromJSON != nil {
requestBootstrapFromJSON = test.requestBootstrapFromJSON
}
if test.jsonMarshal != nil {
jsonMarshal = test.jsonMarshal
}
err := test.skill.Handle(test.w, []byte(test.b))
if !errorContains(err, test.partialErrorMessage) {
t.Errorf("%s: error mismatch:\n\tgot: %v\n\twanted: it to contain '%s'", test.name, err, pointerStr(test.partialErrorMessage))
continue
}
t.Run(test.name, func(t *testing.T) {
// Record & restore original functions.
requestBootstrapFromJSONOriginal := requestBootstrapFromJSON
jsonMarshalOriginal := jsonMarshal
defer func() {
requestBootstrapFromJSON = requestBootstrapFromJSONOriginal
jsonMarshal = jsonMarshalOriginal
}()

// Override mocked functions.
if test.requestBootstrapFromJSON != nil {
requestBootstrapFromJSON = test.requestBootstrapFromJSON
}
if test.jsonMarshal != nil {
jsonMarshal = test.jsonMarshal
}

// Restore mocked functions
requestBootstrapFromJSON = request.BootstrapFromJSON
jsonMarshal = json.Marshal
// Exercise the function being tested.
err := test.skill.Handle(test.w, []byte(test.b))
if !errorContains(err, test.partialErrorMessage) {
t.Errorf("error mismatch: got: %+v, wanted: it to contain '%s'", err, pointerStr(test.partialErrorMessage))
return
}

if test.partialErrorMessage != nil {
continue
}
if test.partialErrorMessage != nil {
return
}

b, err := ioutil.ReadAll(test.w)
if err != nil {
t.Errorf("%s: failed to read test writer: %v", test.name, err)
}
b, err := ioutil.ReadAll(test.w)
if err != nil {
t.Errorf("failed to read test writer: %v", err)
}

if string(b) != test.written {
t.Errorf("%s: write mismatch:\n\tgot: %v\n\texpected:%s", test.name, string(b), test.written)
}
if string(b) != test.written {
t.Errorf("write mismatch: got: %+v, wanted: %s", string(b), test.written)
}
})
}
}

/* Test helper functions */

type testingiface interface {
Logf(format string, args ...interface{})
Errorf(format string, args ...interface{})
}

type badReadWriter struct {
n int
err error
Expand Down
6 changes: 3 additions & 3 deletions customskill/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
// A Skill represents an Alexa custom skill.
type Skill struct {
ValidApplicationIDs []string
OnLaunch func(*request.LaunchRequest) (*response.Response, map[string]interface{}, error)
OnIntent func(*request.IntentRequest, *request.Session) (*response.Response, map[string]interface{}, error)
OnSessionEnded func(*request.SessionEndedRequest) error
OnLaunch func(*request.LaunchRequest, *request.Metadata) (*response.Response, map[string]interface{}, error)
OnIntent func(*request.IntentRequest, *request.Metadata) (*response.Response, map[string]interface{}, error)
OnSessionEnded func(*request.SessionEndedRequest, *request.Metadata) error
}
Loading