Skip to content

Commit

Permalink
Merge pull request #18 from aichaos/bugfixes
Browse files Browse the repository at this point in the history
Low-hanging bugs, unit test and code restructure
  • Loading branch information
kirsle authored Feb 2, 2017
2 parents e0f373b + 1460687 commit b2781a8
Show file tree
Hide file tree
Showing 37 changed files with 1,703 additions and 1,158 deletions.
60 changes: 60 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,66 @@

This documents the history of significant changes to `rivescript-go`.

## v0.1.1 - TBD

This update focuses on bug fixes and code reorganization.

### API Breaking Changes

* `rivescript.New()` and the `Config` struct have been refactored. `Config`
now comes from the `rivescript` package directly rather than needing to
import from `rivescript/config`.

For your code, this means you can remove the `aichaos/rivescript-go/config`
import and change the `config.Config` name to `rivescript.Config`:

```go
import "github.com/aichaos/rivescript-go"

func main() {
// Example defining the struct to override defaults.
bot := rivescript.New(&rivescript.Config{Debug: true})

// For the old `config.Basic()` that provided default settings, just
// pass in a nil Config object.
bot = rivescript.New(nil)

// For the old `config.UTF8()` helper function that provided a Config with
// UTF-8 mode enabled, instead call rivescript.WithUTF8()
bot = rivescript.New(rivescript.WithUTF8())
}
```
* `Reply()`, `SortReplies()` and `CurrentUser()` now return an `error` value
in addition to what they already returned.

### Changes

* Separate the unit tests into multiple files and put them in the `rivescript`
package instead of `rivescript_test`; this enables test code coverage
reporting (we're at 72.1% coverage!)
* Handle module configuration at the root package instead of in the `src`
package. This enabled getting rid of the `rivescript/config` package and
making the public API more sane.
* Code cleanup via `go vet`
* Add more documentation and examples to the Go doc.
* Fix `@Redirects` not working sometimes when tags like `<bot>` insert capital
letters (bug #1)
* Fix an incorrect regexp that makes wildcards inside of optionals, like `[_]`,
not matchable in `<star>` tags. For example, with `+ my favorite [_] is *`
and a message of "my favorite color is red", `<star1>` would be "red" because
the optional makes its wildcard non-capturing (bug #15)
* Fix the `<star>` tag handling to support star numbers greater than `<star9>`:
you can use as many star numbers as will be captured by your trigger (bug #16)
* Fix a probable bug within inheritance/includes: some parts of the code were
looking in one location for them, another in the other, so they probably
didn't work perfectly before.
* Fix `RemoveHandler()` to make it remove all known object macros that used that
handler, which protects against a possible null pointer exception.
* Fix `LoadDirectory()` to return an error when doesn't find any RiveScript
source files to load, which helps protect against the common error that you
gave it the wrong directory.
* New unit tests: object macros
## v0.1.0 - Dec 11, 2016
This update changes some function prototypes in the API which breaks backward
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fmt:

# `make test` to run unit tests
test: gopath
GOPATH=$(GOPATH) GO15VENDOREXPERIMENT=1 go test github.com/aichaos/rivescript-go/src
GOPATH=$(GOPATH) GO15VENDOREXPERIMENT=1 go test ./src

# `make build` to build the binary
build: gopath
Expand Down
11 changes: 7 additions & 4 deletions cmd/rivescript/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"strings"

"github.com/aichaos/rivescript-go"
"github.com/aichaos/rivescript-go/config"
"github.com/aichaos/rivescript-go/lang/javascript"
)

Expand All @@ -51,7 +50,7 @@ func main() {
root := args[0]

// Initialize the bot.
bot := rivescript.New(&config.Config{
bot := rivescript.New(&rivescript.Config{
Debug: *debug,
Strict: !*nostrict,
Depth: *depth,
Expand Down Expand Up @@ -98,8 +97,12 @@ Type a message to the bot and press Return to send it.
} else if strings.Index(text, "/quit") == 0 {
os.Exit(0)
} else {
reply := bot.Reply("localuser", text)
fmt.Printf("Bot> %s\n", reply)
reply, err := bot.Reply("localuser", text)
if err != nil {
fmt.Printf("Error> %s\n", err)
} else {
fmt.Printf("Bot> %s\n", reply)
}
}
}
}
Expand Down
45 changes: 45 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package rivescript

import "github.com/aichaos/rivescript-go/sessions"

/*
Type Config provides options to configure the RiveScript bot.
Create a pointer to this type and send it to the New() constructor to change
the default settings. You only need to provide settings you want to override;
the zero-values of all the options are handled appropriately by the RiveScript
library.
The default values are documented below.
*/
type Config struct {
// Debug enables verbose logging to standard output. Default false.
Debug bool

// Strict enables strict syntax checking, where a syntax error in RiveScript
// code is considered fatal at parse time. Default true.
Strict bool

// UTF8 enables UTF-8 mode within the bot. Default false.
//
// When UTF-8 mode is enabled, triggers in the RiveScript source files are
// allowed to contain foreign characters. Additionally, the user's incoming
// messages are left *mostly* intact, so that they send messages with
// foreign characters to the bot.
UTF8 bool

// Depth controls the global limit for recursive functions within
// RiveScript. Default 50.
Depth uint

// SessionManager is an implementation of the same name for managing user
// variables for the bot. The default is the in-memory session handler.
SessionManager sessions.SessionManager
}

// WithUTF8 provides a Config object that enables UTF-8 mode.
func WithUTF8() *Config {
return &Config{
UTF8: true,
}
}
54 changes: 0 additions & 54 deletions config/config.go

This file was deleted.

67 changes: 67 additions & 0 deletions deprecated.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package rivescript

// deprecated.go is where functions that are deprecated move to.

import (
"fmt"
"os"
)

// common function to put the deprecated note.
func deprecated(name, since string) {
fmt.Fprintf(
os.Stderr,
"Use of 'rivescript.%s()' is deprecated since v%s (this is v%s)\n",
name,
since,
VERSION,
)
}

// SetDebug enables or disable debug mode.
func (self *RiveScript) SetDebug(value bool) {
deprecated("SetDebug", "0.1.0")
self.rs.Debug = value
}

// GetDebug tells you the current status of the debug mode.
func (self *RiveScript) GetDebug() bool {
deprecated("GetDebug", "0.1.0")
return self.rs.Debug
}

// SetUTF8 enables or disabled UTF-8 mode.
func (self *RiveScript) SetUTF8(value bool) {
deprecated("SetUTF8", "0.1.0")
self.rs.UTF8 = value
}

// GetUTF8 returns the current status of UTF-8 mode.
func (self *RiveScript) GetUTF8() bool {
deprecated("GetUTF8", "0.1.0")
return self.rs.UTF8
}

// SetDepth lets you override the recursion depth limit (default 50).
func (self *RiveScript) SetDepth(value uint) {
deprecated("SetDepth", "0.1.0")
self.rs.Depth = value
}

// GetDepth returns the current recursion depth limit.
func (self *RiveScript) GetDepth() uint {
deprecated("GetDepth", "0.1.0")
return self.rs.Depth
}

// SetStrict enables strict syntax checking when parsing RiveScript code.
func (self *RiveScript) SetStrict(value bool) {
deprecated("SetStrict", "0.1.0")
self.rs.Strict = value
}

// GetStrict returns the strict syntax check setting.
func (self *RiveScript) GetStrict() bool {
deprecated("GetStrict", "0.1.0")
return self.rs.Strict
}
61 changes: 49 additions & 12 deletions doc_test.go
Original file line number Diff line number Diff line change
@@ -1,35 +1,73 @@
package rivescript_test
package rivescript

import (
"fmt"

"github.com/aichaos/rivescript-go"
"github.com/aichaos/rivescript-go/config"
"github.com/aichaos/rivescript-go/lang/javascript"
rss "github.com/aichaos/rivescript-go/src"
)

func ExampleRiveScript() {
bot := rivescript.New(config.Basic())
func Example() {
// Create a new RiveScript instance, which represents an individual bot
// with its own brain and memory of users.
//
// You can provide a rivescript.Config struct to configure the bot and
// provide values that differ from the defaults:
bot := rivescript.New(&rivescript.Config{
UTF8: true, // enable UTF-8 mode
Debug: true, // enable debug mode
})

// Or if you want the default configuration, provide a nil config.
// See the documentation for the rivescript.Config type for information
// on what the defaults are.
bot = rivescript.New(nil)

// Load a directory full of RiveScript documents (.rive files)
bot.LoadDirectory("eg/brain")

// Load an individual file.
bot.LoadFile("testsuite.rive")

// Stream in more RiveScript code dynamically from a string.
bot.Stream(`
+ hello bot
- Hello, human!
`)

// Sort the replies after loading them!
bot.SortReplies()

// Get a reply.
reply := bot.Reply("local-user", "Hello, bot!")
reply, _ := bot.Reply("local-user", "Hello, bot!")
fmt.Printf("The bot says: %s", reply)
}

func ExampleRiveScript_utf8() {
// Examples of using UTF-8 mode in RiveScript.
bot := rivescript.New(rivescript.WithUTF8())

bot.Stream(`
// Without UTF-8 mode enabled, this trigger would be a syntax error
// for containing non-ASCII characters; but in UTF-8 mode you can use it.
+ comment ça va
- ça va bien.
`)

// Always call SortReplies when you're done loading replies.
bot.SortReplies()

// Without UTF-8 mode enabled, the user's message "comment ça va" would
// have the ç symbol removed; but in UTF-8 mode it's preserved and can
// match the trigger we defined.
reply, _ := bot.Reply("local-user", "Comment ça va?")
fmt.Println(reply) // "ça va bien."
}

func ExampleRiveScript_javascript() {
// Example for configuring the JavaScript object macro handler via Otto.

bot := rivescript.New(config.Basic())
bot := rivescript.New(nil)

// Create the JS handler.
bot.SetHandler("javascript", javascript.New(bot))
Expand Down Expand Up @@ -59,15 +97,14 @@ func ExampleRiveScript_javascript() {
`)
bot.SortReplies()

reply := bot.Reply("local-user", "Add 5 and 7")
reply, _ := bot.Reply("local-user", "Add 5 and 7")
fmt.Printf("Bot: %s\n", reply)
}

func ExampleRiveScript_subroutine() {
// Example for defining a Go function as an object macro.
// import rss "github.com/aichaos/rivescript-go/src"

bot := rivescript.New(config.Basic())
bot := rivescript.New(nil)

// Define an object macro named `setname`
bot.SetSubroutine("setname", func(rs *rss.RiveScript, args []string) string {
Expand All @@ -86,7 +123,7 @@ func ExampleRiveScript_subroutine() {
`)
bot.SortReplies()

_ = bot.Reply("local-user", "my name is bob")
reply := bot.Reply("local-user", "What is my name?")
bot.Reply("local-user", "my name is bob")
reply, _ := bot.Reply("local-user", "What is my name?")
fmt.Printf("Bot: %s\n", reply)
}
Loading

0 comments on commit b2781a8

Please sign in to comment.